You can run commands on a Windows server from a Linux terminal without ever opening a remote desktop. There are two good ways to do it: Windows Remote Management (WinRM), the protocol behind classic PowerShell remoting, and OpenSSH, which current Windows Server versions include. This guide shows how to set up each one securely, run commands from Linux with Python or PowerShell 7, and fix the usual connection errors.
For interactive work from Linux, enable the OpenSSH server on Windows and connect with ssh, or with PowerShell 7's Enter-PSSession -HostName. For scripts and tools such as Ansible, WinRM over HTTPS on port 5986 with the Python pywinrm library works well. Whichever you choose, restrict the port to your own IP addresses, keep certificate checks on, use a dedicated admin account, and never leave credentials inside scripts.
This guide is for Windows servers where you have administrator access. Domain India's Windows (Plesk) shared hosting is managed through the Plesk panel on port 8443: it has no remote desktop, no SSH and no remote PowerShell, so none of these steps apply there. See section 8.
1. WinRM, SSH or RDP?
| Method | Port | Best for | Notes |
|---|---|---|---|
| WinRM (PowerShell remoting) | 5985 HTTP, 5986 HTTPS | Scripts, Ansible, automation from Linux | Built into Windows Server; use HTTPS on untrusted networks |
| OpenSSH | 22 | Interactive shells, file copy, PowerShell 7 remoting | Included with Windows Server 2019 and later |
| RDP | 3389 | Graphical tasks | Needs a client such as FreeRDP or Remmina; never expose it to the whole internet |
From Linux, SSH is usually the simplest choice for a shell, because PowerShell 7 on Linux does not support the WinRM transport for Enter-PSSession; it uses SSH instead. WinRM remains the standard for Python scripts and for Ansible's classic Windows connection.
2. Enable WinRM over HTTPS on the Windows server
WinRM is present on every current Windows Server. Open PowerShell as Administrator on the server and run:
# Turn on PowerShell remoting (creates the HTTP listener and firewall rules)
Enable-PSRemoting -Force
# Create an HTTPS listener. Use a certificate from your CA whose name matches the server;
# a self-signed one is acceptable only in a lab.
$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*server.example.com*" } | Select-Object -First 1
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * `
-CertificateThumbPrint $cert.Thumbprint -HostName "server.example.com" -Force
# Allow 5986 only from your management IP address
New-NetFirewallRule -Name "WinRM-HTTPS-In" -DisplayName "WinRM over HTTPS" `
-Direction Inbound -Protocol TCP -LocalPort 5986 -RemoteAddress 198.51.100.20 -Action Allow
# Check the listeners
winrm enumerate winrm/config/listenerOnce HTTPS works, you can remove the HTTP listener, or limit its firewall rule to your internal network. Replace 198.51.100.20 with your own static IP address.
3. Run commands from Linux with pywinrm
Modern Debian and Ubuntu releases block system-wide pip installs, so use a virtual environment:
python3 -m venv ~/winrm-env
source ~/winrm-env/bin/activate
pip install pywinrm # add [kerberos] or [credssp] only if you need those loginsKeep the password out of the script by reading it from the environment:
#!/usr/bin/env python3
import os
import winrm
session = winrm.Session(
"https://server.example.com:5986/wsman",
auth=(os.environ["WIN_USER"], os.environ["WIN_PASS"]),
transport="ntlm",
server_cert_validation="validate", # keep certificate checks on
ca_trust_path="/etc/ssl/certs/ca-certificates.crt",
)
r = session.run_ps("Get-CimInstance Win32_OperatingSystem | Select-Object Caption, LastBootUpTime")
print(r.status_code, r.std_out.decode(), r.std_err.decode())Run it with WIN_USER='SERVER\admin' WIN_PASS='…' python3 check.py, or better, load the variables from a secrets manager. run_ps runs PowerShell; run_cmd runs a plain command-line program.
4. Or use OpenSSH and PowerShell 7
OpenSSH Server is an optional feature on Windows Server 2019 and 2022; Windows Server 2025 includes it, but you still need to enable the service.
# On the Windows server, as Administrator
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic
Start-Service sshdThe installer normally adds a firewall rule for port 22; limit it to your IP addresses as you did for WinRM. Then, from Linux, ssh [email protected] opens a shell. Use key authentication: for administrator accounts, Windows reads keys from C:\ProgramData\ssh\administrators_authorized_keys, not from the user's own folder.
For full PowerShell remoting over SSH, install PowerShell 7 on both machines, add this line to C:\ProgramData\ssh\sshd_config on the server, and restart sshd:
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -nologoThen, from pwsh on Linux:
Enter-PSSession -HostName server.example.com -UserName admin
Invoke-Command -HostName server.example.com -UserName admin -ScriptBlock { Get-Service W3SVC }5. Everyday tasks
These commands work through either route:
Get-Service W3SVC, WinRM | Select-Object Name, Status # service status
Restart-Service W3SVC # restart IIS
Get-Volume | Select-Object DriveLetter, SizeRemaining, Size # disk space
Import-Module WebAdministration; Get-Website | Select-Object Name, State, PhysicalPath
Restart-WebAppPool -Name "MyAppPool" # recycle one app pool
Get-WinEvent -LogName System -MaxEvents 20 | Where-Object LevelDisplayName -eq "Error"Use Get-WinEvent, not the older Get-EventLog, which exists only in Windows PowerShell 5.1 and not in PowerShell 7.
6. Security checklist
Get-WinEvent.7. Troubleshooting
| Error | Likely cause | Fix |
|---|---|---|
| Connection refused or timed out | Listener missing, service stopped, or firewall blocking your IP | Run winrm enumerate winrm/config/listener, check the firewall rule's allowed addresses |
| 401 Unauthorized | Wrong user format or password, or the account lacks remoting rights | Use SERVER\user or user@domain; add the user to Remote Management Users or Administrators |
| Certificate verify failed | Name mismatch or an untrusted CA | Connect by the name on the certificate; add your CA to ca_trust_path |
| Operation timed out | A slow command, or a busy server | Raise operation_timeout_sec and read_timeout_sec (read must be larger) in the Session |
| SSH asks for a password despite a key | Admin key in the wrong file, or wrong file permissions | Put it in administrators_authorized_keys with only Administrators and SYSTEM allowed |
8. Windows hosting at Domain India
If you only need to run ASP.NET sites, you don't have to manage a Windows server at all. Domain India's Windows hosting gives you IIS, MSSQL and email through the Plesk panel, with free SSL. You manage sites, databases and application pools in Plesk; there is no RDP or SSH. See the Plesk Windows hosting guide and IIS application pools. The price on the card is a Domain India list price, excluding 18% GST.
- 30 GB Storage
- 150 GB Monthly Bandwidth
- 5 Websites
- 50 Email Accounts
Frequently asked questions
What ports does WinRM use?
WinRM listens on port 5985 for HTTP and 5986 for HTTPS. Use 5986 with a trusted certificate on any network you don't fully control, and allow it only from your own IP addresses.
Can I use PowerShell remoting from Linux?
Yes, over SSH. Install PowerShell 7 on Linux and on the Windows server, enable the OpenSSH server and the PowerShell subsystem, then use Enter-PSSession or Invoke-Command with the -HostName parameter.
Is WinRM over HTTP encrypted?
With NTLM, Kerberos or CredSSP, the messages themselves are encrypted, but Basic authentication over HTTP is not. HTTPS on port 5986 protects every login method and is the safer default.
Does Windows Server include an SSH server?
Yes. OpenSSH Server is an optional feature on Windows Server 2019 and 2022, and Windows Server 2025 includes it. You still need to start the sshd service and allow port 22 in the firewall.
Can I use WinRM or RDP on Domain India Windows shared hosting?
No. Windows shared hosting is managed through the Plesk panel on port 8443. There is no remote desktop, SSH or remote PowerShell access.
How do I stop pywinrm from timing out on long commands?
Pass larger operation_timeout_sec and read_timeout_sec values when you create the Session, with the read timeout larger than the operation timeout.
Ready to host ASP.NET without running a server? Compare Windows hosting plans, or read the Plesk Windows hosting guide to see how sites are managed.
IIS, MSSQL and email managed through Plesk, with free SSL, so you can focus on your application.
See Windows hosting