unit 8 · Windows track

Windows connections: WinRM, PSRP, SSH

Three roads into the same box

essential · 7 min · windows

you may want to read 2 · Agentless, push-based first — but nothing is locked

tl;dr

  • Three plugins reach Windows: winrm, psrp (both ride WinRM) and ssh — chosen per host in inventory.
  • WinRM listens on 5985 (HTTP) / 5986 (HTTPS); unencrypted channels are refused, HTTPS is recommended.
  • SSH is officially supported since core 2.18 but needs OpenSSH 7.9+ — in practice Server 2022 or newer.

why it matters Every Windows host needs an explicit connection choice — Ansible assumes SSH, so until you pick winrm, psrp or ssh deliberately, every Windows task fails before it starts.

Lesson 2 drew the arrow: control node → Windows target, no agent. This lesson is what that arrow is made of. Ansible officially supports three connection plugins for Windows — winrm, psrp and ssh. The choice is inventory configuration, not playbook code. The same play runs over any of them; you pick the transport per host or group, usually in group_vars.

WinRM: the historical default

WinRM is the connection Ansible used for Windows from the start. It talks to the remote-management service you already know. Two ports matter: 5985 for HTTP, 5986 for HTTPS. Don’t let “HTTP” alarm you. WinRM refuses an unencrypted channel unless message-level encryption applies, so plaintext credentials on 5985 get rejected, not leaked. Still, official guidance recommends TLS on 5986. On the control node, this plugin needs pywinrm — which lesson 5 had you install.

PSRP: same wire, better client

PSRP is the newer plugin — and it also runs over WinRM. Same service, same ports, same target-side setup. What changes is the protocol on the wire and the Python library speaking it (pypsrp, the other package lesson 5 installed). You gain slightly faster execution, more resilience under load, and better proxy support. PSRP also offers Negotiate auth: Kerberos first, NTLM fallback. The full auth matrix is lesson 31’s job.

ansible_connection: psrp # or winrm — target setup is identical
ansible_port: 5986 # 5985 = HTTP, 5986 = HTTPS (recommended)
ansible_psrp_auth: negotiate # Kerberos first, NTLM fallback
group_vars/windows.yml — the connection choice lives in inventory

SSH: the newcomer with a version floor

SSH to Windows has technically worked since Ansible 2.8 . It became officially supported in ansible-core 2.18 . The catch is on the Windows side: Ansible requires the Windows-shipped OpenSSH at version 7.9.0.0 or later, and Server 2019 ships 7.7.2.1 — below the floor. In practice that means Server 2022 and newer, not the older half of a mixed estate.

Where it fits, it’s attractive: simpler in non-domain environments, SSH key auth instead of password wrangling, and faster file transfer. One wrinkle: Ansible assumes an SSH target runs a POSIX shell, so you declare otherwise:

ansible_connection: ssh
ansible_shell_type: powershell # without this, Ansible assumes sh
group_vars/windows_2022.yml — SSH needs the shell declared

Choosing for your estate

For a domain estate today, the answer is WinRM or PSRP — and between the two, PSRP: it costs nothing extra and behaves better. Reserve SSH for the parts of the estate on Server 2022 or newer. Standardize on SSH-on-Windows across the board and much of the WinRM auth intricacy stops mattering — but the whole estate must clear the OpenSSH floor first.

Two forward references. Authenticating over WinRM/PSRP — Basic, Kerberos, the rest of the matrix — is lesson 31. What you run on the Windows host to make any of this listen — the modern Enable-PSRemoting path, firewall rules, HTTPS listeners — is lesson 32. This lesson was the decision they build on: which road into the box.

at work, this sounds like

“Is that listener on 5985 or 5986?”
Is the host reachable over plain-HTTP WinRM or the recommended HTTPS one — it decides the port and the certificate work.
“The 2019 boxes can’t do SSH — their OpenSSH build is too old.”
Server 2019 ships OpenSSH 7.7.2.1, below the 7.9 floor Ansible needs, so those hosts stay on WinRM/PSRP.

self-check — recall, not a test

  1. 1 You add a fresh Windows host to inventory and run a ping. It fails with an SSH/port-22 error before you configured anything. Why?

  2. 2 Your domain estate mixes Server 2019 and Server 2022. Which connection do you standardize on, and why?

  3. 3 PSRP runs over WinRM anyway — so what does choosing psrp over winrm actually buy you?

next up 31 · The WinRM auth matrix 7 min · unit 8