Ansible – Managing Windows


I have found Ansible to be a brilliant tool for helping to automate things. Since the Summer of 2020 I have spent time working with this tool to find ways to accomplish things easier and without having to physically touch systems. One thing I like about Ansible is the simplicity with which you can adapt and push changes to systems. Sure 99% of my errors are down to indentation in Yaml files but the more you work with it, the more you are used to the indentation and how it should be done.

I have shown a little bit (really a little bit) of Linux and also how you can deploy a vCenter and configure dvSwtiches in VMware. You can find those examples here. There will come a time where I will add more to those sections but recently I found myself wondering… what about Windows. As much as I really don’t prefer Windows for many things AD is still a very useful thing to have in a test environment. What I don’t want to have to do is all the manual modifications that you have to do now a days to disable services here and there or do Windows updates physically. Ok I tend to have 2 Domain controllers, 2-3 backup servers (Server and Proxies) an SQL server and maybe one or two servers more. But it still takes me time to deal with this. Sure GPOs could be the way but … it means I have to spend more time, to modify more things and I don’t want to.

So how can we utilise Ansible to avoid the fuzz of physical management or GPOs etc  (I am not saying that GPOs are bad but this is a test environment and I don’t want to have to focus more on Windows than what I should be doing, in order to get things done in my day job).

What we need to get started (Windows)

This post is a bit different from some of my other posts because I am in the process of rebuilding my lab (and automate that part) So I used a small environment on VMware fusion to set things up.

In my case I will creat 3 VMs:

  1. Testdc01 – a host intended to work as a domain controller. This vm is installed with Windows 2019  Standard Core.
  2. Testvm01 – a vm installed with Windows 2019 Standard w/ Desktop Experience.
  3. testans01 – a CentOS 7 vm where Ansible will be deployed and and we will do our testing from.

The three VMs are installed in a VMware fusion setup and using NAT. The settings for the NAT is as follows per default:

Gateway and DNS:


So first things first is we need to set an IP on the VMs after installing them.

  • Testans01 will be on
  • Testdc01 will be
  • Testvm01 will be on

That should largely take care of the early steps.

On the VMs we need to set an IP. This can be done with netsh command. The first two lines sets IP, subnet, gateway and DNS. Second line is just to verify IP and third line is to verify that we can ping the outside world.

We also need to install VMware tools. This is done by mounting the VMware tools and then running the following command: setup64.exe /S /Q/vn:

The VM restarts by itself after performing the necesary steps. “You can use get-service VMtools” To verify that the service is installed ok and started.

Next we need to add a user to the box and also set this up as a local administrator:

That is is for setting up the Windows VMs, only one step remains. Enabling the WinRM. You can do this on your own by running WinRM /q for quick configure. I prefer however to use a script prepared by ansible and running that. This makes all the changes we need and makes it very easy to get started. The script requires PowerShell version 3 and you can find it here.

Copy the script to a notepad file and save it somewhere handy. Then run it from a PowerShell prompt. You should get something like this:

As you can see a self-signed certificate is generated.

The Windows box should now be ready to be managed.

One tiny thing, if you want ping and you are on core, then you need to enable the firewall rule.

First import the NetSecurity Module

Then run “Enable-NetFirewallRule -Name FPS-ICMP4-ERQ-IN”

Ansible side

To setup Ansible you can find the instructions here.

There are however a couple of additional steps. The first is to install the pywinrm tool. To do this run:   “pip3 install pywinrm” from a cli of your linux browser. It takes a moment and it’s done.

Next step, and this is mainly because I just run some examples now to demo it. I will setup a custom hosts file. and a few arguments inside. In a future part there will be a demo on a more permanent setup of these things.

So in the host file we have the win group and then some variables. We define a username and a password. Because Windows is Windows and until very recently really hasn’t made use of ssh, you need to specify a protocol for it to work with. In our case this is WinRM.

The last line is optional and in production should not be there since you should have a real certificate there.

A couple of examples

Next lets test a simple ping to verify connectivity.

As you can see the (darker?) green color coding from running shows the command was successful and you see the SUCCESS report also.  This means we have connected successfully to the two Windows hosts.

For this post lets just try one other thing. Lets disable a service like the Downloadable Maps. You can see it here. I chose this because it exists only in the Windows version with GUI. So this means we should see it being disabled in one Windows host but not the other.

Here you can see the service in the service console, it is set to automatic delayed:

To change services we create a small yml file:

We run the script, on one host it fails because the service is not there, on the second host it is changed.

As you see it is now set to disabled on the host where it exists.

Last example is to run Windows Updates. Windows Updates are painful and time consuming. Lets do something about it.

We create a yaml file like before, not we are instructing the windows systems to reboot after installing the updates.

(This one actually may take some time to run…. especially the first time after you install Windows and patch it).

So it ran, on the GUI box it failed because I have the DNS set to the future Domain controller (next post)

However it did run on the core box as you can see here.

That is it for this time. For now that’s about it, but it’s hard to not love Ansible for how it makes life easier (at least in my opinion). Keeping in mind that I’m working on a CE version of Ansible and this stuff is right there for you without having to setup SCCM or worse yet… pay for SCCM.

Update: Just as a last note, I changed the DNS on the GUI based Windows box and re-ran the Updates and it worked also:


Ansible Documentation: Setting up a Windows Host

Youtube: Manage Windows like Linux with Ansible