PowerShell Remoting lets you run commands on one or many Windows servers from your own machine, without opening a Remote Desktop session for each one. It’s how admins manage Server Core installations, automate fleets of servers, and script maintenance. It runs over WinRM (Windows Remote Management), or over SSH in PowerShell 7.

Enable remoting on the server

On Windows Server, remoting is usually enabled by default for domain/private networks. To make sure (run as administrator):

Enable-PSRemoting -Force
Get-Service WinRM
winrm enumerate winrm/config/listener

WinRM listens on 5985 (HTTP) and 5986 (HTTPS).

Important: don’t expose WinRM HTTP to the internet

For a VPS on the public internet:

  • Restrict ports 5985/5986 in Windows Firewall to your IP only, or
  • Reach the server over a VPN (WireGuard, Tailscale), or
  • Use PowerShell over SSH (below).
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP" -RemoteAddress 203.0.113.50

See Windows Server firewall with PowerShell and Tailscale.

Connecting to a non-domain server (typical VPS)

Without Active Directory, Kerberos authentication isn’t available, so the client must trust the server explicitly. Prefer HTTPS.

On the server, create an HTTPS listener with a certificate (self-signed shown here):

$cert = New-SelfSignedCertificate -DnsName "vps1.example.com" -CertStoreLocation Cert:\LocalMachine\My
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $cert.Thumbprint -Force
New-NetFirewallRule -DisplayName "WinRM HTTPS" -Direction Inbound -Protocol TCP -LocalPort 5986 -RemoteAddress 203.0.113.50 -Action Allow

On your Windows client:

$opt = New-PSSessionOption -SkipCACheck -SkipCNCheck     # only for self-signed certs; prefer a real cert
Enter-PSSession -ComputerName vps1.example.com -UseSSL -Credential (Get-Credential) -SessionOption $opt

If you must use HTTP on a trusted network, add the server to TrustedHosts on the client (understand that this disables server identity verification):

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

Interactive sessions and remote commands

# interactive shell on the remote server
Enter-PSSession -ComputerName vps1 -Credential admin
# ... run commands ...
Exit-PSSession

# run a command on several servers at once
Invoke-Command -ComputerName web01, web02 -Credential $cred -ScriptBlock {
    Get-Service W3SVC | Select-Object Status
    Get-Volume C | Select-Object SizeRemaining
}

# run a local script remotely
Invoke-Command -ComputerName web01 -FilePath .\maintenance.ps1 -Credential $cred

Persistent sessions (reuse the connection):

$s = New-PSSession -ComputerName web01 -Credential $cred
Invoke-Command -Session $s -ScriptBlock { Restart-Service W3SVC }
Copy-Item .\app.zip -Destination C:\Deploy\ -ToSession $s
Remove-PSSession $s

PowerShell over SSH (PowerShell 7)

PowerShell 7 can use SSH as the transport. That’s handy for cross-platform management, and it avoids exposing WinRM:

  1. Install OpenSSH Server on the Windows server (Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0), and start sshd.
  2. Install PowerShell 7, and add a subsystem line to C:\ProgramData\ssh\sshd_config:
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -nologo
  1. Restart sshd, then connect from any OS with PowerShell 7:
Enter-PSSession -HostName vps1.example.com -UserName admin

Use SSH keys for authentication. See SSH keys.

Security checklist

  • Restrict remoting ports to known IPs, or use a VPN.
  • Prefer HTTPS listeners or SSH. Avoid broad TrustedHosts = *.
  • Use strong passwords, and account lockout policies. See RDP brute-force protection.
  • Use Just Enough Administration (JEA) to give operators limited, audited command sets.
  • Log remoting activity (PowerShell script block logging, and the Security event log). See Windows Server logon auditing.

Quick reference

Task Command
Enable Enable-PSRemoting -Force
Interactive Enter-PSSession -ComputerName X
Many servers Invoke-Command -ComputerName a,b -ScriptBlock {…}
Copy files Copy-Item -ToSession $s
Over SSH Enter-PSSession -HostName X -UserName Y
Ports 5985 (HTTP), 5986 (HTTPS), 22 (SSH)

Related: PowerShell basics and Server Core vs Desktop Experience.

  • PowerShell
  • Windows Server
  • Remote Access