4 Things To Consider When Implementing Windows Management Using Ansible

If you’re looking to make Ansible work for Windows management, our handy guide takes you through each of the necessary steps. 

For many engineers, Ansible has become indispensable to their operations. However, for those accustomed to using Ansible in Linux, Windows presents a very different proposition. Although improvements have been made in recent times, using Ansible to implement Windows management can be a little more complicated. 

Because Windows is a non-POSIX-compliant operating system, there are differences between how Ansible interacts with them and the way Windows works. This article will highlight some of the differences between Linux/Unix hosts and hosts running Windows.

1. Use Cases

The first thing to consider is the way in which it can be used and the differences between how these are applied on Windows compared to Linux. 

a. Installing software

There are three main ways that Ansible can be used to install software:

  • Using the win_chocolatey module. This sources the program data from the default public Chocolatey repository. Internal repositories can be used instead by setting the source option.

  • Using the win_package module. This installs software using an MSI or .exe installer from a local/network path or URL.

  • Using the win_command or win_shell module to run an installer manually.

b. Installing updates

  • The win_updates and win_hotfix modules can be used to install updates or hotfixes on a host. The module win_updates is used to install multiple updates by category, while win_hotfix can be used to install a single update or hotfix file that has been downloaded locally.

c. Set up users and groups

Ansible can be used to create Windows users and groups both locally and on a domain.

  • Local - The modules win_user, win_group and win_group_membership manage Windows users, groups and group memberships locally.

  • Domain - The modules win_domain_user and win_domain_group manages users and groups in a domain. 

d. Running commands

In cases where there is no appropriate module available for a task, a command or script can be run using the win_shell, win_command, raw, and script modules.  The win_shell and win_command modules can both be used to execute a command or commands. The win_shell module is run within a shell-like process like PowerShell or cmd, so it has access to shell operators like <, >, |, ;, &&, and ||. Multi-lined commands can also be run in win_shell.  When running a command through win_command, the standard Windows argument rules apply:

  1. Each argument is delimited by a white space, which can either be a space or a tab.

  2. An argument can be surrounded by double quotes ". Anything inside these quotes is interpreted as a single argument even if it contains whitespace.

  3. A double quote preceded by a backslash \ is interpreted as just a double quote " and not as an argument delimiter.

  4. Backslashes are interpreted literally unless it immediately precedes double quotes; for example \ == \ and \" == "

  5. If an even number of backslashes is followed by a double quote, one backslash is used in the argument for every pair, and the double quote is used as a string delimiter for the argument.

  6. If an odd number of backslashes is followed by a double quote, one backslash is used in the argument for every pair, and the double quote is escaped and made a literal double quote in the argument.

e. Creating and running a scheduled task

WinRM has some restrictions in place that cause errors when running certain commands. One way to bypass these restrictions is to run a command through a scheduled task. A scheduled task is a Windows component that provides the ability to run an executable on a schedule and under a different account.

2. Path formatting for Windows

Windows differs from a traditional POSIX operating system in many ways. One of the major changes is the shift from / as the path separator to \. This can cause major issues with how playbooks are written since \ is often used as an escape character on POSIX systems.

Ansible allows two different styles of syntax; each deals with path separators for Windows differently:

a. YAML Style

When using the YAML syntax for tasks, the rules are well-defined by the YAML standard:

  • When using a normal string (without quotes), YAML will not consider the backslash an escape character.

  • When using single quotes ', YAML will not consider the backslash an escape character.

  • When using double quotes ", the backslash is considered an escape character and needs to escaped with another backslash.

b. Legacy key=value Style

The legacy key=value syntax is used on the command line for ad-hoc commands, or inside playbooks. The use of this style is discouraged within playbooks because backslash characters need to be escaped, making playbooks harder to read. The legacy syntax depends on the specific implementation in Ansible, and quoting (both single and double) does not have any effect on how it is parsed by Ansible.

The Ansible key=value parser parse_kv() considers the following escape sequences:

  • \, ', ", \a, \b, \f, \n, \r, \t and \v – Single character escape

  • \x.. – 2-digit hex escape

  • \u.... – 4-digit hex escape

  • \U........ – 8-digit hex escape

  • \N{...} – Unicode character by name

This means that the backslash is an escape character for some sequences, and it is usually safer to escape a backslash when in this form.

3. Limitations

Some things you cannot do with Ansible and Windows are:

  • Upgrade PowerShell

  • Interact with the WinRM listeners

Because WinRM is reliant on the services being online and running during normal operations, you cannot upgrade PowerShell or interact with WinRM listeners with Ansible. Both of these actions will cause the connection to fail. This can technically be avoided by using async or a scheduled task, but those methods are fragile if the process it runs breaks the underlying connection Ansible uses, and are best left to the bootstrapping process or before an image is created.

4. Developing Windows Modules

Because Ansible modules for Windows are written in PowerShell, the development guides for Windows modules differ substantially from those for standard modules. Please see Windows module development walkthrough for more information.

Bringing Windows and Ansible together 

The process for making Windows management work with Ansible, then, is very different from what most engineers may have been accustomed to using Linux. It can appear complicated and somewhat cumbersome, but as long as you follow the right steps and processes.

With the Stone Door Group we can provide consultants who can help you with your journey. With their skills and experience they can help you migrate onto the Ansible Automation Platform to help you embed automation into your key business operations.  To learn more, email letsdothis@stonedoorgroup.com.

About the Author

John Esler is a…