Windows

Manage Windows VPS With PowerShell Remoting

RDP is the default tool for managing a Windows VPS, but it is not always the best one. You want to check a service, restart a process, or apply a GPO across twenty servers, opening a full desktop session for each is slow and error-prone. PowerShell remoting lets you run commands on a remote Windows machine as if they were local, over WinRM, without ever launching a GUI. powershell remoting is the backbone of modern Windows administration, and setting it up correctly on your Windows VPS means you can script, automate, and manage from a terminal anywhere. This guide covers installation, HTTPS hardening, credential delegation, and the most common pitfalls.

  • Key takeaways: Enable WinRM and set a TrustedHosts list for immediate connectivity over HTTP (lab) or use a certificate for HTTPS in production. Configure firewall rules for port 5985/5986 and test with Enter-PSSession and Invoke-Command. CredSSP solves the double-hop problem securely. Always restrict TrustedHosts to only the IPs or hostnames you need, never use * in production.

使用 PowerShell 远程管理 Windows VPS,比 RDP 更高效,尤其适合自动化任务。

Managing a Windows VPS with PowerShell remoting is more efficient than RDP, especially for automation tasks.

Prerequisites

  • A Windows VPS running Windows Server 2022 or Windows Server 2019 (Windows 10/11 Pro works too for management workstations).
  • Administrator access on both the local machine and the VPS.
  • Port 5985 (HTTP) or 5986 (HTTPS) reachable, check your security group or hypervisor firewall.
  • One dedicated IPv4 per server if you plan to use IP-based TrustedHosts (nearly always the case).
  • PowerShell 5.1 or later on both ends (PowerShell 7.x is fine, but WinRM still uses the 5.1 endpoint by default).

Why Use PowerShell Remoting Instead of RDP?

RDP gives you a desktop, you log in, open a terminal or GUI, perform the task, and disconnect. That is fine for interactive troubleshooting but terrible for scale. PowerShell remoting sends commands over the network as SOAP messages over WinRM. You can run a single command on fifty servers with one Invoke-Command call. It logs every action in the PowerShell transcript or session logs. More importantly, it does not consume a full graphical session license, which matters when you manage many core-licensed Windows Server instances.

The trade-off is that WinRM is not enabled by default on all images, and misconfiguring TrustedHosts opens a security hole. A locked-down PowerShell remoting setup is far safer than leaving RDP exposed to the public internet if you use strong authentication and HTTPS.

Step 1, Enable WinRM and Check the Listener

On the Windows VPS, open PowerShell as Administrator and run:

Enable-PSRemoting -Force

This command starts the WinRM service, sets it to auto-start, creates a firewall rule for port 5985, and registers the default session configuration. It also enables the WSMan provider. After it finishes, verify the listener:

winrm enumerate winrm/config/Listener

You should see output similar to:

Listener
    Address = *
    Transport = HTTP
    Port = 5985
    Enabled = true

If you see nothing, the listener was not created. You can force it:

winrm quickconfig -q

Verify: From the same machine, test locally:

Enter-PSSession -ComputerName localhost

You should get a remote session prompt ([localhost]: PS C:\>). Type Exit-PSSession to leave.

Step 2, Configure the Firewall for WinRM

Windows Firewall on modern Windows Server versions blocks WinRM from external sources unless you created a rule during initial setup. The Enable-PSRemoting cmdlet adds an inbound rule for the private and domain profiles, not public. If your VPS network is set to Public, the rule will not apply.

Check the current network profile:

Get-NetConnectionProfile

If it shows NetworkCategory = Public, either switch it to Private (if you trust the subnet) or add a firewall rule explicitly:

New-NetFirewallRule -DisplayName "WinRM HTTP" -Direction Inbound -LocalPort 5985 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound -LocalPort 5986 -Protocol TCP -Action Allow

Your VPS provider may also have a layer-3 firewall or security group. Make sure port 5985 (or 5986) is allowed from your management IP only, never from 0.0.0.0/0. A Windows VPS with WinRM open to the internet is a brute-force target.

Verify: From your local machine, test connectivity with Test-NetConnection:

Test-NetConnection -ComputerName <vps-ip> -Port 5985

It should return TcpTestSucceeded : True.

Step 3, Set Up TrustedHosts (or Use HTTPS)

The biggest friction with PowerShell remoting is the TrustedHosts list. By default, WinRM over HTTP requires the remote machine to be in the local trust list because NTLM or Kerberos cannot validate the target if it is not domain-joined (most VPS environments are workgroup machines).

You have two options:

Option A, TrustedHosts (quick, for lab or trusted networks)

On your management machine, set the TrustedHosts list to include the VPS IP:

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.0.2.10" -Concatenate

Replace the IP with your VPS address. Use -Concatenate to add without overwriting. To see the list:

Get-Item WSMan:\localhost\Client\TrustedHosts

Security note: TrustedHosts removes server authentication for HTTP, any machine you add can be impersonated on the network. Never use * as the value in a production environment. Keep the list as short as possible.

Option B, HTTPS Listener (recommended for production)

A self-signed certificate for the HTTPS listener avoids the TrustedHosts requirement and encrypts all traffic. On the VPS:

