For many Linux systems engineers, Ansible has become a way of life. They use Ansible to orchestrate complex deployment processes, to define multiple systems with a quick and simple configuration management tool, or somewhere in between.

However, Microsoft Windows users have generally required a different set of tools to manage systems. They also often needed a different mindset on how to handle them.

Recently Ansible has improved this situation quite a bit. The Ansible 2.3 release included a bunch of new modules for this purpose. Ansible 2.3.1 is already available for Fedora 26.

At AnsibleFest London 2017, Matt Davis, Senior Principal Software Engineer at Ansible, will lead a session covering this topic in some detail. In this article we look at how to prepare Windows systems to enable this functionality along with a few things we can do with it.

Preparing the target systems

There’s a couple of prerequisites that are required to prepare a Windows system to allow ansible to connect. The connection type used for this is “winrm” which is the Windows Remote Management protocol.

When using this ansible executes powershell on the target system. This requires a minimal version of Powershell 3.0 although it’s recommended to install the most recent version of Windows Management Framework, which at the time of writing is 5.1 and includes Powershell 5.1 as part of it.

With that in place the WinRM service needs to be configured on the Windows system. The easiest way to do this is with the ansible powershell script.

By default commands, but not scripts, can be executed by the ExecutionPolicy. However when running the script via the powershell executable this can be bypassed.

Run powershell as an an administrative user and then:

powershell.exe  -ExecutionPolicy Bypass -File ConfigureRemotingForAnsible.ps1 -CertValidityDays 3650 -Verbose

After this the WinRM service will be listening and any user with administrative privileges will be able to authenticate and connect.

Although it’s possible to use CredSSP or Kerberos for delegated (single sign-on) the simplest method just makes use of username and password via NTLM authentication.

To configure the winrm connector itself there’s a few different variables but the bare minimum to make this work for any Windows system will need:

ansible_user: 'localAdminUser'
ansible_password: 'P455w0rd'
ansible_connection: 'winrm'
ansible_winrm_server_cert_validation: 'ignore'

The last line is important with the default self-signed certificates that Windows uses for WinRM, but can be removed if using verified certificates from a central CA for the systems.

So with that in place how flexible is it? How much can really be remotely controlled and configured?

Well step one on the controlling computer is to install ansible and the winrm libraries:

dnf -y install ansible python2-winrm

With that ready there’s a fair number of the core modules avaliable but the majority of tasks are from windows specific modules.

Remote windows updates

Using ansible to define your Windows systems updates allows them to be remotely checked and deployed, whether they come directly from Microsoft or from an internal Windows Server Update Service:

ansible -i mywindowssystem, -c winrm -e ansible_winrm_server_cert_validation=ignore -u administrator -k -m win_updates

mywindowssytem | SUCCESS => {
    "changed": true, 
    "failed_update_count": 0, 
    "found_update_count": 3, 
    "installed_update_count": 3, 
    "reboot_required": true, 
    "updates": {
        "488ad51b-afca-46b9-b0de-bdbb4f56672f": {
            "id": "488ad51b-afca-46b9-b0de-bdbb4f56672f", 
            "installed": true, 
            "kb": [
                "4022726"
            ], 
            "title": "2017-06 Security Monthly Quality Rollup for Windows 8.1 for x64-based Systems (KB4022726)"
        }, 
        "94e2e9ab-e2f7-4f8c-9ade-602a0511cc08": {
            "id": "94e2e9ab-e2f7-4f8c-9ade-602a0511cc08", 
            "installed": true, 
            "kb": [
                "4022730"
            ], 
            "title": "2017-06 Security Update for Adobe Flash Player for Windows 8.1 for x64-based Systems (KB4022730)"
        }, 
        "ade56166-6d55-45a5-9e31-0fac924e4bbe": {
            "id": "ade56166-6d55-45a5-9e31-0fac924e4bbe", 
            "installed": true, 
            "kb": [
                "890830"
            ], 
            "title": "Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - June 2017 (KB890830)"
        }
    }
}

Rebooting automatically is also possible with a small playbook:

- hosts: windows
  tasks:
    - name: apply critical and security windows updates 
      win_updates:
        category_names: 
          - SecurityUpdates
          - CriticalUpdates
      register: wuout
    - name: reboot if required
      win_reboot:
      when: wuout.reboot_required

Package management

There’s two ways to handle package installs on windows using ansible.

The first is to use win_package which can install any msi or run an executable installer from a network share or uri. This is useful for more locked down internal networks with no internet connectivity or for applications not on Chocolatey. In order to avoid re-running an installer and keep any plays safe to run it’s important to lookup the product ID from the registry so that win_package can detect if it’s already installed.

The second is to use the briefly referenced Chocolatey. There is no setup required for this on the target system as the win_chocolatey module will automatically install the Chocolatey package manager if it’s not already present. To install the Java 8 Runtime Environment via Chocolatey it’s as simple as:

ansible -i mywindowssystem, -c winrm -e ansible_winrm_server_cert_validation=ignore -u administrator -k -m win_chocolatey -a "name=jre8"
mywindowssystem | SUCCESS => {
    "changed": true, 
    "rc": 0
}

And the rest…

The list is growing as ansible development continues so always check the documentation for the up-to-date set of windows modules supported. Of course it’s always possible to just execute raw powershell as well:

ansible -i mywindowssystem, -c winrm -e ansible_winrm_server_cert_validation=ignore -u administrator -k -m win_shell -a "Get-Process"
mywindowssystem | SUCCESS | rc=0 >>

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName          
-------  ------    -----      -----     ------     --  -- -----------          
     28       4     2136       2740       0.00   2452   0 cmd                  
     40       5     1024       3032       0.00   2172   0 conhost              
    522      13     2264       5204       0.77    356   0 csrss                
     83       8     1724       3788       0.20    392   1 csrss                
    106       8     1936       5928       0.02   2516   0 dllhost              
     84       9     1412        528       0.02   1804   0 GoogleCrashHandler   
     77       7     1448        324       0.03   1968   0 GoogleCrashHandler64 
      0       0        0         24                 0   0 Idle                 
      

With the collection of modules already available and the help of utilities like Chocolatey it’s already possible to manage the vast majority of the Windows estate with ansible allowing many of the same techniques and best practices already embedded in the Linux culture to make the transition over the fence, even with more complex actions such as joining or creating an Active Directory domain.

ansible -i mywindowssystem, -c winrm -e ansible_winrm_server_cert_validation=ignore -u administrator -k -m win_say -a "msg='I love my ansible, and it loves me'"