Windows as Ansible Client

I control quite a few of computers in my network using Ansible. However, one set of clients were traditionally unreachable - Windows computers. And yes, there were ways around it but early Ansible really had trouble connecting to vanilla Windows installations without any agents involved. Well, those days are over.

Since Windows has OpenSSH built-in for a while now (as an optional component), it’s almost as easy to prepare a Windows client as it is to prepare a Linux one.

The first step is to install OpenSSH and one can do it either by manual clickety-clicking or by executing the following in administrative PowerShell prompt.

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Start-Service sshd

Set-Service -Name sshd -StartupType 'Automatic'

New-NetFirewallRule -Name "SSH-192_168_0_0" -DisplayName "SSH (192.168.0.0/16)" -Enabled True -Profile Any -Direction inbound -Protocol TCP -LocalPort 22 -RemoteAddress 192.168.0.0/16 -Action Allow  -ErrorAction SilentlyContinue

Next comes the need to create an administrative user since Windows equivalent of root user is actually disabled on most systems. And yes, you can skip this step if you’re ok with using client user for administrative tasks. I personally like to keep it separate and naming such user root helps with setup on Ansible “server” side.

Add-Type -AssemblyName System.Web

NET user /add /y root "$([System.Web.Security.Membership]::GeneratePassword(20, 2))"

NET localgroup /add Administrators root

REG add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\Userlist" /v root /t REG_DWORD /d 0 /f

Lastly, we need to add a public SSH key for passwordless authentication. This is as easy as writing a file.

New-Item -Path "$Env:ALLUSERSPROFILE\ssh" -Force -Name "administrators_authorized_keys" -ItemType "file" -Value "ssh-ed25519 `n"

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /inheritance:d

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /remove "NT AUTHORITY\Authenticated Users"

And that’s all. On Ansible side we just add cmd as ansible_shell_type and we’re good. Something like this:

ansible_connection: ssh
ansible_shell_type: cmd

Indeed, one could also use powershell instead of cmd but I found cmd working for all my scenarios while PowerShell is sometimes wonky for older Windows clients.

Regardless, you can now use Ansible to change your Winodws client configuration too.