Updating the SSL Certificate for IIS and RDP on Windows Server 2019
When an SSL/TLS certificate is renewed on Windows Server 2019, the certificate used by IIS and the certificate used by Remote Desktop Services must be updated separately. Updating the HTTPS binding in IIS does not automatically change the certificate presented by RDP.
Before You Begin
Confirm that the replacement certificate:
- Matches the DNS name used by clients.
- Includes the Server Authentication enhanced key usage.
- Contains its associated private key.
- Is installed in the Local Computer\Personal certificate store.
The Server Authentication enhanced key usage has the object identifier:
1.3.6.1.5.5.7.3.1
1. Create the Certificate Signing Request in IIS
- Open Internet Information Services (IIS) Manager.
- Select the server in the left navigation pane.
- Open Server Certificates.
- Select Create Certificate Request.
- Enter the requested certificate information.
- Select the required cryptographic provider and key length.
- Save the certificate signing request, or CSR, to a file.
2. Submit the CSR and Obtain the Certificate
Submit the CSR to the certificate authority. After the request is approved, download the issued certificate in a format supported by IIS, such as .cer or .crt.
3. Complete the Certificate Request in IIS
- Return to IIS Manager.
- Open Server Certificates.
- Select Complete Certificate Request.
- Browse to the issued certificate file.
- Enter a friendly name for the certificate.
- Select the Personal certificate store when prompted.
- Complete the import.
The certificate should now appear in:
Certificates (Local Computer)
└── Personal
└── Certificates
4. Update the IIS HTTPS Binding
For each IIS website that uses the certificate:
- Open IIS Manager.
- Expand Sites.
- Select the website.
- Select Bindings.
- Select the https binding.
- Select Edit.
- Select the new certificate from the SSL certificate list.
- Select OK.
If the server hosts multiple HTTPS sites, verify the hostname, IP address, port, and Server Name Indication settings for each binding before applying the change.
5. Restart or Reload IIS
Open Windows PowerShell as Administrator and run one of the following commands.
Restart IIS completely:
iisreset
Or restart only the World Wide Web Publishing Service:
Restart-Service W3SVC
6. Verify the Certificate in the Local Computer Store
- Press Windows+R.
- Enter
mmc. - Select File > Add/Remove Snap-in.
- Add the Certificates snap-in.
- Select Computer account.
- Select Local computer.
- Browse to Personal > Certificates.
Open the certificate and verify that Windows reports:
You have a private key that corresponds to this certificate.
7. Export and Import a PFX File When Required
This step is only necessary when the certificate and private key were created or installed on another computer, or when the certificate must be moved between certificate stores.
Export the Certificate
- In the Certificates snap-in, right-click the certificate.
- Select All Tasks > Export.
- Select Yes, export the private key.
- Select the PKCS #12 or PFX format.
- Protect the file with a strong password.
- Save the file with a
.pfxextension.
Import the PFX File
- Copy the PFX file securely to the Windows Server 2019 computer.
- Right-click the PFX file and select Install PFX.
- Select Local Machine.
- Enter the PFX password.
- Import the certificate into the Personal certificate store.
After the import, verify that the certificate and private key are present in:
Cert:\LocalMachine\My
8. Locate the New Certificate Thumbprint
Open Windows PowerShell as Administrator and run:
Get-ChildItem "Cert:\LocalMachine\My" |
Select-Object Subject, Thumbprint, NotAfter
To narrow the results to a particular server name:
Get-ChildItem "Cert:\LocalMachine\My" |
Where-Object {
$_.Subject -like "*server.example.com*"
} |
Select-Object Subject, Thumbprint, NotAfter, HasPrivateKey
Confirm that the selected certificate has not expired and that HasPrivateKey is True.
9. Bind the Certificate to Remote Desktop Services
The recommended method uses the CIM PowerShell cmdlets.
Replace the sample thumbprint with the thumbprint of the new certificate:
$Thumbprint = "0123456789ABCDEF0123456789ABCDEF01234567"
$RdpSetting = Get-CimInstance `
-Namespace "root/cimv2/terminalservices" `
-ClassName "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'"
Set-CimInstance `
-InputObject $RdpSetting `
-Property @{
SSLCertificateSHA1Hash = $Thumbprint
}
Using a variable reduces the risk of copying the wrong value into the binding command.
Older WMI Method
The older WMI commands also work on Windows Server 2019, although CIM is preferred:
$RdpSetting = Get-WmiObject `
-Namespace "root\cimv2\terminalservices" `
-Class "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'"
Set-WmiInstance `
-Path $RdpSetting.__PATH `
-Arguments @{
SSLCertificateSHA1Hash = "0123456789ABCDEF0123456789ABCDEF01234567"
}
10. Restart Remote Desktop Services or Reboot
A reboot is the safest method, especially when the server is being maintained remotely.
To restart Remote Desktop Services from an elevated PowerShell session:
Restart-Service TermService -Force
Warning: Restarting the Remote Desktop Services service will disconnect active RDP sessions. Do not run this command from a remote session unless you have console access, an alternate management path, or a tested recovery method.
11. Verify the RDP Certificate Binding
Run:
Get-CimInstance `
-Namespace "root/cimv2/terminalservices" `
-ClassName "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'" |
Select-Object TerminalName, SSLCertificateSHA1Hash
The displayed thumbprint should match the new certificate.
You can also compare the configured thumbprint directly:
$ConfiguredThumbprint = (
Get-CimInstance `
-Namespace "root/cimv2/terminalservices" `
-ClassName "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'"
).SSLCertificateSHA1Hash
$ConfiguredThumbprint
12. Test the Certificate from Another Computer
- Open Remote Desktop Connection by running
mstsc. - Connect using the fully qualified DNS name covered by the certificate.
- Inspect the certificate presented by the server.
- Verify the subject or subject alternative name.
- Verify the expiration date.
- Verify the issuing certificate authority.
- Verify the thumbprint when necessary.
Common Problems
The Certificate Is in the Wrong Store
The RDP certificate must be installed under:
Certificates (Local Computer)
└── Personal
└── Certificates
A certificate installed only under Current User cannot be used by the Remote Desktop listener.
The Certificate Does Not Have a Private Key
RDP cannot use a certificate that does not have its associated private key. Import the original PFX file or complete the certificate request on the computer where the CSR was created.
The Thumbprint Contains Hidden Characters
Copying a thumbprint from the graphical certificate interface can include an invisible Unicode character or embedded spaces. Retrieving the thumbprint with PowerShell is more reliable.
A sanitized PowerShell value can be created with:
$Thumbprint = (
Get-ChildItem "Cert:\LocalMachine\My\0123456789ABCDEF0123456789ABCDEF01234567"
).Thumbprint -replace '\s',''
The Certificate Name Does Not Match
The certificate subject or subject alternative name must match the DNS name used by the RDP client. A connection made with an IP address or an unlisted hostname will still produce a certificate warning.
The Certificate Lacks Server Authentication
Verify that the certificate includes the following enhanced key usage:
Server Authentication
1.3.6.1.5.5.7.3.1
RDP Continues to Present the Old Certificate
Check the following:
- The correct thumbprint was assigned to the
RDP-Tcplistener. - The new certificate is in the Local Computer Personal store.
- The private key is present and accessible.
- Remote Desktop Services was restarted or the server was rebooted.
- The client is connecting directly to this server rather than through an RD Gateway, load balancer, or another intermediary.
Condensed PowerShell Procedure
After the new certificate is installed, the following example identifies the newest matching certificate and assigns it to the RDP listener.
$DnsName = "server.example.com"
$Certificate = Get-ChildItem "Cert:\LocalMachine\My" |
Where-Object {
$_.HasPrivateKey -and
$_.NotAfter -gt (Get-Date) -and
(
$_.Subject -like "*CN=$DnsName*" -or
$_.DnsNameList.Unicode -contains $DnsName
)
} |
Sort-Object NotAfter -Descending |
Select-Object -First 1
if (-not $Certificate) {
throw "No valid certificate with a private key was found for $DnsName."
}
$RdpSetting = Get-CimInstance `
-Namespace "root/cimv2/terminalservices" `
-ClassName "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'"
Set-CimInstance `
-InputObject $RdpSetting `
-Property @{
SSLCertificateSHA1Hash = $Certificate.Thumbprint
}
Get-CimInstance `
-Namespace "root/cimv2/terminalservices" `
-ClassName "Win32_TSGeneralSetting" `
-Filter "TerminalName='RDP-Tcp'" |
Select-Object TerminalName, SSLCertificateSHA1Hash
Review the certificate selected by the script before restarting Remote Desktop Services or rebooting the server.
Final Checklist
- The certificate is installed in the Local Computer Personal store.
- The certificate contains a private key.
- The certificate includes Server Authentication.
- The IIS HTTPS binding references the new certificate.
- The RDP-Tcp listener references the new certificate thumbprint.
- IIS was restarted or reloaded.
- Remote Desktop Services was restarted, or the server was rebooted.
- The certificate was tested from another computer using the correct DNS name.