Introduction

Ansible is a powerful agentless IT automation platform that can manage Windows Server 2016 hosts via WinRM (Windows Remote Management). Unlike Linux automation over SSH, Ansible reaches Windows servers through WinRM using NTLM or Kerberos authentication. This guide covers configuring Windows Server 2016 as a fully managed Ansible node — enabling WinRM with HTTPS, configuring authentication, setting firewall rules, and validating connectivity from an Ansible control node.

Understanding WinRM and Ansible

Ansible communicates with Windows over the WinRM protocol using the winrm Python library. Key configuration points are: the WinRM listener (HTTP port 5985 or HTTPS port 5986), the authentication method (Basic, NTLM, Kerberos, or CredSSP), and the firewall rules allowing the control node to reach the WinRM ports. Ansible recommends HTTPS WinRM with NTLM or Kerberos for production environments.

Configuring WinRM on Windows Server 2016

Run Microsoft’s official WinRM setup script on the Windows Server 2016 target node. This is the recommended Ansible configuration script:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:tempConfigureRemotingForAnsible.ps1"
(New-Object System.Net.WebClient).DownloadFile($url, $file)
# Run with certificate authentication enabled
powershell.exe -ExecutionPolicy ByPass -File $file -EnableCredSSP -ForceNewSSLCert

Manually Configuring HTTPS WinRM

For environments without Internet access, configure WinRM HTTPS manually with a certificate:

# Create a self-signed certificate for WinRM
$cert = New-SelfSignedCertificate `
    -DnsName $env:COMPUTERNAME `
    -CertStoreLocation 'Cert:LocalMachineMy' `
    -KeySpec KeyExchange

# Create the HTTPS listener
New-WSManInstance -ResourceURI winrm/config/Listener `
    -SelectorSet @{Address='*'; Transport='HTTPS'} `
    -ValueSet @{CertificateThumbprint=$cert.Thumbprint; Enabled='true'}

# Enable the WinRM service and set startup
Enable-PSRemoting -Force
Set-Service -Name WinRM -StartupType Automatic

# Open firewall port 5986
New-NetFirewallRule -DisplayName 'WinRM HTTPS Ansible' `
    -Direction Inbound -Protocol TCP -LocalPort 5986 `
    -RemoteAddress '10.0.0.0/24' -Action Allow  # restrict to Ansible control node subnet

# Verify listeners
winrm enumerate winrm/config/Listener

Configuring Authentication

Enable NTLM and Basic authentication (or Kerberos for domain environments) on the WinRM service:

# Enable authentication methods
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service/auth '@{NTLM="true"}'
winrm set winrm/config/service/auth '@{Kerberos="true"}'
winrm set winrm/config/service/auth '@{CredSSP="true"}'

# Allow unencrypted connections (only for testing - not production)
# winrm set winrm/config/service '@{AllowUnencrypted="true"}'

# Configure MaxEnvelopeSizekb for large payloads (e.g. file copy)
winrm set winrm/config '@{MaxEnvelopeSizekb="150000"}'
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}'

# View current configuration
winrm get winrm/config

Setting Up Ansible Inventory

On the Linux Ansible control node, configure the Windows host inventory and connection variables:

# /etc/ansible/inventory/windows.ini
[windows_servers]
ws2016-01 ansible_host=10.0.0.20
ws2016-02 ansible_host=10.0.0.21

[windows_servers:vars]
ansible_user=Administrator
ansible_password=YourStrongPassword
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_scheme=https
ansible_port=5986
ansible_winrm_server_cert_validation=ignore

Installing Python WinRM Dependencies

Install required Python packages on the Ansible control node:

# Install pywinrm and Kerberos support
pip3 install pywinrm
pip3 install pywinrm[kerberos]
pip3 install pywinrm[credssp]

# Verify Ansible can reach the Windows host
ansible windows_servers -m win_ping -i /etc/ansible/inventory/windows.ini

Running Ansible Modules Against Windows Server 2016

Test common Windows Ansible modules to validate connectivity and start automation:

# Ping the Windows host
ansible ws2016-01 -m win_ping

# Get system facts
ansible ws2016-01 -m setup -a 'gather_subset=all'

# Manage Windows features via playbook
cat > /tmp/win_features.yml << EOF
- hosts: windows_servers
  tasks:
    - name: Ensure IIS is installed
      win_feature:
        name: Web-Server
        state: present
        include_management_tools: yes

    - name: Ensure Telnet Client is absent
      win_feature:
        name: Telnet-Client
        state: absent
EOF
ansible-playbook /tmp/win_features.yml -i /etc/ansible/inventory/windows.ini

Using Kerberos Authentication for Domain Accounts

For domain environments, Kerberos is the preferred authentication method over NTLM:

# Install Kerberos packages on control node (RHEL/CentOS)
yum install -y krb5-workstation krb5-libs python3-devel
pip3 install requests_kerberos

# Configure /etc/krb5.conf
cat /etc/krb5.conf | grep -A5 '[realms]'

# Update inventory for Kerberos
# ansible_winrm_transport=kerberos
# [email protected]  (UPN format required)

# Obtain a Kerberos ticket
kinit [email protected]

# Test with Kerberos
ansible ws2016-01 -m win_ping -e 'ansible_winrm_transport=kerberos'

Hardening the WinRM Configuration

Apply security hardening to the WinRM listener for production use:

# Restrict WinRM access to specific IP ranges
New-NetFirewallRule -DisplayName 'WinRM Restricted' `
    -Direction Inbound -Protocol TCP -LocalPort 5986 `
    -RemoteAddress '10.10.0.0/24' -Action Allow -Profile Domain

# Disable basic authentication in production
winrm set winrm/config/service/auth '@{Basic="false"}'

# Set a shorter idle timeout to free resources
winrm set winrm/config/winrs '@{IdleTimeoutms="60000"}'

# Audit WinRM connections via event log
Get-WinEvent -LogName 'Microsoft-Windows-WinRM/Operational' -MaxEvents 20 |
    Select-Object TimeCreated,Id,Message | Format-List

Summary

Configuring Windows Server 2016 for Ansible management via WinRM enables powerful agentless automation of Windows infrastructure. With HTTPS WinRM, NTLM or Kerberos authentication, and proper firewall restrictions, Ansible can manage Windows features, services, files, registry settings, and more — all from a central Linux control node. This configuration is the foundation for integrating Windows Server 2016 into modern DevOps and infrastructure-as-code pipelines.