When using Ansible to manage Windows, many of the syntax and rules that apply
for Unix/Linux hosts also apply to Windows, but there are still some differences
when it comes to components like path separators and OS-specific tasks.
This document covers details specific to using Ansible for Windows.

Some installers like Microsoft Office or SQL Server require credential delegation or
access to components restricted by WinRM. The best method to bypass these
issues is to use become with the task. With become, Ansible will run
the installer as if it were run interactively on the host.

Note

Many installers do not properly pass back error information over WinRM. In these cases, if the install has been verified to work locally the recommended method is to use become.

Note

Some installers restart the WinRM or HTTP services, or cause them to become temporarily unavailable, making Ansible assume the system is unreachable.

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.

Note

The win_hotfix module has a requirement that the DISM PowerShell cmdlets are
present. These cmdlets were only added by default on Windows Server 2012
and newer and must be installed on older Windows hosts.

The following example shows how win_updates can be used:

-name:install all critical and security updateswin_updates:category_names:-CriticalUpdates-SecurityUpdatesstate:installedregister:update_result-name:reboot host if requiredwin_reboot:when:update_result.reboot_required

The following example show how win_hotfix can be used to install a single
update or hotfix:

The following is an example of creating local accounts and groups that can
access a folder on the same host:

-name:create local group to contain new userswin_group:name:LocalGroupdescription:Allow access to C:\Development folder-name:create local userwin_user:name:'{{item.name}}'password:'{{item.password}}'groups:LocalGroupupdate_password:nopassword_never_expired:yeswith_items:-name:User1password:Password1-name:User2password:Password2-name:create Development folderwin_file:path:C:\Developmentstate:directory-name:set ACL of Development folderwin_acl:path:C:\Developmentrights:FullControlstate:presenttype:allowuser:LocalGroup-name:remove parent inheritance of Development folderwin_acl_inheritance:path:C:\Developmentreorganize:yesstate:absent

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.

The win_command module simply runs a process outside of a shell. It can still
run a shell command like mkdir or New-Item by passing the shell commands
to a shell executable like cmd.exe or PowerShell.exe.

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.

Ansible version 2.5 added modules that make it easier to work with scheduled tasks in Windows.
The following is an example of running a script as a scheduled task that deletes itself after
running:

-name:create scheduled task to run a processwin_scheduled_task:name:adhoc-taskusername:SYSTEMactions:-path:PowerShell.exearguments:|Start-Sleep -Seconds 30 # this isn't required, just here as a demonstrationNew-Item -Path C:\temp\test -ItemType Directory# remove this action if the task shouldn't be deleted on completion-path:cmd.exearguments:/c schtasks.exe /Delete /TN "adhoc-task" /Ftriggers:-type:registration-name:wait for the scheduled task to completewin_scheduled_task_stat:name:adhoc-taskregister:task_statuntil:(task_stat.state is defined and task_stat.state.status != "TASK_STATE_RUNNING") or (task_stat.task_exists == False)retries:12delay:10

Note

The modules used in the above example were updated/added in Ansible
version 2.5.

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:

GOODtempdir:C:\Windows\TempWORKStempdir:'C:\Windows\Temp'tempdir:"C:\\Windows\\Temp"BAD, BUT SOMETIMES WORKStempdir:C:\\Windows\\Temptempdir:'C:\\Windows\\Temp'tempdir:C:/Windows/TempFAILStempdir:"C:\Windows\Temp"---# example of single quotes when they are required-name:copy tomcat configwin_copy:src:log4j.xmldest:'{{tc_home}}\lib\log4j.xml'

The legacy key=value syntax is used on the command line for adhoc 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.

Here are some examples of using Windows paths with the key=value style:

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.

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