
Executive Summary
Ansible can manage Windows systems by connecting from an Ansible control node to Windows hosts over WinRM, then executing automation tasks through PowerShell on the remote machine. Instead of installing an agent on each Windows server, Ansible uses inventory, playbooks, variables, and Windows-specific modules to handle tasks such as installing software, copying files, managing services, creating users, applying configuration, and running administrative commands.
For administrators who already understand Ansible basics, the important shift is this: Windows automation uses the same playbook model, but the transport, authentication, modules, and command syntax are different. Linux hosts commonly use SSH and shell commands. Windows hosts commonly use WinRM, PowerShell, and modules prefixed with win_.
For broader context, this article fits into the Automation and DevOps Guide and the Infrastructure & Systems Guide.
Operational Tip: Treat Windows automation as configuration management first, not remote scripting. Use purpose-built modules whenever possible, and reserve raw PowerShell commands for cases where no module fits.
What Changes When You Manage Windows Instead of Linux?
The overall Ansible workflow stays familiar. You still define hosts in an inventory, write playbooks in YAML, organize reusable logic with roles, and run tasks from a control node. The differences appear in the connection method, authentication model, operating system behavior, and module choices.
- Connection: Windows nodes commonly use WinRM instead of SSH.
- Execution engine: Most Windows tasks are executed through PowerShell.
- Modules: Windows automation relies on modules such as
win_package,win_service,win_copy,win_user, andwin_shell. - Paths: Windows paths require care with backslashes, quoting, and drive letters.
- Reboots: Many Windows changes, especially patches and feature installs, may require controlled reboots.
- Authentication: Domain accounts, local accounts, Kerberos, NTLM, and certificate-based options may all be relevant.
The best results come from writing idempotent tasks. An idempotent playbook can run repeatedly without causing unnecessary changes. For example, a task that ensures a service is running should report “changed” only when Ansible actually starts or modifies that service.
How WinRM and PowerShell Fit Together
WinRM, short for Windows Remote Management, is the protocol Ansible commonly uses to communicate with Windows hosts. It allows remote command execution and configuration over HTTP or HTTPS ports, subject to firewall, listener, and authentication settings.
Ansible sends module code to the target machine, Windows runs that code through PowerShell, and Ansible receives structured results back. This is why PowerShell version, execution policy, remoting configuration, and permissions matter even when you are using high-level Ansible modules.
Common WinRM Setup Considerations
- Confirm WinRM is enabled and listening on the Windows host.
- Allow the required WinRM ports through Windows Firewall.
- Choose an authentication method that matches your environment.
- Prefer encrypted communication, especially outside isolated lab networks.
- Use accounts with only the privileges needed for the automation task.
In domain environments, Kerberos is often preferred because it integrates with Active Directory. In smaller labs, NTLM or local administrator credentials may be used, but credentials should be handled carefully with Ansible Vault or another approved secrets management process.
Prerequisites Before You Start
Before running Windows playbooks, confirm both the control node and managed hosts are ready. The control node is usually Linux, macOS, or a supported automation platform. The managed hosts are the Windows servers or workstations you want Ansible to configure.
| Area | What to Verify |
|---|---|
| Control node | Ansible installed, Python dependencies available, and access to inventory files. |
| Windows host | WinRM enabled, PowerShell available, firewall rules correct, and DNS or IP connectivity working. |
| Credentials | Administrative or delegated permissions stored securely instead of hardcoded in playbooks. |
| Network | Reliable name resolution, allowed WinRM ports, and no proxy or inspection device breaking sessions. |
A simple inventory entry for Windows might define the host, connection type, port, transport, username, and password or vault-protected variable. Keep sensitive values out of source control, and separate environment-specific data from reusable playbook logic.
Common Windows Automation Use Cases
Software Deployment
Ansible can install MSI packages, EXE installers, and software from internal file shares. With win_package, you can define the installer path, expected product identifier, arguments, and desired state. This is useful for standard agents, monitoring tools, runtimes, and line-of-business applications.
Patching and Reboots
Windows patching often involves updates, restarts, and post-reboot validation. Ansible can coordinate update installation, reboot handling, service checks, and reporting. Always test patching logic carefully because update duration and reboot behavior can vary across Windows versions and workloads.
Configuration Management
Configuration tasks include copying application files, setting registry values, adjusting local policy-related settings, managing scheduled tasks, and ensuring directories exist. The goal is to describe the desired state clearly, then let Ansible converge machines toward that state.
Service Management
Windows services are common automation targets. You may need to start a service, stop it before maintenance, change its startup mode, or restart it after a configuration file changes. The win_service module is usually better than calling net stop or sc.exe manually.
Compliance and Audit Tasks
Ansible can help validate local users, installed software, required files, service states, and command outputs. While it is not a complete compliance platform by itself, it can collect consistent evidence and correct many drift issues automatically.
Useful Windows Ansible Modules
| Module | Use Case |
|---|---|
win_package | Install, uninstall, or verify software packages. Provide identifiers or creates-style checks so Ansible can determine whether the package is already present. |
win_service | Manage Windows services, including service state and startup behavior. |
win_copy | Transfer files from the control node to a Windows host for configuration, scripts, templates, certificates, or support files. |
win_shell | Run PowerShell command or script fragments when no purpose-built module fits. Add conditions or changed-status handling to avoid noisy playbook results. |
win_user | Create, update, or remove local Windows accounts. Protect passwords with Ansible Vault and review local account policies before broad deployment. |
Complete Sample Playbook
The following playbook demonstrates several realistic Windows tasks in one place. It installs software, ensures a service is running, copies a configuration file, creates a local user account, and runs a PowerShell command. Adjust paths, product IDs, service names, and credentials for your environment.
---
- name: Basic Windows management with Ansible
hosts: windows_servers
gather_facts: false
vars:
app_installer: C:InstallersExampleAgent.msi
app_config_source: filesexample-agent.conf
app_config_dest: C:ProgramDataExampleAgentexample-agent.conf
local_admin_user: rht_local_ops
local_admin_password: "{{ vault_local_admin_password }}"
tasks:
- name: Install Example Agent
ansible.windows.win_package:
path: "{{ app_installer }}"
state: present
arguments: /qn /norestart
- name: Ensure Example Agent service is automatic and running
ansible.windows.win_service:
name: ExampleAgent
start_mode: auto
state: started
- name: Copy Example Agent configuration file
ansible.windows.win_copy:
src: "{{ app_config_source }}"
dest: "{{ app_config_dest }}"
- name: Create a local operations account
ansible.windows.win_user:
name: "{{ local_admin_user }}"
password: "{{ local_admin_password }}"
state: present
groups:
- Administrators
password_never_expires: true
user_cannot_change_password: true
- name: Run a PowerShell health check command
ansible.windows.win_shell: |
$service = Get-Service -Name ExampleAgent
"ExampleAgent status is $($service.Status)"
register: agent_health
- name: Show health check output
ansible.builtin.debug:
var: agent_health.stdout
This playbook is intentionally simple. In production, you would likely add handlers, tags, pre-checks, validation tasks, and role-based organization. You may also use win_reboot when installers or updates require a restart.
Production Reminder: A playbook that works in a lab can still fail in production because of pending reboots, locked files, installer return codes, antivirus interference, Group Policy, or delegated-account limitations. Build validation checks into the playbook instead of assuming every host is identical.
Practical Setup and Safety Tips
- Start with inventory groups. Separate development, test, and production Windows hosts so you can roll out changes gradually.
- Use Ansible Vault. Never commit Windows passwords, domain credentials, or installer secrets in plain text.
- Prefer modules over shell commands. Modules usually provide better idempotency, clearer results, and fewer quoting problems.
- Plan for reboots. Windows maintenance often requires restarts, so define reboot windows and post-reboot checks.
- Log results. Save playbook output in your automation platform or CI system so changes are traceable.
- Handle 32-bit and 64-bit paths carefully. Some installers and registry locations differ depending on architecture.
- Validate permissions. A task that works with a domain admin account may fail with a delegated service account.
FAQ: Managing Windows with Ansible
Does Ansible require an agent on Windows?
No. Ansible normally connects over WinRM and runs tasks remotely without installing a persistent Ansible agent on the Windows host.
Can Ansible manage both Windows servers and workstations?
Yes, if the machines are reachable, WinRM is configured, credentials are valid, and your organization allows remote management of those endpoints.
Should I use win_shell for everything?
No. Use dedicated Windows modules first. Use win_shell only when you need PowerShell flexibility that a module does not provide.
Related RavenHawkTech Reading
- Automation and DevOps Guide — broader automation, scripting, CI/CD, observability, and change-control guidance.
- Infrastructure & Systems Guide — the systems foundation Windows automation depends on.
- Graylog Podman Pod Deployment and Upgrade Guide — an example of repeatable infrastructure deployment and operational maintenance.
Key Takeaway: Managing Windows with Ansible is approachable when you begin with safe, repeatable tasks and expand after testing. Build playbooks in non-production environments, validate results carefully, and roll changes broadly only after you understand the impact.
