Code example improvements in Windows documentation (#45055)

This PR includes:
- Using explicit yaml+jinja code-blocks
- Work around pygments lexer issues with colons (in URLs and options)
pull/48758/head
Dag Wieers 6 years ago committed by Sandra McCann
parent 007092869b
commit fd02ecd290

@ -62,7 +62,9 @@ according to the resource it is managing. A list of built in resources can be
found at `resources <https://docs.microsoft.com/en-us/powershell/dsc/resources>`_.
Using the `Registry <https://docs.microsoft.com/en-us/powershell/dsc/registryresource>`_
resource as an example, this is the DSC definition as documented by Microsoft::
resource as an example, this is the DSC definition as documented by Microsoft:
.. code-block:: powershell
Registry [string] #ResourceName
{
@ -85,9 +87,11 @@ options are parameters that are used to define the resource, such as ``Key`` and
keeping the case as-is is recommended becuase it makes it easier to distinguish DSC
resource options from Ansible's ``win_dsc`` options.
This is what the Ansible task version of the above DSC Registry resource would look like::
This is what the Ansible task version of the above DSC Registry resource would look like:
.. code-block:: yaml+jinja
- name: use win_dsc module with the Registry DSC resource
- name: Use win_dsc module with the Registry DSC resource
win_dsc:
resource_name: Registry
Ensure: Present
@ -109,15 +113,17 @@ A ``[PSCredential]`` object is used to store credentials in a secure way, but
Ansible has no way to serialize this over JSON. To set a DSC PSCredential property,
the definition of that parameter should have two entries that are suffixed with
``_username`` and ``_password`` for the username and password respectively.
For example::
For example:
PsDscRunAsCredential_username: '{{ansible_user}}'
PsDscRunAsCredential_password: '{{ansible_password}}'
.. code-block:: yaml+jinja
PsDscRunAsCredential_username: '{{ ansible_user }}'
PsDscRunAsCredential_password: '{{ ansible_password }}'
SourceCredential_username: AdminUser
SourceCredential_password: PasswordForAdminUser
.. Note:: You should set ``no_log: true`` on the task definition in
.. Note:: You should set ``no_log: yes`` on the task definition in
Ansible to ensure any credentials used are not stored in any log file or
console output.
@ -126,7 +132,9 @@ CimInstance Type
A ``[CimInstance]`` object is used by DSC to store a dictionary object based on
a custom class defined by that resource. Defining a value that takes in a
``[CimInstance]`` in YAML is the same as defining a dictionary in YAML.
For example, to define a ``[CimInstance]`` value in Ansible::
For example, to define a ``[CimInstance]`` value in Ansible:
.. code-block:: yaml+jinja
# [CimInstance]AuthenticationInfo == MSFT_xWebAuthenticationInformation
AuthenticationInfo:
@ -149,7 +157,9 @@ Simple type arrays like ``[string[]]`` or ``[UInt32[]]`` are defined as a list
or as a comma separated string which are then cast to their type. Using a list
is recommended because the values are not manually parsed by the ``win_dsc``
module before being passed to the DSC engine. For example, to define a simple
type array in Ansible::
type array in Ansible:
.. code-block:: yaml+jinja
# [string[]]
ValueData: entry1, entry2, entry3
@ -165,7 +175,9 @@ type array in Ansible::
- 3010
Complex type arrays like ``[CimInstance[]]`` (array of dicts), can be defined
like this example::
like this example:
.. code-block:: yaml+jinja
# [CimInstance[]]BindingInfo == MSFT_xWebBindingInformation
BindingInfo:
@ -196,18 +208,20 @@ force the DSC engine to run under a different account. As
``_username`` and ``_password`` suffix.
Using the Registry resource type as an example, this is how to define a task
to access the ``HKEY_CURRENT_USER`` hive of the Ansible user::
to access the ``HKEY_CURRENT_USER`` hive of the Ansible user:
.. code-block:: yaml+jinja
- name: use win_dsc with PsDscRunAsCredential to run as a different user
- name: Use win_dsc with PsDscRunAsCredential to run as a different user
win_dsc:
resource_name: Registry
Ensure: Present
Key: HKEY_CURRENT_USER\ExampleKey
ValueName: TestValue
ValueData: TestData
PsDscRunAsCredential_username: '{{ansible_user}}'
PsDscRunAsCredential_password: '{{ansible_password}}'
no_log: true
PsDscRunAsCredential_username: '{{ ansible_user }}'
PsDscRunAsCredential_password: '{{ ansible_password }}'
no_log: yes
Custom DSC Resources
````````````````````
@ -223,10 +237,10 @@ The ``Find-DscResource`` cmdlet can also be used to find custom resources. For e
.. code-block:: powershell
# find all DSC resources in the configured repositories
# Find all DSC resources in the configured repositories
Find-DscResource
# find all DSC resources that relate to SQL
# Find all DSC resources that relate to SQL
Find-DscResource -ModuleName "*sql*"
.. Note:: DSC resources developed by Microsoft that start with ``x``, means the
@ -241,9 +255,11 @@ There are three ways that a DSC resource can be installed on a host:
* Saving the module manually and copying it another host
This is an example of installing the ``xWebAdministration`` resources using
``win_psmodule``::
``win_psmodule``:
- name: install xWebAdministration DSC resource
.. code-block:: yaml+jinja
- name: Install xWebAdministration DSC resource
win_psmodule:
name: xWebAdministration
state: present
@ -255,7 +271,10 @@ The first two methods above only work when the host has access to the internet.
When a host does not have internet access, the module must first be installed
using the methods above on another host with internet access and then copied
across. To save a module to a local filepath, the following PowerShell cmdlet
can be run::
can be run:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
Save-Module -Name xWebAdministration -Path C:\temp
@ -271,21 +290,21 @@ Examples
Extract a zip file
------------------
.. code-block:: yaml
.. code-block:: yaml+jinja
- name: extract a zip file
- name: Extract a zip file
win_dsc:
resource_name: Archive
Destination: c:\temp\output
Destination: C:\temp\output
Path: C:\temp\zip.zip
Ensure: Present
Create a directory
------------------
.. code-block:: yaml
.. code-block:: yaml+jinja
- name: create file with some text
- name: Create file with some text
win_dsc:
resource_name: File
DestinationPath: C:\temp\file
@ -295,7 +314,7 @@ Create a directory
Ensure: Present
Type: File
- name: create directory that is hidden is set with the System attribute
- name: Create directory that is hidden is set with the System attribute
win_dsc:
resource_name: File
DestinationPath: C:\temp\hidden-directory
@ -306,14 +325,14 @@ Create a directory
Interact with Azure
-------------------
.. code-block:: yaml
.. code-block:: yaml+jinja
- name: install xAzure DSC resources
- name: Install xAzure DSC resources
win_psmodule:
name: xAzure
state: present
- name: create virtual machine in Azure
- name: Create virtual machine in Azure
win_dsc:
resource_name: xAzureVM
ImageName: a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201409.01-en.us-127GB.vhd
@ -321,31 +340,31 @@ Interact with Azure
ServiceName: ServiceName
StorageAccountName: StorageAccountName
InstanceSize: Medium
Windows: True
Windows: yes
Ensure: Present
Credential_username: '{{ansible_user}}'
Credential_password: '{{ansible_password}}'
Credential_username: '{{ ansible_user }}'
Credential_password: '{{ ansible_password }}'
Setup IIS Website
-----------------
.. code-block:: yaml
.. code-block:: yaml+jinja
- name: install xWebAdministration module
- name: Install xWebAdministration module
win_psmodule:
name: xWebAdministration
state: present
- name: install IIS features that are required
- name: Install IIS features that are required
win_dsc:
resource_name: WindowsFeature
Name: '{{item}}'
Name: '{{ item }}'
Ensure: Present
loop:
- Web-Server
- Web-Asp-Net45
- name: setup web content
- name: Setup web content
win_dsc:
resource_name: File
DestinationPath: C:\inetpub\IISSite\index.html
@ -357,7 +376,7 @@ Setup IIS Website
</html>
Ensure: present
- name: create new website
- name: Create new website
win_dsc:
resource_name: xWebsite
Name: NewIISSite

@ -57,7 +57,7 @@ installed version and then clone the git repo.
git clone https://github.com/ansible/ansible.git
source ansible/hacking/env-setup
# to enable Ansible on login, run the following
# To enable Ansible on login, run the following
echo ". ~/ansible/hacking/env-setup -q' >> ~/.bashrc
Can I use SSH keys to authenticate?

@ -33,7 +33,7 @@ requirement. You can use the `Upgrade-PowerShell.ps1 <https://github.com/jborean
This is an example of how to run this script from PowerShell:
.. code-block:: guess
.. code-block:: powershell
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Upgrade-PowerShell.ps1"
$file = "$env:temp\Upgrade-PowerShell.ps1"
@ -43,16 +43,16 @@ This is an example of how to run this script from PowerShell:
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force
# version can be 3.0, 4.0 or 5.1
# Version can be 3.0, 4.0 or 5.1
&$file -Version 5.1 -Username $username -Password $password -Verbose
Once completed, you will need to remove auto logon
and set the execution policy back to the default of ``Restricted``. You can
do this with the following PowerShell commands:
.. code-block:: guess
.. code-block:: powershell
# this isn't needed but is a good security practice to complete
# This isn't needed but is a good security practice to complete
Set-ExecutionPolicy -ExecutionPolicy Restricted -Force
$reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
@ -91,7 +91,7 @@ imaging process. The script `Install-WMF3Hotfix.ps1 <https://github.com/jborean9
The following PowerShell command will install the hotfix:
.. code-block:: guess
.. code-block:: powershell
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Install-WMF3Hotfix.ps1"
$file = "$env:temp\Install-WMF3Hotfix.ps1"
@ -114,7 +114,7 @@ authentication option on the service.
To use this script, run the following in PowerShell:
.. code-block:: guess
.. code-block:: powershell
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
@ -138,11 +138,15 @@ The WinRM services listens for requests on one or more ports. Each of these port
listener created and configured.
To view the current listeners that are running on the WinRM service, run the
following command::
following command:
.. code-block:: powershell
winrm enumerate winrm/config/Listener
This will output something like the following::
This will output something like the following:
.. code-block:: guess
Listener
Address = *
@ -187,6 +191,7 @@ the key options that are useful to understand are:
in the connection. To get the details of the certificate itself, run this
command with the relevant certificate thumbprint in PowerShell:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
$thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE"
@ -210,7 +215,7 @@ There are three ways to set up a WinRM listener:
* Using PowerShell to create the listener with a specific configuration. This
can be done by running the following PowerShell commands:
.. code-block:: guess
.. code-block:: powershell
$selector_set = @{
Address = "*"
@ -233,12 +238,13 @@ Delete WinRM Listener
+++++++++++++++++++++
To remove a WinRM listener:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
# remove all listeners
# Remove all listeners
Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force
# only remove listeners that are run over HTTPS
# Only remove listeners that are run over HTTPS
Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -contains "Transport=HTTPS" } | Remove-Item -Recurse -Force
.. Note:: The ``Keys`` object is an array of strings, so it can contain different
@ -251,12 +257,16 @@ There are a number of options that can be set to control the behavior of the Win
including authentication options and memory settings.
To get an output of the current service configuration options, run the
following command::
following command:
.. code-block:: powershell
winrm get winrm/config/Service
winrm get winrm/config/Winrs
This will output something like the following::
This will output something like the following:
.. code-block:: guess
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
@ -327,6 +337,7 @@ options are:
To modify a setting under the ``Service`` key in PowerShell, the following
command can be used:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
# substitute {path} with the path to the option after winrm/config/Service
@ -338,12 +349,13 @@ command can be used:
To modify a setting under the ``Winrs`` key in PowerShell, the following
command can be used:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
# substitute {path} with the path to the option after winrm/config/Winrs
# Substitute {path} with the path to the option after winrm/config/Winrs
Set-Item -Path WSMan:\localhost\Shell\{path} -Value "value here"
# for example, to change Winrs\MaxShellRunTime run
# For example, to change Winrs\MaxShellRunTime run
Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647
.. Note:: If running in a domain environment, some of these options are set by
@ -358,15 +370,18 @@ could in fact be issues with the host setup instead.
One easy way to determine whether a problem is a host issue is to
run the following command from another Windows host to connect to the
target Windows host::
target Windows host:
.. comment: Pygments powershell lexer does not support -u:Username
.. code-block:: guess
# test out HTTP
# Test out HTTP
winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig
# test out HTTPS (will fail if the cert is not verifiable)
# Test out HTTPS (will fail if the cert is not verifiable)
winrs -r:http://server:5985/wsman -u:Username -p:Password -ssl ipconfig
# test out HTTPS, ignoring certificate verification
# Test out HTTPS, ignoring certificate verification
$username = "Username"
$password = ConvertTo-SecureString -String "Password" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password

@ -28,53 +28,55 @@ There are three main ways that Ansible can be used to install software:
The ``win_chocolatey`` module is recommended since it has the most complete logic for checking to see if a package has already been installed and is up-to-date.
Below are some examples of using all three options to install 7-Zip::
Below are some examples of using all three options to install 7-Zip:
# install/uninstall with chocolatey
- name: ensure 7-Zip is installed via Chocolatey
.. code-block:: yaml+jinja
# Install/uninstall with chocolatey
- name: Ensure 7-Zip is installed via Chocolatey
win_chocolatey:
name: 7zip
state: present
- name: ensure 7-Zip is not installed via Chocolatey
- name: Ensure 7-Zip is not installed via Chocolatey
win_chocolatey:
name: 7zip
state: absent
# install/uninstall with win_package
- name: download the 7-Zip package
# Install/uninstall with win_package
- name: Download the 7-Zip package
win_get_url:
url: https://www.7-zip.org/a/7z1701-x64.msi
dest: C:\temp\7z.msi
- name: ensure 7-Zip is installed via win_package
- name: Ensure 7-Zip is installed via win_package
win_package:
path: C:\temp\7z.msi
state: present
- name: ensure 7-Zip is not installed via win_package
- name: Ensure 7-Zip is not installed via win_package
win_package:
path: C:\temp\7z.msi
state: absent
# install/uninstall with win_command
- name: download the 7-Zip package
# Install/uninstall with win_command
- name: Download the 7-Zip package
win_get_url:
url: https://www.7-zip.org/a/7z1701-x64.msi
dest: C:\temp\7z.msi
- name: check if 7-Zip is already installed
- name: Check if 7-Zip is already installed
win_reg_stat:
name: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{23170F69-40C1-2702-1701-000001000000}
register: 7zip_installed
- name: ensure 7-Zip is installed via win_command
- name: Ensure 7-Zip is installed via win_command
win_command: C:\Windows\System32\msiexec.exe /i C:\temp\7z.msi /qn /norestart
when: 7zip_installed.exists == False
when: 7zip_installed.exists == false
- name: ensure 7-Zip is uninstalled via win_command
- name: Ensure 7-Zip is uninstalled via win_command
win_command: C:\Windows\System32\msiexec.exe /x {23170F69-40C1-2702-1701-000001000000} /qn /norestart
when: 7zip_installed.exists == True
when: 7zip_installed.exists == true
Some installers like Microsoft Office or SQL Server require credential delegation or
access to components restricted by WinRM. The best method to bypass these
@ -96,9 +98,11 @@ update or hotfix file that has been downloaded locally.
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::
The following example shows how ``win_updates`` can be used:
.. code-block:: yaml+jinja
- name: install all critical and security updates
- name: Install all critical and security updates
win_updates:
category_names:
- CriticalUpdates
@ -106,26 +110,28 @@ The following example shows how ``win_updates`` can be used::
state: installed
register: update_result
- name: reboot host if required
- name: Reboot host if required
win_reboot:
when: update_result.reboot_required
The following example show how ``win_hotfix`` can be used to install a single
update or hotfix::
update or hotfix:
.. code-block:: yaml+jinja
- name: download KB3172729 for Server 2012 R2
- name: Download KB3172729 for Server 2012 R2
win_get_url:
url: http://download.windowsupdate.com/d/msdownload/update/software/secu/2016/07/windows8.1-kb3172729-x64_e8003822a7ef4705cbb65623b72fd3cec73fe222.msu
dest: C:\temp\KB3172729.msu
- name: install hotfix
- name: Install hotfix
win_hotfix:
hotfix_kb: KB3172729
source: C:\temp\KB3172729.msu
state: present
register: hotfix_result
- name: reboot host if required
- name: Reboot host if required
win_reboot:
when: hotfix_result.reboot_required
@ -139,17 +145,19 @@ The modules ``win_user``, ``win_group`` and ``win_group_membership`` manage
Windows users, groups and group memberships locally.
The following is an example of creating local accounts and groups that can
access a folder on the same host::
access a folder on the same host:
- name: create local group to contain new users
.. code-block:: yaml+jinja
- name: Create local group to contain new users
win_group:
name: LocalGroup
description: Allow access to C:\Development folder
- name: create local user
- name: Create local user
win_user:
name: '{{item.name}}'
password: '{{item.password}}'
name: '{{ item.name }}'
password: '{{ item.password }}'
groups: LocalGroup
update_password: no
password_never_expired: yes
@ -159,12 +167,12 @@ access a folder on the same host::
- name: User2
password: Password2
- name: create Development folder
- name: Create Development folder
win_file:
path: C:\Development
state: directory
- name: set ACL of Development folder
- name: Set ACL of Development folder
win_acl:
path: C:\Development
rights: FullControl
@ -172,7 +180,7 @@ access a folder on the same host::
type: allow
user: LocalGroup
- name: remove parent inheritance of Development folder
- name: Remove parent inheritance of Development folder
win_acl_inheritance:
path: C:\Development
reorganize: yes
@ -182,13 +190,15 @@ Domain
++++++
The modules ``win_domain_user`` and ``win_domain_group`` manages users and
groups in a domain. The below is an example of ensuring a batch of domain users
are created::
are created:
.. code-block:: yaml+jinja
- name: ensure each account is created
- name: Ensure each account is created
win_domain_user:
name: '{{item.name}}'
upn: '{{item.name}}@MY.DOMAIN.COM'
password: '{{item.password}}'
name: '{{ item.name }}'
upn: '{{ item.name }}@MY.DOMAIN.COM'
password: '{{ item.password }}'
password_never_expires: no
groups:
- Test User
@ -229,30 +239,32 @@ The ``win_command`` module simply runs a process outside of a shell. It can stil
run a shell command like ``mkdir`` or ``New-Item`` by passing the shell commands
to a shell executable like ``cmd.exe`` or ``PowerShell.exe``.
Here are some examples of using ``win_command`` and ``win_shell``::
Here are some examples of using ``win_command`` and ``win_shell``:
- name: run a command under PowerShell
.. code-block:: yaml+jinja
- name: Run a command under PowerShell
win_shell: Get-Service -Name service | Stop-Service
- name: run a command under cmd
- name: Run a command under cmd
win_shell: mkdir C:\temp
args:
executable: cmd.exe
- name: run a multiple shell commands
- name: Run a multiple shell commands
win_shell: |
New-Item -Path C:\temp -ItemType Directory
Remove-Item -Path C:\temp -Force -Recurse
$path_info = Get-Item -Path C:\temp
$path_info.FullName
- name: run an executable using win_command
- name: Run an executable using win_command
win_command: whoami.exe
- name: run a cmd command
- name: Run a cmd command
win_command: cmd.exe /c mkdir C:\temp
- name: run a vbs script
- name: Run a vbs script
win_command: cscript.exe script.vbs
.. Note:: Some commands like ``mkdir``, ``del``, and ``copy`` only exist in
@ -284,7 +296,9 @@ rules apply:
is used in the argument for every pair, and the double quote is escaped and
made a literal double quote in the argument.
With those rules in mind, here are some examples of quoting::
With those rules in mind, here are some examples of quoting:
.. code-block:: yaml+jinja
- win_command: C:\temp\executable.exe argument1 "argument 2" "C:\path\with space" "double \"quoted\""
@ -300,7 +314,7 @@ With those rules in mind, here are some examples of quoting::
argv[1] = escaped \" backslash
argv[2] = unquoted-end-backslash\
# due to YAML and Ansible parsing '\"' must be written as '{% raw %}\\{% endraw %}"'
# Due to YAML and Ansible parsing '\"' must be written as '{% raw %}\\{% endraw %}"'
- win_command: C:\temp\executable.exe C:\no\space\path "arg with end \ before end quote{% raw %}\\{% endraw %}"
argv[0] = C:\temp\executable.exe
@ -318,24 +332,26 @@ 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::
running:
.. code-block:: yaml+jinja
- name: create scheduled task to run a process
- name: Create scheduled task to run a process
win_scheduled_task:
name: adhoc-task
username: SYSTEM
actions:
- path: PowerShell.exe
arguments: |
Start-Sleep -Seconds 30 # this isn't required, just here as a demonstration
Start-Sleep -Seconds 30 # This isn't required, just here as a demonstration
New-Item -Path C:\temp\test -ItemType Directory
# remove this action if the task shouldn't be deleted on completion
# Remove this action if the task shouldn't be deleted on completion
- path: cmd.exe
arguments: /c schtasks.exe /Delete /TN "adhoc-task" /F
triggers:
- type: registration
- name: wait for the scheduled task to complete
- name: Wait for the scheduled task to complete
win_scheduled_task_stat:
name: adhoc-task
register: task_stat
@ -386,26 +402,28 @@ The YAML specification considers the following `escape sequences <http://yaml.or
* ``\U........`` -- 8-digit hex escape
Here are some examples on how to write Windows paths::
Here are some examples on how to write Windows paths:
GOOD
.. code-block:: yaml+jinja
# GOOD
tempdir: C:\Windows\Temp
WORKS
# WORKS
tempdir: 'C:\Windows\Temp'
tempdir: "C:\\Windows\\Temp"
BAD, BUT SOMETIMES WORKS
# BAD, BUT SOMETIMES WORKS
tempdir: C:\\Windows\\Temp
tempdir: 'C:\\Windows\\Temp'
tempdir: C:/Windows/Temp
FAILS
# FAILS
tempdir: "C:\Windows\Temp"
---
# example of single quotes when they are required
- name: copy tomcat config
# Example of single quotes when they are required
- name: Copy tomcat config
win_copy:
src: log4j.xml
dest: '{{tc_home}}\lib\log4j.xml'
@ -436,22 +454,24 @@ sequences:
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::
Here are some examples of using Windows paths with the key=value style:
.. code-block:: ini
GOOD
# GOOD
tempdir=C:\\Windows\\Temp
WORKS
# WORKS
tempdir='C:\\Windows\\Temp'
tempdir="C:\\Windows\\Temp"
BAD, BUT SOMETIMES WORKS
# BAD, BUT SOMETIMES WORKS
tempdir=C:\Windows\Temp
tempdir='C:\Windows\Temp'
tempdir="C:\Windows\Temp"
tempdir=C:/Windows/Temp
FAILS
# FAILS
tempdir=C:\Windows\temp
tempdir='C:\Windows\temp'
tempdir="C:\Windows\temp"

@ -16,7 +16,9 @@ configuration is required to use WinRM with Ansible.
Ansible uses the `pywinrm <https://github.com/diyan/pywinrm>`_ package to
communicate with Windows servers over WinRM. It is not installed by default
with the Ansible package, but can be installed by running the following::
with the Ansible package, but can be installed by running the following:
.. code-block:: shell
pip install "pywinrm>=0.3.0"
@ -52,7 +54,9 @@ also the most insecure. This is because the username and password are simply
base64 encoded, and if a secure channel is not in use (eg, HTTPS) then it can be
decoded by anyone. Basic authentication can only be used for local accounts (not domain accounts).
The following example shows host vars configured for basic authentication::
The following example shows host vars configured for basic authentication:
.. code-block:: yaml+jinja
ansible_user: LocalUsername
ansible_password: Password
@ -62,6 +66,7 @@ The following example shows host vars configured for basic authentication::
Basic authentication is not enabled by default on a Windows host but can be
enabled by running the following in PowerShell:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true
@ -71,7 +76,9 @@ Certificate
Certificate authentication uses certificates as keys similar to SSH key
pairs, but the file format and key generation process is different.
The following example shows host vars configured for certificate authentication::
The following example shows host vars configured for certificate authentication:
.. code-block:: yaml+jinja
ansible_connection: winrm
ansible_winrm_cert_pem: /path/to/certificate/public/key.pem
@ -81,6 +88,7 @@ The following example shows host vars configured for certificate authentication:
Certificate authentication is not enabled by default on a Windows host but can
be enabled by running the following in PowerShell:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true
@ -111,7 +119,7 @@ To generate a certificate with ``OpenSSL``:
.. code-block:: shell
# set the name of the local user that will have the key mapped to
# Set the name of the local user that will have the key mapped to
USERNAME="username"
cat > openssl.conf << EOL
@ -129,13 +137,13 @@ To generate a certificate with ``OpenSSL``:
To generate a certificate with ``New-SelfSignedCertificate``:
.. code-block:: guess
.. code-block:: powershell
# set the name of the local user that will have the key mapped
# Set the name of the local user that will have the key mapped
$username = "username"
$output_path = "C:\temp"
# instead of generating a file, the cert will be added to the personal
# Instead of generating a file, the cert will be added to the personal
# LocalComputer folder in the certificate store
$cert = New-SelfSignedCertificate -Type Custom `
-Subject "CN=$username" `
@ -144,14 +152,14 @@ To generate a certificate with ``New-SelfSignedCertificate``:
-KeyAlgorithm RSA `
-KeyLength 2048
# export the public key
# Export the public key
$pem_output = @()
$pem_output += "-----BEGIN CERTIFICATE-----"
$pem_output += [System.Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n"
$pem_output += "-----END CERTIFICATE-----"
[System.IO.File]::WriteAllLines("$output_path\cert.pem", $pem_output)
# export the private key in a PFX file
# Export the private key in a PFX file
[System.IO.File]::WriteAllBytes("$output_path\cert.pfx", $cert.Export("Pfx"))
@ -169,7 +177,7 @@ both the issuing certificate and public key are the same.
Following example shows how to import the issuing certificate:
.. code-block:: guess
.. code-block:: powershell
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import("cert.pem")
@ -187,7 +195,7 @@ Following example shows how to import the issuing certificate:
The code to import the client certificate public key is:
.. code-block:: guess
.. code-block:: powershell
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import("cert.pem")
@ -206,13 +214,14 @@ Once the certificate has been imported, it needs to be mapped to the local user
This can be done with the following PowerShell command:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
$username = "username"
$password = ConvertTo-SecureString -String "password" -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
# this is the issuer thumbprint which in the case of a self generated cert
# This is the issuer thumbprint which in the case of a self generated cert
# is the public key thumbprint, additional logic may be required for other
# scenarios
$thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint
@ -247,7 +256,9 @@ Kerberos has several advantages over using NTLM:
the authentication stage.
* Unlike Kerberos, NTLM does not allow credential delegation.
This example shows host variables configured to use NTLM authentication::
This example shows host variables configured to use NTLM authentication:
.. code-block:: yaml+jinja
ansible_user: LocalUsername
ansible_password: Password
@ -264,7 +275,9 @@ is available through WinRM.
Kerberos requires some additional setup work on the Ansible host before it can be
used properly.
The following example shows host vars configured for Kerberos authentication::
The following example shows host vars configured for Kerberos authentication:
.. code-block:: yaml+jinja
ansible_user: username@MY.DOMAIN.COM
ansible_password: Password
@ -328,7 +341,7 @@ that it can communicate with a domain. This configuration is done through the
To configure Kerberos, in the section that starts with:
::
.. code-block:: ini
[realms]
@ -336,7 +349,7 @@ Add the full domain name and the fully qualified domain names of the primary
and secondary Active Directory domain controllers. It should look something
like this:
::
.. code-block:: ini
[realms]
MY.DOMAIN.COM = {
@ -346,13 +359,13 @@ like this:
In the section that starts with:
::
.. code-block:: ini
[domain_realm]
Add a line like the following for each domain that Ansible needs access for:
::
.. code-block:: ini
[domain_realm]
.my.domain.com = MY.DOMAIN.COM
@ -443,7 +456,9 @@ not compromised and are trusted.
CredSSP can be used for both local and domain accounts and also supports
message encryption over HTTP.
To use CredSSP authentication, the host vars are configured like so::
To use CredSSP authentication, the host vars are configured like so:
.. code-block:: yaml+jinja
ansible_user: Username
ansible_password: Password
@ -457,7 +472,7 @@ There are some extra host variables that can be set as shown below::
CredSSP authentication is not enabled by default on a Windows host, but can
be enabled by running the following in PowerShell:
.. code-block:: guess
.. code-block:: powershell
Enable-WSManCredSSP -Role Server -Force
@ -492,7 +507,7 @@ needs to be installed.
Once the update has been applied and the Windows host rebooted, run the following
PowerShell commands to enable TLS 1.2:
.. code-block:: guess
.. code-block:: powershell
$reg_path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2"
New-Item -Path $reg_path
@ -515,13 +530,14 @@ another certificate.
To explicitly set the certificate to use for CredSSP:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
# note the value $certificate_thumbprint will be different in each
# Note the value $certificate_thumbprint will be different in each
# situation, this needs to be set based on the cert that is used.
$certificate_thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C"
# set the thumbprint value
# Set the thumbprint value
Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $certificate_thumbprint
Non-Administrator Accounts
@ -529,7 +545,7 @@ Non-Administrator Accounts
WinRM is configured by default to only allow connections from accounts in the local
``Administrators`` group. This can be changed by running:
.. code-block:: guess
.. code-block:: powershell
winrm configSDDL default
@ -565,6 +581,7 @@ should only be used for development and debugging purposes, as anything sent
from Ansible can viewed by anyone on the network. To disable the encryption
requirement, run the following from PowerShell on the target host:
.. comment: Pygments powershell lexer does not support colons (i.e. URLs)
.. code-block:: guess
Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value $true
@ -580,16 +597,18 @@ username, password, and connection type of the remote hosts. These variables
are most easily set up in the inventory, but can be set on the ``host_vars``/
``group_vars`` level.
When setting up the inventory, the following variables are required::
When setting up the inventory, the following variables are required:
.. code-block:: yaml+jinja
# it is suggested that these be encrypted with ansible-vault:
# It is suggested that these be encrypted with ansible-vault:
# ansible-vault edit group_vars/windows.yml
ansible_connection: winrm
# may also be passed on the command-line via --user
# May also be passed on the command-line via --user
ansible_user: Administrator
# may also be supplied at runtime with --ask-pass
# May also be supplied at runtime with --ask-pass
ansible_password: SecretPasswordGoesHere
@ -649,7 +668,7 @@ for additional configuration of WinRM connections:
* ``ansible_winrm_send_cbt``: When using ``ntlm`` or ``kerberos`` over HTTPS,
the authentication library will try to send channel binding tokens to
mitigate against man in the middle attacks. This flag controls whether these
bindings will be sent or not (default: ``True``).
bindings will be sent or not (default: ``yes``).
* ``ansible_winrm_*``: Any additional keyword arguments supported by
``winrm.Protocol`` may be provided in place of ``*``
@ -676,7 +695,9 @@ using the `ipaddress <https://docs.python.org/3/library/ipaddress.html>`_
package and pass to pywinrm correctly.
When defining a host using an IPv6 address, just add the IPv6 address as you
would an IPv4 address or hostname::
would an IPv4 address or hostname:
.. code-block:: ini
[windows-server]
2001:db8::1

Loading…
Cancel
Save