Ansible + Windows Overview
Ansible manages Windows hosts using WinRM (Windows Remote Management) or PSRP (PowerShell Remoting Protocol) instead of SSH. The control node still runs on Linux/macOS.
Step 1: Prepare the Windows Host
Run this PowerShell script on each Windows host (as Administrator):
# Enable WinRM
winrm quickconfig -force
# Set up HTTPS listener (recommended) or HTTP
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
# Increase memory limit for large operations
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}'
# Configure firewall
netsh advfirewall firewall add rule name="WinRM HTTP" dir=in localport=5985 protocol=tcp action=allow
netsh advfirewall firewall add rule name="WinRM HTTPS" dir=in localport=5986 protocol=tcp action=allow
Or use the official Ansible setup script:
# Download and run the ConfigureRemotingForAnsible script
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file
Fix: LocalAccountTokenFilterPolicy
If you get authentication errors with local admin accounts:
# Required for non-domain-joined hosts
New-ItemProperty -Name LocalAccountTokenFilterPolicy `
-Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System `
-PropertyType DWord -Value 1 -Force
Fix: Network Connection Type
If you see "WinRM firewall exception will not work since one of the network connection types on this machine is set to public":
# Change network profile to Private
Set-NetConnectionProfile -InterfaceIndex (Get-NetConnectionProfile).InterfaceIndex -NetworkCategory Private
Step 2: Configure Ansible Inventory
[windows]
win1 ansible_host=192.168.1.50
win2 ansible_host=192.168.1.51
[windows:vars]
ansible_user=Administrator
ansible_password={{ vault_win_password }}
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
ansible_winrm_transport=ntlm
ansible_port=5986
Install pywinrm on Control Node
pip install pywinrm
Step 3: Test Connectivity
ansible windows -m ansible.windows.win_ping
Expected output:
win1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Common Windows Modules
Copy Files (win_copy)
- name: Copy file to Windows
ansible.windows.win_copy:
src: files/app.config
dest: C:\App\config\app.config
- name: Copy with content
ansible.windows.win_copy:
content: |
[Settings]
LogLevel=Info
Port=8080
dest: C:\App\settings.ini
Manage Services (win_service)
- name: Start a Windows service
ansible.windows.win_service:
name: wuauserv
state: started
start_mode: auto
- name: Stop and disable a service
ansible.windows.win_service:
name: Spooler
state: stopped
start_mode: disabled
Install Software with Chocolatey
- name: Install Chocolatey packages
chocolatey.chocolatey.win_chocolatey:
name: "{{ item }}"
state: present
loop:
- googlechrome
- notepadplusplus
- 7zip
- git
- vscode
Run PowerShell Commands
- name: Run PowerShell script
ansible.windows.win_powershell:
script: |
Get-Process | Where-Object { $_.CPU -gt 100 } |
Select-Object Name, CPU |
ConvertTo-Json
register: ps_result
- name: Show result
ansible.builtin.debug:
msg: "{{ ps_result.output }}"
Manage Windows Features
- name: Install IIS
ansible.windows.win_feature:
name: Web-Server
state: present
include_management_tools: true
Windows Reboot
- name: Reboot and wait
ansible.windows.win_reboot:
reboot_timeout: 600
post_reboot_delay: 60
msg: "Ansible is rebooting this server"
Manage Files and Directories
- name: Create directory
ansible.windows.win_file:
path: C:\App\logs
state: directory
- name: Delete a file
ansible.windows.win_file:
path: C:\Temp\old-installer.exe
state: absent
Download Files
- name: Download installer
ansible.windows.win_get_url:
url: https://example.com/installer.msi
dest: C:\Temp\installer.msi
checksum: abc123def456
checksum_algorithm: sha256
WinRM vs PSRP
| Feature | WinRM | PSRP |
|---|---|---|
| Protocol | HTTP/HTTPS | PowerShell Remoting |
| Port | 5985/5986 | 5985/5986 |
| Performance | Good | Better for large payloads |
| Setup | Standard | Requires pypsrp |
To use PSRP:
pip install pypsrp
[windows:vars]
ansible_connection=psrp
ansible_psrp_auth=ntlm
Troubleshooting
"winrm or requests is not installed"
pip install pywinrm requests
Connection timeout
# Increase timeout in ansible.cfg
[defaults]
timeout = 60
Certificate validation error
ansible_winrm_server_cert_validation=ignore
Explore our Windows automation tutorials and 800+ Ansible examples.
Related Articles
- Ansible Tutorial for Beginners — Complete getting started guide
- How to Install Ansible — Installation on all platforms
- Ansible Training — Courses and certifications
- Ansible Dry Run — Test playbooks safely
- Ansible Facts — Gather system info
- Ansible Vault — Encrypt secrets
- Ansible Error Handling — Handle failures