# 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")