Managing and Configuring Windows Servers Using Ansible

Managing and Configuring Windows Servers Using Ansible. Ansible is an open source tool that enables the automation of managing and configuring Windows servers. With Ansible, we define tasks in simple and reusable playbooks, such as installing software, configuring services, managing users and groups, and more. This article discusses how we start managing Windows hosts with Ansible.

Managing and Configuring Windows Servers Using Ansible

Unlike Unix based hosts, Ansible can’t communicate with Windows hosts without pre configuration. Before configuring Windows Servers with Ansible, let’s discuss the basic overview of Ansible in general.

Overview of Ansible

Ansible is IT automation engine that handles cloud provisioning, configuration management, application deployment, and intra service orchestration. Ansible models our IT infrastructure by specifying how our systems interact. Simple to deploy since it doesn’t require agents or any other proprietary security infrastructure, and it employs a simple language that lets us describe our automation jobs in a manner that resembles plain English.

In this section, we briefly overview Ansible components.


Ansible operates by connecting to our nodes and sending Ansible modules—scripts—to them. The majority of modules take parameters that specify the ideal system state. After that, Ansible runs these modules (by default over SSH) and deletes them. No servers, daemons, or databases are necessary; our library of modules store on any computer.


To reduce maintenance and duplication when several modules share the same code, Ansible caches those routines as module utilities. For example, the principle that parses URLs is lib/ansible/module_utils/ Of course, we can write our module utilities as well. Unfortunately, we only write module utilities in Python or PowerShell.


Plugins extend the basic capabilities of Ansible. While plugins run on the control node within the /usr/bin/ansible process, modules run on the target machine in separate processes (often on a remote approach). For Ansible’s essential functions, such as data transformation, logging output, connecting to inventories, and more, plugins provide options and enhancements. 


By default, Ansible groups all of our controlled devices into groups that we specify in a file (INI, YAML, etc.) that reflects the computers it maintains. It is always easy to figure out why a specific machine didn’t get connected because of mysterious NTP or DNS issues because there is no additional SSL signing server required to join new hosts.

Here’s what a hosts.ini plain text inventory file looks like:



Once we identify the inventory hosts, they have variables assigned to them either directly in the inventory file or as simple text files (in a directory called “group_vars” or “host_vars“). Alternatively, we may use a dynamic inventory to get our inventory from sources like EC2, Rackspace, OpenStack, and others on inventory, groups, and variables.


Playbooks precisely manage how many computers to handle at once while orchestrating multiple slices of our infrastructure topology. The most intriguing parts of Ansible begin with these playbooks.

As our automation code here’s what a simple playbook looks like:

					- hosts: webservers
  serial: 6
  - common
  - webapp

- hosts: content_servers
  - common
  - content

Enable the WinRM CredSSP Listener

Windows Remote Management (WinRM) is a management protocol used by Windows to communicate with another server remotely. It is a SOAP based protocol that communicates over HTTP/HTTPS and is part of all current Windows operating systems. Since Windows Server 2012, WinRM has been built in the server, but in most cases, we must preconfigure to use WinRM with Ansible.

Several options we use when authenticating with an account when connecting to a Windows host.

In this case, if we use an Active Directory (AD) Service Account, we refer to the Active Directory Accounts column. Also, from the table above, this setup includes HTTP Encryption which makes our connection more secure. Conveniently, Ansible has a ready made package that we use to ensure that we have created a proper listener for Ansible to use.

Configure Windows Remoting with Ansible Using PowerShell

Open Windows PowerShell with elevated administrator privileges and run the following snippet inside an unconfigured Windows host. Please note that we may need to set the execution policy with the Set-ExecutionPolicy cmdlet since the PowerShell file comes from an external and untrusted (at least from a Windows host perspective) source:

Set-Location -Path "C:\Temp" -PassThru
.\ConfigureRemotingForAnsible.ps1 -EnableCredSSP -DisableBasicAuth -Verbose

Verify, if the above command has been properly executed by running the command below:

					winrm enumerate winrm/config/listener

We should now have at least two (2) listeners, the default WinRM HTTP listener and the new Ansible HTTPS CredSSP Listener. Restart the winrm service with the Restart-Service command to apply the changes.:

					Restart-Service winrm