$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "winrm-vps.yourdomain.com" -FriendlyName "WinRM HTTPS"
New-WSManInstance winrm/config/Listener -SelectorSet @{Transport = "HTTPS"} -ValueSet @{Hostname = "winrm-vps.yourdomain.com"; CertificateThumbprint = $cert.Thumbprint}
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound -LocalPort 5986 -Protocol TCP -Action Allow

On your management machine, trust the certificate (import it into the Trusted Root store). Then connect:

$s = New-PSSession -ComputerName "winrm-vps.yourdomain.com" -UseSSL -Credential (Get-Credential)
Enter-PSSession $s

With HTTPS, you do not need to modify TrustedHosts at all.

Step 4, Connect and Run Commands

You have two main ways to interact:

Interactive Session

Enter-PSSession -ComputerName 192.0.2.10 -Credential (Get-Credential)

This opens an interactive PowerShell prompt on the remote VPS. Every command runs there until you type Exit-PSSession.

One-off Command

Invoke-Command -ComputerName 192.0.2.10 -Credential (Get-Credential) -ScriptBlock { Get-Service BITS }

The beauty of Invoke-Command is that you can target an array:

$servers = @("192.0.2.10", "192.0.2.11")
Invoke-Command -ComputerName $servers -ScriptBlock { Restart-Service W3SVC }

Verify: Always check the PSComputerName property in the output, it shows which server returned what object. Without it you cannot tell which result belongs to which machine in a multi-target command.

Step 5, Solve the Double-Hop Problem with CredSSP

The default authentication protocol (Kerberos or NTLM) cannot forward credentials to a second machine. If you connect to VPS-A and from there try to access VPS-B or a file share, you get an access denied error. This is the double-hop problem.

The cleanest fix is CredSSP (Credential Security Support Provider). Enable it on both sides:

On the management machine (client):

Enable-WSManCredSSP -Role Client -DelegateComputer "*.yourdomain.com"

On the VPS (server):

Enable-WSManCredSSP -Role Server

Then connect using the -Authentication CredSSP flag:

$cred = Get-Credential
Enter-PSSession -ComputerName 192.0.2.10 -Authentication CredSSP -Credential $cred

Security warning: CredSSP passes your credentials in clear text to the server for delegation. Only use it on trusted networks. Restrict -DelegateComputer to the specific hostnames you need, never *.

Verify the Setup End-to-End

Run the following from your management machine to confirm everything works:

Test-WSMan -ComputerName 192.0.2.10

It should return a wsmid response with the protocol version. Then run a simple command to confirm session creation:

Invoke-Command -ComputerName 192.0.2.10 -ScriptBlock { hostname; (Get-CimInstance Win32_OperatingSystem).Caption }

Expected output (example):

WSMAN192-0-2-10
Microsoft Windows Server 2022 Standard

Troubleshooting

WinRM service not running

Get-Service WinRM | Start-Service

If it fails to start, check dependencies: the WinRM service requires the HTTP service. Run Get-Service -Name WinRM -DependentServices and resolve any stopped services.

Access denied on Enter-PSSession

Your user must be a member of the Remote Management Users group on the VPS, or an Administrator. Add it:

Add-LocalGroupMember -Group "Remote Management Users" -Member "YourUsername"

TrustedHosts not working

Ensure the IP/hostname in the TrustedHosts list exactly matches how you call -ComputerName. DNS name, IPv4, IPv6, every variant is a different entry. Use the same format consistently.

FAQ

Can I use PowerShell remoting over the internet?

Yes, but only over HTTPS (port 5986). Exposing WinRM over HTTP on the public internet is dangerous because authentication is sent in a reversible hash. Combine HTTPS with IP-based firewall rules that restrict access to your management IP.

Do I need a domain for PowerShell remoting to work?

No. Workgroup machines communicate over NTLM and need the TrustedHosts list. A domain gives you Kerberos authentication (more secure, no TrustedHosts needed), but it adds complexity you may not need for a single VPS.

What is the difference between WinRM and PowerShell remoting?

WinRM is the protocol and service that implements WS-Management. PowerShell remoting is the feature that uses WinRM to transport PowerShell commands. You can also use WinRM to retrieve WMI/CIM data without PowerShell.

How do I enable PowerShell remoting on a Nano Server or Server Core?

Nano Server and Server Core ship with WinRM enabled by default. Run Enable-PSRemoting -Force to ensure the firewall rules are active. There is no GUI anyway, PowerShell remoting is the primary management channel on Core.

Can I use PowerShell 7 with WinRM on Windows Server 2022?

Yes. PowerShell 7 registers its own endpoint (Microsoft.PowerShell is 5.1, PowerShell.7 is 7.x). Use Enter-PSSession -ConfigurationName PowerShell.7 to target the new runtime.

Related articles

使用 PowerShell 远程管理 Windows VPS 的配置要点

本文详细介绍了如何在 Windows VPS 上启用并配置 PowerShell 远程管理(基于 WinRM),包括启用监听器、设置防火墙、创建 HTTPS 自签名证书、配置 TrustedHosts 以及应对双跳问题的 CredSSP 方法。生产环境中建议使用 HTTPS 而非 HTTP,双跳场景需谨慎使用 CredSSP 并明确限制委托目标。PowerShell 远程管理适用于批量操作和自动化运维,比 RDP 更适合管理多台服务器。

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.