How to Install Ansible and Manage Windows Servers with Ansible on Windows Server 2025
Ansible is an agentless automation platform that manages remote systems by pushing configuration over existing protocols. On Linux targets Ansible uses SSH; on Windows targets it uses WinRM (Windows Remote Management), the native Windows remoting protocol. This means Windows Server 2025 machines can be fully managed without installing any agent — only WinRM must be configured. This guide covers setting up an Ansible control node on Linux, preparing Windows Server 2025 as a managed host, writing inventories, testing connectivity, and running the most useful Windows-specific modules.
Prerequisites
- A Linux host (Ubuntu 22.04 / 24.04, RHEL 9, or Debian 12) as the Ansible control node
- Python 3.9 or later on the control node
- Windows Server 2025 as the managed host (Standard or Datacenter edition)
- A local administrator account on the Windows Server 2025 target
- Network connectivity on TCP 5985 (WinRM HTTP) or 5986 (WinRM HTTPS) between control node and managed host
Step 1: Install Ansible on the Control Node (Linux)
# Ubuntu / Debian
sudo apt update
sudo apt install -y python3 python3-pip python3-venv
# Create a virtual environment (recommended)
python3 -m venv ~/ansible-env
source ~/ansible-env/bin/activate
# Install Ansible and Windows support libraries
pip install --upgrade pip
pip install ansible pywinrm requests-ntlm requests-credssp
# Verify installation
ansible --version
python -c "import winrm; print('pywinrm OK')"
Install the Windows collection from Ansible Galaxy, which provides the win_* modules:
ansible-galaxy collection install ansible.windows
ansible-galaxy collection install community.windows
Step 2: Configure WinRM on Windows Server 2025
On the Windows Server 2025 target, open an elevated PowerShell prompt and run the following commands to enable and configure WinRM. Microsoft provides a convenience script for Ansible that handles the full setup:
# Enable PowerShell remoting (creates WinRM listener on port 5985)
Enable-PSRemoting -Force
# Allow unencrypted traffic for initial testing (HTTP / NTLM)
# In production always use HTTPS (port 5986)
Set-Item -Path WSMan:localhostServiceAllowUnencrypted -Value $true
# Allow basic and NTLM authentication
Set-Item -Path WSMan:localhostServiceAuthBasic -Value $true
Set-Item -Path WSMan:localhostServiceAuthNTLM -Value $true
# Set the maximum memory per shell (increase for complex tasks)
Set-Item -Path WSMan:localhostShellMaxMemoryPerShellMB -Value 1024
# Configure WinRM service startup and start it
Set-Service -Name WinRM -StartupType Automatic
Start-Service WinRM
# Open firewall ports
New-NetFirewallRule -DisplayName "WinRM HTTP (5985)" `
-Direction Inbound -Protocol TCP -LocalPort 5985 -Action Allow
New-NetFirewallRule -DisplayName "WinRM HTTPS (5986)" `
-Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow
# Test the WinRM listener
winrm enumerate winrm/config/Listener
For automated, repeatable configuration across many machines, use the ConfigureRemotingForAnsible.ps1 script maintained in the Ansible documentation repository. Download and run it on each managed Windows host:
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$scriptPath = "$env:TEMPConfigureRemotingForAnsible.ps1"
Invoke-WebRequest -Uri $url -OutFile $scriptPath
# Run with HTTPS and CredSSP enabled
powershell -ExecutionPolicy Bypass -File $scriptPath -EnableCredSSP -ForceNewSSLCert -SkipNetworkProfileCheck
Step 3: Build the Ansible Inventory
On the control node create an inventory file that defines your Windows hosts and their connection parameters. Use INI or YAML format — YAML is clearer for complex variable sets:
# /etc/ansible/inventory/windows.yml (YAML inventory)
all:
children:
windows:
hosts:
win-srv-01:
ansible_host: 192.168.10.20
win-srv-02:
ansible_host: 192.168.10.21
vars:
ansible_user: Administrator
ansible_password: "S3cur3P@ss2025!"
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore
ansible_winrm_port: 5985
ansible_shell_type: powershell
Store credentials in an Ansible Vault file instead of plain text:
# Create an encrypted vault file
ansible-vault create /etc/ansible/inventory/windows_vault.yml
# Inside the vault file
vault_win_password: "S3cur3P@ss2025!"
# Reference the vault variable in inventory
# ansible_password: "{{ vault_win_password }}"
# Run Ansible commands with vault decryption
ansible windows -m win_ping --ask-vault-pass
# or use a vault password file
ansible windows -m win_ping --vault-password-file ~/.vault_pass.txt
Step 4: Test Connectivity with win_ping
# Test all hosts in the [windows] group
ansible windows -i /etc/ansible/inventory/windows.yml -m win_ping
# Expected successful output:
# win-srv-01 | SUCCESS => {
# "changed": false,
# "ping": "pong"
# }
# Test a single host
ansible win-srv-01 -i /etc/ansible/inventory/windows.yml -m win_ping -v
Step 5: Run Windows Modules — win_package, win_feature, win_service
Ansible’s Windows collection provides purpose-built modules for Windows administration. Run them ad-hoc or inside playbooks.
Install a Windows Feature
ansible windows -i inventory/windows.yml -m ansible.windows.win_feature -a "name=Web-Server state=present include_management_tools=yes"
Manage Windows Services
ansible windows -i inventory/windows.yml -m ansible.windows.win_service -a "name=W32Time state=started start_mode=auto"
Copy Files to Windows Hosts
ansible windows -i inventory/windows.yml -m ansible.windows.win_copy -a "src=/tmp/config.xml dest=C:\App\config.xml"
Step 6: Write a Windows Playbook
A playbook groups multiple tasks into a repeatable, idempotent automation unit:
# playbooks/configure_iis_server.yml
---
- name: Configure IIS on Windows Server 2025
hosts: windows
gather_facts: true
tasks:
- name: Install IIS and management tools
ansible.windows.win_feature:
name:
- Web-Server
- Web-Mgmt-Tools
- Web-Asp-Net45
state: present
include_sub_features: true
- name: Ensure IIS service is started and set to auto
ansible.windows.win_service:
name: W3SVC
state: started
start_mode: auto
- name: Deploy application web.config
ansible.windows.win_copy:
src: files/web.config
dest: C:inetpubwwwrootweb.config
backup: true
- name: Create application directory
ansible.windows.win_file:
path: C:AppLogs
state: directory
- name: Install Chocolatey package manager
community.windows.win_chocolatey:
name: chocolatey
state: present
- name: Install application prerequisites via Chocolatey
community.windows.win_chocolatey:
name:
- dotnet-8.0-runtime
- nssm
state: present
- name: Set environment variable for application
ansible.windows.win_environment:
name: APP_ENVIRONMENT
value: Production
state: present
level: machine
- name: Run post-deployment validation script
ansible.windows.win_shell: |
$response = Invoke-WebRequest -Uri http://localhost -UseBasicParsing
if ($response.StatusCode -ne 200) {
throw "IIS health check failed with status $($response.StatusCode)"
}
Write-Output "IIS health check passed"
register: health_check_result
- name: Display health check output
debug:
var: health_check_result.stdout_lines
# Run the playbook
ansible-playbook -i inventory/windows.yml playbooks/configure_iis_server.yml -v
# Dry-run (check mode)
ansible-playbook -i inventory/windows.yml playbooks/configure_iis_server.yml --check --diff
Step 7: Gather Windows Facts
Ansible’s setup module (called automatically at the start of plays) collects extensive facts about Windows hosts:
ansible win-srv-01 -i inventory/windows.yml -m ansible.windows.win_disk_facts
ansible win-srv-01 -i inventory/windows.yml -m setup -a "filter=ansible_os_family"
# Use facts in playbooks
- name: Show Windows version
debug:
msg: "{{ ansible_distribution }} {{ ansible_distribution_version }}"
Conclusion
Ansible transforms Windows Server 2025 administration from a series of manual Remote Desktop sessions into a repeatable, version-controlled, and auditable automation practice. By enabling WinRM with NTLM authentication, organizing managed hosts into inventory groups, storing secrets in Ansible Vault, and composing idempotent playbooks with the ansible.windows collection, teams can manage dozens or hundreds of Windows Server 2025 instances with confidence. As the environment grows, consider integrating Ansible with AWX or Red Hat Ansible Automation Platform for a web-based dashboard, role-based access control, and scheduled job execution across your entire Windows server fleet.