Deleting the Default HTTP Listener

Since Ansible uses a more secure HTTPS listener, we safely remove the default HTTP listener. However, this step is optional as, though unlikely; we may have applications using the default listener. To remove the default HTTP listener, run the below script:

					To remove the default HTTP listener, run the below script:
 winrm delete winrm/config/Listener?Address=*+Transport=HTTP


Remember to restart the winrm service to apply the changes.

Enabling the Ansible Listener on Multiple Hosts Using PowerShell

We should manage multiple Windows hosts and enable their Ansible listeners. In that case, we do not need to manually remote into the server to download the package and repeatedly follow the steps above. Instead, we have a script that enables the CredSSP in a batch manner.

					$servers = @("Server1", "Server2", "Server3") # Replace with the names of your servers or use Get-Content
$username = "YourUsername" # Replace with your username
$password = ConvertTo-SecureString "YourPassword" -AsPlainText -Force # Replace with your password

foreach ($server in $servers) {
    $cred = New-Object System.Management.Automation.PSCredential ($username, $password)
    $session = New-PSSession -ComputerName $server -Credential $cred
    Invoke-Command -Session $session -ScriptBlock {
        Set-Location -Path "C:\Temp" -PassThru
        .\ConfigureRemotingForAnsible.ps1 -EnableCredSSP -DisableBasicAuth -Verbose
        Restart-Service winrm
    Remove-PSSession -Session $session

Before running the script above, make sure that:


  1. We are running elevated PowerShell;
  2. We execute the PowerShell file in a server/workstation that reaches the planned multiple hosts, like a jump server; and
  3. We have proper credentials that have local administrator rights.

Once done, we may add the hostname/FQDN of the Windows host to the Ansible Inventory, which we discuss next.

Add the Host to the Ansible Inventory

Now that we have prepared our Windows hosts to manage remotely with Ansible, we start adding them to the Ansible Inventory. To start, connect to our Ansible master node.

As mentioned, Ansible uses hosts.ini to manage the inventory by default, but as with any default, we change it to our preference. So, the default inventory file may differ from what is presented below. To add a host entry, open the inventory file in a command line editor.

Now add the FQDN/IP Address inside the child groups. Please note that we use different hierarchy structures and formatting per inventory file. For this article, we are using a YAML inventory file, which should look something like this:


Note: When building the Ansible inventory, any deviation from the proper formatting imposed by Ansible may result in errors when running the Ansible playbooks later.

Test Ansible Host Connectivity

We use the Ansible command and built-in modules to ensure that we reach the host from Ansible for remote management. We use the win_ping module, part of the Ansible Core built-in package that tests the connectivity of Windows hosts. Internally, here is the basic syntax of an Ansible command:

					ansible  -m ""



  • Child Group: is the list of one or more hosts that Ansible runs the module on;
  • -m (or –module-name)is the parameter responsible for the module name of the action that we execute on the child group

For example, if we refer to the above Ansible inventory, we run a ping test on the group by running the command below as an elevated superuser:

					ansible all -m "win_ping"

Ansible modules output the result in JSON format, which uses a key-value pair. In this case, the win_ping module, when successful, returns an output that should look something like this:

This means that Ansible reaches the host, otherwise:

Once GREEN, Ansible remotely accesses into the server to perform configuration management. From here, we either start writing our first playbook or continue organizing the Ansible inventory that conforms to the best practices.

Thank you for reading the article Managing and Configuring Windows Servers Using Ansible. We shall conclude it now. 

Managing and Configuring Windows Servers Using Ansible Conclusion

In conclusion, Ansible is a powerful tool that we also use for managing and configuring Windows servers. With its simple and reusable playbooks, we automate tasks, making our job as system administrators more efficient and effective. Furthermore, by using Ansible to manage and configure our Windows servers, we reduce time and effort required for server management, enabling cross-functionality with UNIX-based operating systems.

Avatar for Marion Mendoza
Marion Mendoza

Windows Server and VMware SME. Powershell Guru. Currently working with Fortune 500 companies responsible for participating in 3rd level systems support across the enterprise. Acting as a Windows Server engineer and VMware Specialist.

0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Would love your thoughts, please comment.x