Introduction to Ansible for Windows Server 2019
Ansible is an open-source IT automation platform developed by Red Hat that enables infrastructure as code for provisioning, configuration management, application deployment, and orchestration. While Ansible was originally designed for Linux management using SSH, it fully supports Windows Server 2019 management using WinRM (Windows Remote Management) as the transport. Ansible for Windows uses PowerShell natively, giving access to the full power of Windows management without installing agents on managed nodes. The Ansible control node where Ansible itself is installed must run on Linux or macOS. Ansible is agentless by design, and Windows Server 2019 only requires WinRM to be enabled and configured. This makes Ansible an excellent choice for automating Windows server configuration alongside Linux systems in heterogeneous environments.
Setting Up the Ansible Control Node
Install Ansible on a Linux control node such as Ubuntu 22.04. The control node manages Windows Server 2019 targets via WinRM. Install Ansible and required Python packages:
sudo apt-get update && sudo apt-get install -y python3-pip python3-dev
pip3 install ansible pywinrm kerberos requests-kerberos
ansible --version
Install the community.windows and ansible.windows Ansible Galaxy collections which provide Windows-specific modules:
ansible-galaxy collection install ansible.windows
ansible-galaxy collection install community.windows
ansible-galaxy collection install microsoft.ad
Preparing Windows Server 2019 for Ansible
Windows Server 2019 must have WinRM configured to accept Ansible connections. Ansible provides a configuration script that sets up WinRM with the correct settings. Run this from an elevated PowerShell session on the Windows Server 2019 machine:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:TEMPConfigureRemotingForAnsible.ps1"
Invoke-WebRequest -Uri $url -OutFile $file
& $file -EnableCredSSP -DisableBasicAuth -SkipNetworkProfileCheck
Alternatively, manually configure WinRM for HTTPS with a self-signed certificate:
Enable-PSRemoting -Force
$cert = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME -CertStoreLocation Cert:LocalMachineMy
New-Item -Path WSMan:localhostListener -Transport HTTPS -Address * -CertificateThumbprint $cert.Thumbprint -Force
Set-Item WSMan:localhostServiceAuthBasic -Value $true
Set-Item WSMan:localhostServiceAllowUnencrypted -Value $false
New-NetFirewallRule -DisplayName "WinRM HTTPS Ansible" -Direction Inbound -Protocol TCP -LocalPort 5986 -Action Allow
Verify WinRM is listening on the correct ports:
winrm enumerate winrm/config/Listener
netstat -ano | findstr "5985|5986"
Creating the Ansible Inventory
The inventory file defines which hosts Ansible manages and how to connect to them. Create an inventory for Windows Server 2019 machines. Create /etc/ansible/hosts or a project-specific inventory file:
[windows_servers]
ws2019-01.contoso.com
ws2019-02.contoso.com
ws2019-03.contoso.com
[windows_servers:vars]
ansible_user=Administrator
ansible_password=AdminP@ssw0rd123
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore
ansible_winrm_port=5986
ansible_winrm_scheme=https
ansible_become=false
For Kerberos authentication (recommended in domain environments), use:
[windows_servers:vars]
[email protected]
ansible_password=AnsibleSvc@123!
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_winrm_server_cert_validation=ignore
ansible_winrm_kerberos_delegation=true
Testing Ansible Connectivity
Test connectivity from the Ansible control node to Windows Server 2019 using the win_ping module:
ansible windows_servers -m win_ping
ansible ws2019-01.contoso.com -m win_ping -i inventory.ini
ansible windows_servers -m win_command -a "whoami" -i inventory.ini
ansible windows_servers -m win_shell -a "Get-Service | Where-Object {$_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic'}" -i inventory.ini
Gather facts about Windows Server 2019 machines:
ansible ws2019-01.contoso.com -m setup -i inventory.ini | head -100
ansible windows_servers -m win_gather_facts -i inventory.ini
Writing Ansible Playbooks for Windows Server 2019
Ansible playbooks are YAML files that define automation tasks. Create a playbook to configure Windows Server 2019 security settings:
---
- name: Configure Windows Server 2019 Security Baseline
hosts: windows_servers
gather_facts: true
tasks:
- name: Disable SMBv1
ansible.windows.win_feature:
name: FS-SMB1
state: absent
- name: Enable Windows Firewall
community.windows.win_firewall:
profiles:
- Domain
- Private
- Public
state: enabled
- name: Set password policy
community.windows.win_security_policy:
section: System Access
key: MinimumPasswordLength
value: 14
- name: Configure Windows Update
community.windows.win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
state: installed
reboot: false
- name: Enable RDP with NLA
ansible.windows.win_reg_entry:
path: HKLM:SystemCurrentControlSetControlTerminal ServerWinStationsRDP-Tcp
name: UserAuthentication
data: 1
type: dword
- name: Disable AutoRun
ansible.windows.win_reg_entry:
path: HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesExplorer
name: NoDriveTypeAutoRun
data: 255
type: dword
Run the playbook:
ansible-playbook -i inventory.ini windows_security_baseline.yml
ansible-playbook -i inventory.ini windows_security_baseline.yml --check # Dry run
ansible-playbook -i inventory.ini windows_security_baseline.yml --diff # Show changes
Managing Windows Features and Roles with Ansible
Install and remove Windows Server roles and features using the win_feature module. Create a playbook for a web server role configuration:
---
- name: Configure IIS Web Server
hosts: web_servers
tasks:
- name: Install IIS
ansible.windows.win_feature:
name:
- Web-Server
- Web-Asp-Net45
- Web-Windows-Auth
- Web-Common-Http
- Web-Default-Doc
- Web-Http-Logging
state: present
include_management_tools: true
register: iis_install
- name: Reboot if IIS installation requires it
ansible.windows.win_reboot:
when: iis_install.reboot_required
- name: Create web application directory
ansible.windows.win_file:
path: C:inetpubwwwrootMyApp
state: directory
- name: Copy web application files
ansible.windows.win_copy:
src: files/webapp/
dest: C:inetpubwwwrootMyApp
- name: Create IIS application pool
community.windows.win_iis_webapppool:
name: MyAppPool
state: started
attributes:
managedRuntimeVersion: v4.0
startMode: AlwaysRunning
- name: Create IIS website
community.windows.win_iis_website:
name: MyWebSite
state: started
port: 443
ip: "*"
application_pool: MyAppPool
physical_path: C:inetpubwwwrootMyApp
Patching Windows Server 2019 with Ansible
Use the win_updates module to automate patch management across Windows Server 2019 machines. Create a patching playbook with pre and post-patch health checks:
---
- name: Patch Windows Server 2019
hosts: windows_servers
serial: 1
tasks:
- name: Check disk space before patching
ansible.windows.win_shell: |
$disk = Get-PSDrive C
$freeGB = [math]::Round($disk.Free/1GB, 2)
if ($freeGB -lt 10) { Write-Error "Insufficient disk space: ${freeGB}GB free" }
Write-Output "Free disk space: ${freeGB}GB"
- name: Install critical and security updates
ansible.windows.win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
- UpdateRollups
state: installed
reboot: false
register: update_result
- name: Display update summary
ansible.builtin.debug:
msg: "Installed {{ update_result.installed_update_count }} updates"
- name: Reboot if updates require it
ansible.windows.win_reboot:
reboot_timeout: 600
post_reboot_delay: 60
when: update_result.reboot_required
- name: Verify server is responsive after reboot
ansible.windows.win_ping:
Run the patching playbook with controlled serial execution:
ansible-playbook -i inventory.ini patch_windows.yml --limit ws2019-01.contoso.com
ansible-playbook -i inventory.ini patch_windows.yml --tags "security" --forks 1
Using Ansible Vault for Credentials
Store sensitive credentials such as Windows admin passwords and service account credentials securely using Ansible Vault. Create an encrypted variables file:
ansible-vault create group_vars/windows_servers/vault.yml
# Enter the vault password when prompted, then add:
# vault_ansible_password: "AdminP@ssw0rd123"
# vault_domain_admin_password: "DomainAdmin@123"
# vault_service_account_password: "SvcAccount@456"
Reference vault variables in your inventory and playbooks:
# group_vars/windows_servers/vars.yml
ansible_password: "{{ vault_ansible_password }}"
# Run playbooks with vault password
ansible-playbook -i inventory.ini site.yml --ask-vault-pass
ansible-playbook -i inventory.ini site.yml --vault-password-file ~/.ansible_vault_pass
Ansible for Windows Server 2019 provides a powerful, agentless automation platform that enables consistent configuration management, application deployment, and patch management across large Windows server fleets using familiar YAML syntax and an extensive library of Windows-specific modules.