Connecting via SSH

Manage Windows Servers from Linux with WinRM or SSH

By the Domain India teamPublished 8 min read
Knowledge base article
Contents (9 sections)

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.

Key takeaways

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.

For servers you manage yourself

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?

MethodPortBest forNotes
WinRM (PowerShell remoting)5985 HTTP, 5986 HTTPSScripts, Ansible, automation from LinuxBuilt into Windows Server; use HTTPS on untrusted networks
OpenSSH22Interactive shells, file copy, PowerShell 7 remotingIncluded with Windows Server 2019 and later
RDP3389Graphical tasksNeeds 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:

powershell
# 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/listener

Once 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:

bash
python3 -m venv ~/winrm-env
source ~/winrm-env/bin/activate
pip install pywinrm            # add [kerberos] or [credssp] only if you need those logins

Keep the password out of the script by reading it from the environment:

python
#!/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.

powershell
# On the Windows server, as Administrator
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Set-Service -Name sshd -StartupType Automatic
Start-Service sshd

The 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:

text
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -nologo

Then, from pwsh on Linux:

powershell
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:

powershell
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

Restrict the port
Allow 5986 or 22 only from your own static IP addresses or a VPN. Never open WinRM or RDP to the whole internet.
Encrypt everything
Use HTTPS for WinRM with a certificate you trust, and keep certificate validation on in your scripts.
Least privilege
Use a dedicated account for automation, not the built-in Administrator, and consider Just Enough Administration (JEA) for limited roles.
Keep secrets out of code
Read passwords from environment variables or a secrets manager, and prefer SSH keys or Kerberos where you can.
Keep account lockout on
A lockout policy slows password guessing. Don't switch it off to work around a login problem.
Watch the logs
Successful network logons are event 4624 and failures 4625 in the Security log; review them with Get-WinEvent.

7. Troubleshooting

ErrorLikely causeFix
Connection refused or timed outListener missing, service stopped, or firewall blocking your IPRun winrm enumerate winrm/config/listener, check the firewall rule's allowed addresses
401 UnauthorizedWrong user format or password, or the account lacks remoting rightsUse SERVER\user or user@domain; add the user to Remote Management Users or Administrators
Certificate verify failedName mismatch or an untrusted CAConnect by the name on the certificate; add your CA to ca_trust_path
Operation timed outA slow command, or a busy serverRaise operation_timeout_sec and read_timeout_sec (read must be larger) in the Session
SSH asks for a password despite a keyAdmin key in the wrong file, or wrong file permissionsPut 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.

ASP Business
₹328.83/mo + GST
  • 30 GB Storage
  • 150 GB Monthly Bandwidth
  • 5 Websites
  • 50 Email Accounts
See plan details

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.

ASP.NET hosting without server admin

IIS, MSSQL and email managed through Plesk, with free SSL, so you can focus on your application.

See Windows hosting

Ready when you are

Get VPS from ₹552.65/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Manage Windows from Linux: WinRM & SSH | Domain India