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.