To continue from my previous guide I will now show how to use certificates from Let’s Encrypt and automate the renewal for use with Windows Remote Desktop Services. As before I will use Posh-ACME to get the certificates from Let’s Encrypt.
Install the Powershell module Posh-ACME from Powershell Gallery if needed.
1 Install-Module -Name Posh-ACME
In order to use Posh-ACME you need to figure out how to let the script make changes to your public DNS-server. This is beyond the scope of this guide as that procedure varies depending on your provider. You will have to look in the documentation for Posh-ACME. List-of-Supported-DNS-Providers
In a production environment the following steps should be performed as a separate (batch/script) account. Posh-ACME saves the settings in the user profile and you need to schedule a task to update the certificates. You do not want to schedule a task with your regular user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 # Specify the environment to acquire certificates from (LE_PROD is Let's Encrypt production environment and LE_STAGE is the test environment).
Set-PAServer LE_PROD
# I use Azure DNS so I populate $azParams with my settings:
# Credentials for AzureDNS
$user = '...'
$pass = ConvertTo-SecureString -AsPlainText '...' -Force
$MySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$pass
# Parameters for AzureDNS
$azParams = @{
AZSubscriptionId='----';
AZTenantId='----';
AZAppCred=($MySecureCreds)
}
# Acquire the certificate:
$newCert = New-PACertificate 'rdg.demodomain.se' -AcceptTOS -Contact admin@demodomain.se -DnsPlugin Azure -PluginArgs $azParams
# Note: I'm not using the "-Install" switch here because on Server 2016 RDS it isn't possible to point to a existing certificate in the store. Only import from pfx.
# Assign the certificate to Remote Desktop Services:
Set-RDCertificate -Role RDGateway -ImportPath $newCert.PfxFile -Password $newCert.PfxPass
# If you run RDS on Server 2019, it is possible to use the "-Thumbprint" parameter instead of importing from pfx.
This short script below will renew the certificate if needed, configure Remote Desktop Services with the new certificate and then remove the old certificate. Schedule this to run every day or so.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 # Update existing certificate
# This task should be scheduled to run every day (or something similar)
# Specify the domainname to update:
$rdsDomain = "rdg.demodomain.se"
# Get the current certificate:
$currentCert = Get-Item Cert:\LocalMachine\My\* | Where Subject -like "CN=$rdsDomain"
# Specify the environment (Production or Test)
Set-PAServer LE_PROD
# Specify what certificate to renew
Set-PAOrder -MainDomain $rdsDomain
# Submit the renewal
$newCert = Submit-Renewal
if ($newCert -ne $null)
{
# If atleast one new certificate is returned:
foreach ($c in $newCert)
{
# Check if the returned certificate matches the domainname specified:
if ($c.AllSANs -contains $rdsDomain)
{
# Bind new certificate to the RDS Service (RD Gateway in my case but can be any of the other services)
Set-RDCertificate -Role RDGateway -ImportPath $c.PfxFile -Password $c.PfxPass
# Remove the old certificate from the certificate store
Remove-Item $currentCert.PSPath
}
}
}