Windows protects Remote Desktop with a self-signed certificate, which is why every new client shows an identity warning. If you install a certificate from a trusted authority and connect by its hostname, the warning disappears and clients can verify the server properly. This guide covers the requirements, importing the certificate, binding it to the RDP listener with PowerShell, and keeping it renewed.
Before you start
- A Windows VPS running Windows Server 2019, 2022 or 2025, with an Administrator account.
- A hostname, such as
rdp.example.com, with a DNS A record pointing to your server IP. You connect asrdp.example.com:3389. - A certificate for that exact hostname, issued by a public certificate authority. It can be a commercial certificate or a free one from an ACME client such as win-acme.
- The certificate as a
.pfxfile with its private key, or already in the server's Local Computer → Personal store. - The browser console from your VPS provider's control panel as a fallback in case Remote Desktop stops accepting connections.
Warning: A wrong binding, or a certificate whose private key Remote Desktop cannot read, can stop RDP from accepting new connections. Keep your current session open while you work and know how to open the browser console.
Check the certificate meets the requirements
Remote Desktop accepts a certificate only if:
- The subject or a Subject Alternative Name matches the hostname clients use, for example
rdp.example.com. - It includes the Server Authentication enhanced key usage.
- It has a private key on the server.
- It sits in the Local Computer certificate store, not the user store.
- It is within its validity dates.
Import the certificate
If you have a .pfx file, copy it to the server (for example to C:\certs\rdp.pfx) and import it in an elevated PowerShell window:
$pw = Read-Host -AsSecureString -Prompt 'PFX password'
Import-PfxCertificate -FilePath C:\certs\rdp.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $pwThe output shows the new certificate's Thumbprint. You can list certificates for your hostname at any time:
Get-ChildItem Cert:\LocalMachine\My |
Where-Object Subject -like '*rdp.example.com*' |
Format-List Subject, Thumbprint, NotAfter, HasPrivateKeyConfirm HasPrivateKey: True. Delete the .pfx file from the server once it is imported.
Give Remote Desktop access to the private key
The Remote Desktop service runs as NETWORK SERVICE and must be able to read the private key.
- Press Win + R, type
certlm.mscand press Enter. - Open Personal → Certificates and find your certificate.
- Right-click it and choose All Tasks → Manage Private Keys.
- Click Add, type
NETWORK SERVICE, click Check Names, then OK. - Give it Read permission only and click OK.
Bind the certificate to the RDP listener
Copy the thumbprint without spaces. Then set it on the RDP listener:
$thumb = 'PASTE_THUMBPRINT_HERE'
$ts = Get-CimInstance -Namespace root\cimv2\TerminalServices -ClassName Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'"
Set-CimInstance -InputObject $ts -Property @{ SSLCertificateSHA1Hash = $thumb }Read it back to confirm:
Get-CimInstance -Namespace root\cimv2\TerminalServices -ClassName Win32_TSGeneralSetting -Filter "TerminalName='RDP-Tcp'" |
Select-Object SSLCertificateSHA1HashThe value should match your thumbprint. New connections use the new certificate. Your current session stays connected.
Note: This changes only the certificate. Port 3389 and its firewall rule stay exactly as they were.
Connect by hostname
From your PC, connect to the name on the certificate, not the IP:
mstsc /v:rdp.example.com:3389If you connect by IP, the name will not match and the warning returns. Update saved .rdp files and connection managers to use the hostname.
Plan renewals
Certificates expire, and Remote Desktop does not swap in a renewed certificate on its own. The renewed certificate has a new thumbprint, so you must bind it again.
- Commercial certificates: set a calendar reminder well before the expiry date. Import the new certificate, grant key access and run the binding commands again.
- ACME certificates (win-acme and similar): these are short-lived and renew automatically. Configure the client to run a post-renewal script that grants key access and rebinds the new thumbprint. Check your ACME client's documentation for its script options.
- Check expiry dates from time to time:
Get-ChildItem 'Cert:\LocalMachine\My' | Where-Object Subject -like '*rdp.example.com*' | Select-Object NotAfter, ThumbprintIf the bound certificate is deleted or expires, clients see errors or warnings again, so remove old certificates only after the new one is bound.
Check it works
- Connect from a PC that has never connected before, using
rdp.example.com:3389. - You should go straight to the credentials prompt with no identity warning.
- In the session, run the read-back command above and confirm the thumbprint.
Troubleshooting
- New connections fail right after binding: Remote Desktop cannot read the private key. Repeat the key access step for NETWORK SERVICE, using the browser console if needed.
- Warning still says the name does not match: you are connecting by IP or by a different name. Use the exact hostname on the certificate.
Set-CimInstancereports invalid parameter: the thumbprint has spaces or hidden characters. Retype it, or copy it fromGet-ChildItemoutput.- Warning returned after a few months: the certificate was renewed but not rebound. Bind the new thumbprint.
Next steps
- Set up the hostname first: Connect to Remote Desktop with a domain name instead of an IP.
- Get a free certificate on Windows: Free SSL on IIS with win-acme.
- Understand the warning you are removing: The RDP certificate identity warning explained.
