# PowerShell


# Connect to Remote PowerShell

Enter-PSSession -ComputerName <FQDN/IP>

# Test WMI Filter

Easy way to test WMI filters on your local machine, example:

gwmi -Query 'Select * from Win32_OperatingSystem where Caption != "Microsoft Windows XP Professional"'

# List installed products

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

# Install RSAT

Applicable after version 1809

Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability –Online

Check installed status

Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property DisplayName, State

# Obtain Let's Encrypt Certificate for RDP

This example will use DNS verification via Cloudflare

# Check Powershell Version

Ensure you have Powershell version 5.1 or newer

$PSversionTable

# Install Posh-ACME

Install Posh-ACME (opens new window) If you installed this a while ago, make sure you update to a version >3.10.0

Install-Module -Name Posh-ACME

# Add Powershell Script

Using the example here (opens new window)

$CFParams = @{CFAuthEmail='xxxxxxxx'; CFAuthKey='xxxxxxxx'}
New-PACertificate test.example.com -DnsPlugin Cloudflare -PluginArgs $CFParams

Here's a script to renew and then set the certificate as the current RDP cert

# Change your settings here
$certDomain = "YOUR.DOMAIN.COM"
$emailAddr = "YOUR@EMAIL.com"
$cfKey = "CLOUDFLAREAPIKEY"

# Don't touch below here
$evSource = "Let's Encrypt Cert Renew"
if (! ([System.Diagnostics.EventLog]::Exists('Application') -and [System.Diagnostics.EventLog]::SourceExists($evSource))) {
    New-EventLog -LogName Application -Source $evSource
}
$myHostName = [System.Net.Dns]::GetHostByName($env:computerName).HostName
Function Write-LogEntry ($text) {
    Write-EventLog -LogName Application -Source $evSource -EntryType Information -EventID 1 -Message $text
}

Function Renew-Cert {
    Set-PAServer LE_PROD
    $CFParams = @{CFAuthEmail=$emailAddr; CFAuthKey=$cfKey}
    $certDetails = New-PACertificate $certDomain -AcceptTOS -Contact $emailAddr -DnsPlugin Cloudflare -PluginArgs $CFParams -Install

    if ($certDetails) {
        if (![string]::IsNullOrEmpty($certDetails.Thumbprint)) {
            $SourceStoreScope = 'LocalMachine'
            $SourceStorename = 'My'
            $DestStoreScope = 'LocalMachine'
            $DestStoreName = 'Remote Desktop'
            $newThumb = $certDetails.Thumbprint
            $SourceStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store  -ArgumentList $SourceStorename, $SourceStoreScope
            $SourceStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)
            $cert = $SourceStore.Certificates | Where-Object  -FilterScript {
                $_.Thumbprint -like $newThumb
            }
            
            $DestStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store  -ArgumentList $DestStoreName, $DestStoreScope
            $DestStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
            $DestStore.Add($cert)
            $SourceStore.Close()
            $DestStore.Close()
    
            Write-LogEntry("New cert copied to Remote Desktop store")
            
            Set-WmiInstance -Path $rdpProp.__path -argument @{SSLCertificateSHA1Hash="$newThumb"}
            Write-LogEntry("New RDP cert set")
        }
    } else {
        Write-LogEntry("Failed to renew")
    }
}
Write-LogEntry("Running...")

# Cleanup old Certs
Get-ChildItem 'Cert:\LocalMachine\My' -Recurse | Where-Object {$_.hasprivatekey -and $_.notafter -lt ((Get-Date).AddDays(0))} | Remove-Item
Get-ChildItem 'Cert:\LocalMachine\Remote Desktop' -Recurse | Where-Object {$_.hasprivatekey -and $_.notafter -lt ((Get-Date).AddDays(0))} | Remove-Item
$rdpProp = (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'")

$currentCert = Get-ChildItem 'Cert:\LocalMachine\Remote Desktop' -Recurse | Where-Object  -FilterScript { ($_.Thumbprint -like $rdpProp.SSLCertificateSHA1Hash) -and ($_.Issuer -notlike "CN="+$myHostName) }

if (!$currentCert) {
    Write-LogEntry("No cert found, renewing!")
    Renew-Cert
} elseif ($currentCert.NotAfter -lt ((Get-Date).AddDays(30)) ) {
    Write-LogEntry("Current cert is expiring within 30 days, renewing!")
    Renew-Cert
    
} else {
    Write-LogEntry("No renewal needed")
}

Write-LogEntry("Finished Running")
Last Updated: 2021/03/31 12:28+00:00