PowerShell Remoting (WinRM) over HTTPS on a Windows VPS: Secure Automation Setup

PowerShell Remoting over plain HTTP (port 5985) works, but it is encrypted with Kerberos or NTLM only — and on a workgroup VPS with TrustedHosts in play, authentication can fall back to NTLM, which is weak and easily blocked by security policies. The production answer is WinRM over HTTPS on port 5986 with a certificate your client trusts. This guide shows how to enable WinRM, bind an HTTPS listener with a proper certificate, configure TrustedHosts versus Kerberos, open the firewall, and run Invoke-Command without tripping over the classic error codes. If you are comparing plans while you automate, the Windows VPS provider comparison notes which hosts give you full admin control (required for WinRM setup) versus locked-down shared plans.

Step 1: Enable WinRM and Check the Default Listener

On the VPS, open an elevated PowerShell and enable the service. This creates the default HTTP listener on port 5985:

Enable-PSRemoting -Force
Get-Service WinRM                 # should be Running
Get-Item WSMan:\localhost\Service\EnableCompatibilityHooks
Get-ChildItem WSMan:\localhost\Listener | Select-Object Name, Transport, Port

If you intend to use HTTPS exclusively, you can disable the HTTP listener later. Many administrators keep both and firewall 5985 off from the internet — see Step 4.

Step 2: Get a Certificate the Client Trusts

WinRM over HTTPS requires a certificate with the server’s name in the Subject (or SAN). A self-signed cert works only if you import it into the client’s Trusted Root Certification Authorities store — otherwise you will fight the 0x8033810C “certificate not trusted” error forever. For a real setup, buy a cheap domain cert or use Let’s Encrypt with a DNS challenge so the CN matches your VPS hostname:

# Check for an existing cert with a private key (LocalMachine\My):
Get-ChildItem Cert:\LocalMachine\My | Select-Object Thumbprint, Subject, NotAfter

If you test with a self-signed cert, generate one with the correct CN (this is the single most common cause of HTTPS listener failures):

$cert = New-SelfSignedCertificate -DnsName 'vps1.example.com' -CertStoreLocation Cert:\LocalMachine\My -KeyExportPolicy Exportable
$cert.Thumbprint

Step 3: Create the HTTPS Listener on Port 5986

Bind the listener to the certificate thumbprint and the server’s hostname. The Hostname must match the cert’s CN or SAN:

$thumb = 'THUMBPRINT-FROM-STEP-2'
New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Transport='HTTPS'} -ValueSet @{Hostname='vps1.example.com'; CertificateThumbprint=$thumb; Port=5986}

# Verify both listeners:
Get-ChildItem WSMan:\localhost\Listener | Select-Object Transport, Port, Enabled

Note the requirement: the listener’s Hostname and the certificate must agree, and the certificate must be in LocalMachine\My with a private key. If the listener silently fails to appear, that agreement is almost always the problem. For more on certificates on Windows Server, our guide to HTTPS and SSL certificates on a Windows VPS walks through the same trust chain from the IIS side.

Step 4: Firewall Rules — 5986 In, 5985 Out of Reach

Allow the HTTPS port and, if you are locking things down, block the plain HTTP port from remote sources:

New-NetFirewallRule -DisplayName 'WinRM HTTPS' -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow
New-NetFirewallRule -DisplayName 'Block WinRM HTTP remote' -Direction Inbound -Protocol TCP -LocalPort 5985 -Action Block -RemoteAddress Any

If the VPS sits behind a provider-level firewall or security group, open TCP 5986 there too. Remember: 5986 is HTTPS, 5985 is HTTP — mixing them up produces “connection refused” on the exact port you think you opened.

Step 5: TrustedHosts vs. Kerberos — Pick Deliberately

Authentication is where most WinRM setups go sideways. Two mechanisms:

MechanismWhen it worksSecurity notes
KerberosDomain-joined machines; both sides in the same AD forestStrongest option; no TrustedHosts needed
NTLM + TrustedHostsWorkgroup VPS (the common case)Adds the host to TrustedHosts; avoid wildcard *; use HTTPS so NTLM credentials travel encrypted

For a standalone Windows VPS, the practical setup is NTLM over HTTPS. On the client machine, add the server to TrustedHosts (scoped, not wildcard):

Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'vps1.example.com' -Concatenate
# View:
Get-Item WSMan:\localhost\Client\TrustedHosts

With HTTPS you can also skip TrustedHosts entirely by using -Authentication Negotiate and explicit credentials, since the channel is already encrypted — that is the configuration most security teams approve. A broader look at secure remote administration, including when RDP still beats PowerShell for interactive work, is in our RDP vs VPN comparison for Windows VPS access.

Step 6: Run Invoke-Command Securely

From the client, with a domain or local credential object, using -UseSSL:

$cred = Get-Credential 'vps1\ops-admin'
Invoke-Command -ComputerName 'vps1.example.com' -Credential $cred -UseSSL -SessionOption (New-PSSessionOption -OperationTimeoutSec 120) -ScriptBlock {
    Get-Service WinRM
    Get-NetTCPConnection -State Listen | Where-Object LocalPort -in 5985,5986
}

Better still, create a reusable session and pass it around:

$s = New-PSSession -ComputerName 'vps1.example.com' -Credential $cred -UseSSL
Invoke-Command -Session $s -ScriptBlock { Set-Service w32time -StartupType Automatic }
Remove-PSSession $s

Common Errors and Their Fixes

ErrorMeaningFix
0x8033810CCertificate not trusted / CN mismatch on the clientImport the cert into Trusted Root store; check CN matches the hostname you connect to
0x80070005 (Access denied)User lacks permissionAdd the account to Remote Management Users or Administrators on the VPS
Connection refused on 5986No HTTPS listener or firewall blockVerify listener with Get-ChildItem WSMan:\localhost\Listener; open TCP 5986
“The WinRM client cannot process the request”TrustedHosts missing (NTLM path)Set-Item WSMan:\localhost\Client\TrustedHosts with the exact hostname/IP
0x80338028 (timeout)Network path blockedTest-NetConnection vps1 -Port 5986 from the client

Wrap-Up

WinRM over HTTPS is the difference between “it works on my machine” automation and automation you can defend in a security review: a trusted certificate, port 5986 only, scoped TrustedHosts, and explicit credentials in every Invoke-Command. The full recipe — enable WinRM, bind an HTTPS listener whose CN matches the cert, open 5986, and pick Kerberos or scoped TrustedHosts — takes about fifteen minutes on a fresh Windows Server VPS. When you pick the host, make sure the plan gives you administrator access and a static IP, both of which matter for certificate validity; compare plans on our Windows VPS feature comparison before you buy.

Leave a Comment