Ansible Windows Automation

Ansible manages Windows servers as comfortably as Linux servers. The control node must run Linux or macOS, and Windows machines serve as managed nodes. The communication method differs. Linux uses SSH and Python. Windows uses WinRM (Windows Remote Management) or OpenSSH, and tasks run through PowerShell. Picture a translator at a meeting: Ansible speaks one language, and the connection layer converts every instruction into PowerShell that Windows understands.

Diagram: The Windows Connection

  Linux Control Node                 Windows Server
  ┌────────────────┐   WinRM 5986    ┌─────────────────────┐
  │ Ansible        │════ HTTPS ════▶│ WinRM listener      │
  │ pywinrm        │                 │      │              │
  └────────────────┘                 │      ▼              │
                                     │ PowerShell runs     │
                                     │ the module code     │
                                     └─────────────────────┘

Prepare the Control Node

python3 -m pip install pywinrm
ansible-galaxy collection install ansible.windows community.windows

Prepare the Windows Host

Run a PowerShell session as administrator on each Windows server. The official ConfigureRemotingForAnsible.ps1 script enables WinRM for lab use. Production systems need HTTPS listeners with valid certificates and a firewall rule for port 5986.

winrm enumerate winrm/config/listener
Test-WSMan localhost

Define the Inventory

[windows]
win1 ansible_host=10.0.2.20
win2 ansible_host=10.0.2.21

[windows:vars]
ansible_user=Administrator
ansible_connection=winrm
ansible_port=5986
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=validate

Keep the account password out of this file. Define ansible_password in an encrypted vault file inside group_vars/windows/. Switch the certificate setting to ignore only in a closed lab.

Test the Connection

ansible windows -m ansible.windows.win_ping

A reply of pong confirms the setup.

Windows Module Names

Windows modules start with win_.

TaskModule
Copy a fileansible.windows.win_copy
Manage a serviceansible.windows.win_service
Run a commandansible.windows.win_command
Run PowerShellansible.windows.win_shell
Edit the registryansible.windows.win_regedit
Add Windows featuresansible.windows.win_feature
Install updatesansible.windows.win_updates
Install packageschocolatey.chocolatey.win_chocolatey
Manage usersansible.windows.win_user
Open firewall portscommunity.windows.win_firewall_rule

Set Up an IIS Web Server

- name: Configure IIS
  hosts: windows
  tasks:
    - name: Install the IIS feature
      ansible.windows.win_feature:
        name: Web-Server
        state: present
        include_management_tools: true
      register: iis_install

    - name: Reboot when required
      ansible.windows.win_reboot:
      when: iis_install.reboot_required

    - name: Create the site folder
      ansible.windows.win_file:
        path: C:\inetpub\shop
        state: directory

    - name: Copy the home page
      ansible.windows.win_copy:
        src: files/index.html
        dest: C:\inetpub\shop\index.html

    - name: Open port 80
      community.windows.win_firewall_rule:
        name: Allow HTTP
        localport: 80
        action: allow
        direction: in
        protocol: tcp
        state: present
        enable: yes

Run PowerShell

- name: List the five biggest processes
  ansible.windows.win_shell: |
    Get-Process | Sort-Object WS -Descending | Select-Object -First 5 Name, WS
  register: top_processes

- ansible.builtin.debug:
    var: top_processes.stdout_lines

Windows Paths in YAML

Backslashes behave differently inside quotes. Plain unquoted or single quoted strings keep backslashes literally. Double quoted strings treat a backslash as an escape character, so write "C:\\inetpub" in that style.

Patch Windows

- name: Install security updates
  ansible.windows.win_updates:
    category_names:
      - SecurityUpdates
      - CriticalUpdates
    reboot: true

Common Problems

  • A timeout often means the firewall blocks port 5986
  • An authentication error suggests the wrong transport setting for the account type
  • Domain accounts work best with the kerberos transport
  • Fact gathering on Windows takes a few seconds longer than on Linux

Try This

Prepare one Windows lab machine with WinRM. Add it to the inventory and run win_ping. Write a playbook that creates the folder C:\Practice and copies a text file into it. Run the playbook twice to confirm the second run reports no change.

Summary

Ansible manages Windows through WinRM or OpenSSH and runs tasks with PowerShell. Modules named win_* handle files, services, features, registry keys, updates, and packages. Secure HTTPS connections, vault-stored passwords, and correct transport settings keep Windows automation reliable and safe.