windows_setup.rst (ansible-2.14.0) | : | windows_setup.rst (ansible-2.14.1rc1) | ||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
Setting up a Windows Host | Setting up a Windows Host | |||
========================= | ========================= | |||
This document discusses the setup that is required before Ansible can communicat e with a Microsoft Windows host. | This document discusses the setup that is required before Ansible can communicat e with a Microsoft Windows host. | |||
.. contents:: | .. contents:: | |||
:local: | :local: | |||
Host Requirements | Host Requirements | |||
````````````````` | ````````````````` | |||
For Ansible to communicate to a Windows host and use Windows modules, the | For Ansible to communicate to a Windows host and use Windows modules, the | |||
Windows host must meet these requirements: | Windows host must meet these base requirements for connectivity: | |||
* Ansible can generally manage Windows versions under current | * With Ansible you can generally manage Windows versions under the current and e | |||
and extended support from Microsoft. Ansible can manage desktop OSs including | xtended support from Microsoft. You can also manage desktop OSs including Window | |||
Windows 8.1, and 10, and server OSs including Windows Server 2012, 2012 R2, | s 8.1, and 10, and server OSs including Windows Server 2012, 2012 R2, 2016, 2019 | |||
2016, 2019, and 2022. | , and 2022. | |||
* Ansible requires PowerShell 3.0 or newer and at least .NET 4.0 to be | * You need to install PowerShell 3.0 or newer and at least .NET 4.0 on the Windo | |||
installed on the Windows host. | ws host. | |||
* A WinRM listener should be created and activated. More details for this can be | * You need to create and activate a WinRM listener. More details, see `WinRM Set | |||
found below. | up <https://docs.ansible.com/ansible/latest//user_guide/windows_setup.html#winrm | |||
-listener>`_. | ||||
.. Note:: While these are the base requirements for Ansible connectivity, some A | ||||
nsible | .. Note:: Some Ansible modules have additional requirements, such as a newer OS | |||
modules have additional requirements, such as a newer OS or PowerShell | or PowerShell version. Consult the module documentation page to determine whethe | |||
version. Please consult the module's documentation page | r a host meets those requirements. | |||
to determine whether a host meets those requirements. | ||||
Upgrading PowerShell and .NET Framework | Upgrading PowerShell and .NET Framework | |||
--------------------------------------- | --------------------------------------- | |||
Ansible requires PowerShell version 3.0 and .NET Framework 4.0 or newer to funct ion on older operating systems like Server 2008 and Windows 7. The base image do es not meet this | Ansible requires PowerShell version 3.0 and .NET Framework 4.0 or newer to funct ion on older operating systems like Server 2008 and Windows 7. The base image do es not meet this | |||
requirement. You can use the `Upgrade-PowerShell.ps1 <https://github.com/jborean 93/ansible-windows/blob/master/scripts/Upgrade-PowerShell.ps1>`_ script to updat e these. | requirement. You can use the `Upgrade-PowerShell.ps1 <https://github.com/jborean 93/ansible-windows/blob/master/scripts/Upgrade-PowerShell.ps1>`_ script to updat e these. | |||
This is an example of how to run this script from PowerShell: | This is an example of how to run this script from PowerShell: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tl s12 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tl s12 | |||
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/s cripts/Upgrade-PowerShell.ps1" | $url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/s cripts/Upgrade-PowerShell.ps1" | |||
$file = "$env:temp\Upgrade-PowerShell.ps1" | $file = "$env:temp\Upgrade-PowerShell.ps1" | |||
$username = "Administrator" | $username = "Administrator" | |||
$password = "Password" | $password = "Password" | |||
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) | (New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) | |||
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force | Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force | |||
# Version can be 3.0, 4.0 or 5.1 | ||||
&$file -Version 5.1 -Username $username -Password $password -Verbose | &$file -Version 5.1 -Username $username -Password $password -Verbose | |||
Once completed, you will need to remove auto logon | In the script, the ``file`` value can be the PowerShell version 3.0, 4.0, or 5.1 | |||
and set the execution policy back to the default (``Restricted `` for Windows cl | . | |||
ients, or ``RemoteSigned`` for Windows servers). You can | ||||
do this with the following PowerShell commands: | Once completed, you need to run the following PowerShell commands: | |||
1. As an optional but good security practice, you can set the execution policy b | ||||
ack to the default. | ||||
.. code-block:: powershell | .. code-block:: powershell | |||
# This isn't needed but is a good security practice to complete | ||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force | |||
Use the ``RemoteSigned`` value for Windows servers, or ``Restricted`` for Window | ||||
s clients. | ||||
2. Remove the auto logon. | ||||
.. code-block:: powershell | ||||
$reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Win logon" | $reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Win logon" | |||
Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 0 | Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 0 | |||
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -ErrorAct ion SilentlyContinue | Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -ErrorAct ion SilentlyContinue | |||
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -ErrorAct ion SilentlyContinue | Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -ErrorAct ion SilentlyContinue | |||
The script works by checking to see what programs need to be installed | The script determines what programs you need to install (such as .NET Framework | |||
(such as .NET Framework 4.5.2) and what PowerShell version is required. If a reb | 4.5.2) and what PowerShell version needs to be present. If a reboot is needed an | |||
oot | d the ``username`` and ``password`` parameters are set, the script will automati | |||
is required and the ``username`` and ``password`` parameters are set, the | cally reboot the machine and then logon. If the ``username`` and ``password`` pa | |||
script will automatically reboot and logon when it comes back up from the | rameters are not set, the script will prompt the user to manually reboot and log | |||
reboot. The script will continue until no more actions are required and the | on when required. When the user is next logged in, the script will continue wher | |||
PowerShell version matches the target version. If the ``username`` and | e it left off and the process continues until no more | |||
``password`` parameters are not set, the script will prompt the user to | ||||
manually reboot and logon when required. When the user is next logged in, the | ||||
script will continue where it left off and the process continues until no more | ||||
actions are required. | actions are required. | |||
.. Note:: If running on Server 2008, then SP2 must be installed. If running on | .. Note:: If you run the script on Server 2008, then you need to install SP2. Fo | |||
Server 2008 R2 or Windows 7, then SP1 must be installed. | r Server 2008 R2 or Windows 7 you need SP1. | |||
.. Note:: Windows Server 2008 can only install PowerShell 3.0; specifying a | On Windows Server 2008 you can install only PowerShell 3.0. A newer version | |||
newer version will result in the script failing. | will result in the script failure. | |||
.. Note:: The ``username`` and ``password`` parameters are stored in plain text | The ``username`` and ``password`` parameters are stored in plain text in the | |||
in the registry. Make sure the cleanup commands are run after the script fin | registry. Run the cleanup commands after the script finishes to ensure no crede | |||
ishes | ntials are stored on the host. | |||
to ensure no credentials are still stored on the host. | ||||
WinRM Memory Hotfix | WinRM Memory Hotfix | |||
------------------- | ------------------- | |||
When running on PowerShell v3.0, there is a bug with the WinRM service that | On PowerShell v3.0, there is a bug that limits the amount of memory available to | |||
limits the amount of memory available to WinRM. Without this hotfix installed, | the WinRM service. Use the `Install-WMF3Hotfix.ps1 <https://github.com/jborean9 | |||
Ansible will fail to execute certain commands on the Windows host. These | 3/ansible-windows/blob/master/scripts/Install-WMF3Hotfix.ps1>`_ script to instal | |||
hotfixes should be installed as part of the system bootstrapping or | l a hotfix on affected hosts as part of the system bootstrapping or imaging proc | |||
imaging process. The script `Install-WMF3Hotfix.ps1 <https://github.com/jborean9 | ess. Without this hotfix, Ansible fails to execute certain commands on the Windo | |||
3/ansible-windows/blob/master/scripts/Install-WMF3Hotfix.ps1>`_ can be used to i | ws host. | |||
nstall the hotfix on affected hosts. | ||||
The following PowerShell command will install the hotfix: | To install the hotfix: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tl s12 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tl s12 | |||
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/s cripts/Install-WMF3Hotfix.ps1" | $url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/s cripts/Install-WMF3Hotfix.ps1" | |||
$file = "$env:temp\Install-WMF3Hotfix.ps1" | $file = "$env:temp\Install-WMF3Hotfix.ps1" | |||
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) | (New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file) | |||
powershell.exe -ExecutionPolicy ByPass -File $file -Verbose | powershell.exe -ExecutionPolicy ByPass -File $file -Verbose | |||
For more details, please refer to the `Hotfix document <https://support.microsof t.com/en-us/help/2842230/out-of-memory-error-on-a-computer-that-has-a-customized -maxmemorypersh>`_ from Microsoft. | For more details, refer to the `"Out of memory" error on a computer that has a c ustomized MaxMemoryPerShellMB quota set and has WMF 3.0 installed <https://suppo rt.microsoft.com/en-us/help/2842230/out-of-memory-error-on-a-computer-that-has-a -customized-maxmemorypersh>`_ article. | |||
WinRM Setup | WinRM Setup | |||
``````````` | ``````````` | |||
Once Powershell has been upgraded to at least version 3.0, the final step is to | You need to configure the WinRM service so that Ansible can connect to it. There | |||
configure the WinRM service so that Ansible can connect to it. There are two | are two main components of the WinRM service that governs how Ansible can inter | |||
main components of the WinRM service that governs how Ansible can interface with | face with the Windows host: the ``listener`` and the ``service`` configuration s | |||
the Windows host: the ``listener`` and the ``service`` configuration settings. | ettings. | |||
WinRM Listener | WinRM Listener | |||
-------------- | -------------- | |||
The WinRM services listens for requests on one or more ports. Each of these port | The WinRM services listen for requests on one or more ports. Each of these ports | |||
s must have a | must have a listener created and configured. | |||
listener created and configured. | ||||
To view the current listeners that are running on the WinRM service, run the | To view the current listeners that are running on the WinRM service: | |||
following command: | ||||
.. code-block:: powershell | .. code-block:: powershell | |||
winrm enumerate winrm/config/Listener | winrm enumerate winrm/config/Listener | |||
This will output something like: | This will output something like: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
Listener | Listener | |||
skipping to change at line 153 | skipping to change at line 130 | |||
Address = * | Address = * | |||
Transport = HTTPS | Transport = HTTPS | |||
Port = 5986 | Port = 5986 | |||
Hostname = SERVER2016 | Hostname = SERVER2016 | |||
Enabled = true | Enabled = true | |||
URLPrefix = wsman | URLPrefix = wsman | |||
CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE | CertificateThumbprint = E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE | |||
ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0 .2.15%6, fe80::5efe:192.168.56.155%8, fe80:: | ListeningOn = 10.0.2.15, 127.0.0.1, 192.168.56.155, ::1, fe80::5efe:10.0 .2.15%6, fe80::5efe:192.168.56.155%8, fe80:: | |||
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 | ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7 | |||
In the example above there are two listeners activated; one is listening on | In the example above there are two listeners activated. One is listening on port | |||
port 5985 over HTTP and the other is listening on port 5986 over HTTPS. Some of | 5985 over HTTP and the other is listening on port 5986 over HTTPS. Some of the | |||
the key options that are useful to understand are: | key options that are useful to understand are: | |||
* ``Transport``: Whether the listener is run over HTTP or HTTPS, it is | * ``Transport``: Whether the listener is run over HTTP or HTTPS. We recommend yo | |||
recommended to use a listener over HTTPS as the data is encrypted without | u use a listener over HTTPS because the data is encrypted without any further ch | |||
any further changes required. | anges required. | |||
* ``Port``: The port the listener runs on, by default it is ``5985`` for HTTP | * ``Port``: The port the listener runs on. By default it is ``5985`` for HTTP an | |||
and ``5986`` for HTTPS. This port can be changed to whatever is required and | d ``5986`` for HTTPS. This port can be changed to whatever is required and corre | |||
corresponds to the host var ``ansible_port``. | sponds to the host var ``ansible_port``. | |||
* ``URLPrefix``: The URL prefix to listen on, by default it is ``wsman``. If | * ``URLPrefix``: The URL prefix to listen on. By default it is ``wsman``. If you | |||
this is changed, the host var ``ansible_winrm_path`` must be set to the same | change this option, you need to set the host var ``ansible_winrm_path`` to the | |||
value. | same value. | |||
* ``CertificateThumbprint``: If running over an HTTPS listener, this is the | * ``CertificateThumbprint``: If you use an HTTPS listener, this is the thumbprin | |||
thumbprint of the certificate in the Windows Certificate Store that is used | t of the certificate in the Windows Certificate Store that is used in the connec | |||
in the connection. To get the details of the certificate itself, run this | tion. To get the details of the certificate itself, run this command with the re | |||
command with the relevant certificate thumbprint in PowerShell: | levant certificate thumbprint in PowerShell: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
$thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" | $thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" | |||
Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object { $_.Thumb print -eq $thumbprint } | Select-Object * | Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object { $_.Thumb print -eq $thumbprint } | Select-Object * | |||
Setup WinRM Listener | Setup WinRM Listener | |||
++++++++++++++++++++ | ++++++++++++++++++++ | |||
There are three ways to set up a WinRM listener: | There are three ways to set up a WinRM listener: | |||
* Using ``winrm quickconfig`` for HTTP or | * Using ``winrm quickconfig`` for HTTP or ``winrm quickconfig -transport:https`` | |||
``winrm quickconfig -transport:https`` for HTTPS. This is the easiest option | for HTTPS. This is the easiest option to use when running outside of a domain e | |||
to use when running outside of a domain environment and a simple listener is | nvironment and a simple listener is required. Unlike the other options, this pro | |||
required. Unlike the other options, this process also has the added benefit of | cess also has the added benefit of opening up the firewall for the ports require | |||
opening up the Firewall for the ports required and starts the WinRM service. | d and starts the WinRM service. | |||
* Using Group Policy Objects. This is the best way to create a listener when the | * Using Group Policy Objects (GPO). This is the best way to create a listener wh | |||
host is a member of a domain because the configuration is done automatically | en the host is a member of a domain because the configuration is done automatica | |||
without any user input. For more information on group policy objects, see the | lly without any user input. For more information on group policy objects, see th | |||
`Group Policy Objects documentation <https://msdn.microsoft.com/en-us/library/ | e `Group Policy Objects documentation <https://msdn.microsoft.com/en-us/library/ | |||
aa374162(v=vs.85).aspx>`_. | aa374162(v=vs.85).aspx>`_. | |||
* Using PowerShell to create the listener with a specific configuration. This | * Using PowerShell to create a listener with a specific configuration. This can | |||
can be done by running the following PowerShell commands: | be done by running the following PowerShell commands: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
$selector_set = @{ | $selector_set = @{ | |||
Address = "*" | Address = "*" | |||
Transport = "HTTPS" | Transport = "HTTPS" | |||
} | } | |||
$value_set = @{ | $value_set = @{ | |||
CertificateThumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" | CertificateThumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" | |||
} | } | |||
New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selec tor_set -ValueSet $value_set | New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selec tor_set -ValueSet $value_set | |||
To see the other options with this PowerShell cmdlet, see | To see the other options with this PowerShell command, refer to the | |||
`New-WSManInstance <https://docs.microsoft.com/en-us/powershell/module/microso | `New-WSManInstance <https://docs.microsoft.com/en-us/powershell/module/microso | |||
ft.wsman.management/new-wsmaninstance?view=powershell-5.1>`_. | ft.wsman.management/new-wsmaninstance?view=powershell-5.1>`_ documentation. | |||
.. Note:: When creating an HTTPS listener, an existing certificate needs to be | .. Note:: When creating an HTTPS listener, you must create and store a certifica | |||
created and stored in the ``LocalMachine\My`` certificate store. Without a | te in the ``LocalMachine\My`` certificate store. | |||
certificate being present in this store, most commands will fail. | ||||
Delete WinRM Listener | Delete WinRM Listener | |||
+++++++++++++++++++++ | +++++++++++++++++++++ | |||
To remove a WinRM listener: | * To remove all WinRM listeners: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
# Remove all listeners | ||||
Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force | Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force | |||
# Only remove listeners that are run over HTTPS | * To remove only those listeners that run over HTTPS: | |||
.. code-block:: powershell | ||||
Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -cont ains "Transport=HTTPS" } | Remove-Item -Recurse -Force | Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -cont ains "Transport=HTTPS" } | Remove-Item -Recurse -Force | |||
.. Note:: The ``Keys`` object is an array of strings, so it can contain differen | .. Note:: The ``Keys`` object is an array of strings, so it can contain differen | |||
t | t values. By default, it contains a key for ``Transport=`` and ``Address=`` whic | |||
values. By default it contains a key for ``Transport=`` and ``Address=`` | h correspond to the values from the ``winrm enumerate winrm/config/Listeners`` c | |||
which correspond to the values from winrm enumerate winrm/config/Listeners. | ommand. | |||
WinRM Service Options | WinRM Service Options | |||
--------------------- | --------------------- | |||
There are a number of options that can be set to control the behavior of the Win | You can control the behavior of the WinRM service component, including authentic | |||
RM service component, | ation options and memory settings. | |||
including authentication options and memory settings. | ||||
To get an output of the current service configuration options, run the | To get an output of the current service configuration options, run the following | |||
following command: | command: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
winrm get winrm/config/Service | winrm get winrm/config/Service | |||
winrm get winrm/config/Winrs | winrm get winrm/config/Winrs | |||
This will output something like: | This will output something like: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
skipping to change at line 283 | skipping to change at line 237 | |||
Winrs | Winrs | |||
AllowRemoteShellAccess = true | AllowRemoteShellAccess = true | |||
IdleTimeout = 7200000 | IdleTimeout = 7200000 | |||
MaxConcurrentUsers = 2147483647 | MaxConcurrentUsers = 2147483647 | |||
MaxShellRunTime = 2147483647 | MaxShellRunTime = 2147483647 | |||
MaxProcessesPerShell = 2147483647 | MaxProcessesPerShell = 2147483647 | |||
MaxMemoryPerShellMB = 2147483647 | MaxMemoryPerShellMB = 2147483647 | |||
MaxShellsPerUser = 2147483647 | MaxShellsPerUser = 2147483647 | |||
While many of these options should rarely be changed, a few can easily impact | You do not need to change the majority of these options. However, some of the im | |||
the operations over WinRM and are useful to understand. Some of the important | portant ones to know about are: | |||
options are: | ||||
* ``Service\AllowUnencrypted``: This option defines whether WinRM will allow | * ``Service\AllowUnencrypted`` - specifies whether WinRM will allow HTTP traffic | |||
traffic that is run over HTTP without message encryption. Message level | without message encryption. Message level encryption is only possible when the | |||
encryption is only possible when ``ansible_winrm_transport`` is ``ntlm``, | ``ansible_winrm_transport`` variable is ``ntlm``, ``kerberos`` or ``credssp``. B | |||
``kerberos`` or ``credssp``. By default this is ``false`` and should only be | y default, this is ``false`` and you should only set it to ``true`` when debuggi | |||
set to ``true`` when debugging WinRM messages. | ng WinRM messages. | |||
* ``Service\Auth\*``: These flags define what authentication | * ``Service\Auth\*`` - defines what authentication options you can use with the | |||
options are allowed with the WinRM service. By default, ``Negotiate (NTLM)`` | WinRM service. By default, ``Negotiate (NTLM)`` and ``Kerberos`` are enabled. | |||
and ``Kerberos`` are enabled. | ||||
* ``Service\Auth\CbtHardeningLevel``: Specifies whether channel binding tokens a | * ``Service\Auth\CbtHardeningLevel`` - specifies whether channel binding tokens | |||
re | are not verified (None), verified but not required (Relaxed), or verified and re | |||
not verified (None), verified but not required (Relaxed), or verified and | quired (Strict). CBT is only used when connecting with NT LAN Manager (NTLM) or | |||
required (Strict). CBT is only used when connecting with NTLM or Kerberos | Kerberos over HTTPS. | |||
over HTTPS. | ||||
* ``Service\CertificateThumbprint``: This is the thumbprint of the certificate | * ``Service\CertificateThumbprint`` - thumbprint of the certificate for encrypti | |||
used to encrypt the TLS channel used with CredSSP authentication. By default | ng the TLS channel used with CredSSP authentication. By default, this is empty. | |||
this is empty; a self-signed certificate is generated when the WinRM service | A self-signed certificate is generated when the WinRM service starts and is used | |||
starts and is used in the TLS process. | in the TLS process. | |||
* ``Winrs\MaxShellRunTime``: This is the maximum time, in milliseconds, that a | * ``Winrs\MaxShellRunTime`` - maximum time, in milliseconds, that a remote comma | |||
remote command is allowed to execute. | nd is allowed to execute. | |||
* ``Winrs\MaxMemoryPerShellMB``: This is the maximum amount of memory allocated | * ``Winrs\MaxMemoryPerShellMB`` - maximum amount of memory allocated per shell, | |||
per shell, including the shell's child processes. | including its child processes. | |||
To modify a setting under the ``Service`` key in PowerShell: | To modify a setting under the ``Service`` key in PowerShell, you need to provide a path to the option after ``winrm/config/Service``: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
# substitute {path} with the path to the option after winrm/config/Service | Set-Item -Path WSMan:\localhost\Service\{path} -Value {some_value} | |||
Set-Item -Path WSMan:\localhost\Service\{path} -Value "value here" | ||||
For example, to change ``Service\Auth\CbtHardeningLevel``: | ||||
.. code-block:: powershell | ||||
# for example, to change Service\Auth\CbtHardeningLevel run | ||||
Set-Item -Path WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict | Set-Item -Path WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict | |||
To modify a setting under the ``Winrs`` key in PowerShell: | To modify a setting under the ``Winrs`` key in PowerShell, you need to provide a path to the option after ``winrm/config/Winrs``: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
# Substitute {path} with the path to the option after winrm/config/Winrs | Set-Item -Path WSMan:\localhost\Shell\{path} -Value {some_value} | |||
Set-Item -Path WSMan:\localhost\Shell\{path} -Value "value here" | ||||
For example, to change ``Winrs\MaxShellRunTime``: | ||||
.. code-block:: powershell | ||||
# For example, to change Winrs\MaxShellRunTime run | ||||
Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647 | Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647 | |||
.. Note:: If running in a domain environment, some of these options are set by | .. Note:: If you run the command in a domain environment, some of these options | |||
GPO and cannot be changed on the host itself. When a key has been | are set by | |||
configured with GPO, it contains the text ``[Source="GPO"]`` next to the val | GPO and cannot be changed on the host itself. When you configured a key with | |||
ue. | GPO, it contains the text ``[Source="GPO"]`` next to the value. | |||
Common WinRM Issues | Common WinRM Issues | |||
------------------- | ------------------- | |||
Because WinRM has a wide range of configuration options, it can be difficult | WinRM has a wide range of configuration options, which makes its configuration c | |||
to setup and configure. Because of this complexity, issues that are shown by Ans | omplex. As a result, errors that Ansible displays could in fact be problems with | |||
ible | the host setup instead. | |||
could in fact be issues with the host setup instead. | ||||
To identify a host issue, run the following command from another Windows host to | ||||
connect to the target Windows host. | ||||
One easy way to determine whether a problem is a host issue is to | * To test HTTP: | |||
run the following command from another Windows host to connect to the | ||||
target Windows host: | ||||
.. code-block:: powershell | .. code-block:: powershell | |||
# Test out HTTP | ||||
winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig | winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig | |||
# Test out HTTPS (will fail if the cert is not verifiable) | * To test HTTPS: | |||
.. code-block:: powershell | ||||
winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig | winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig | |||
# Test out HTTPS, ignoring certificate verification | The command will fail if the certificate is not verifiable. | |||
* To test HTTPS ignoring certificate verification: | ||||
.. code-block:: powershell | ||||
$username = "Username" | $username = "Username" | |||
$password = ConvertTo-SecureString -String "Password" -AsPlainText -Force | $password = ConvertTo-SecureString -String "Password" -AsPlainText -Force | |||
$cred = New-Object -TypeName System.Management.Automation.PSCredential -Argu mentList $username, $password | $cred = New-Object -TypeName System.Management.Automation.PSCredential -Argu mentList $username, $password | |||
$session_option = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocat ionCheck | $session_option = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocat ionCheck | |||
Invoke-Command -ComputerName server -UseSSL -ScriptBlock { ipconfig } -Crede ntial $cred -SessionOption $session_option | Invoke-Command -ComputerName server -UseSSL -ScriptBlock { ipconfig } -Crede ntial $cred -SessionOption $session_option | |||
If this fails, the issue is probably related to the WinRM setup. If it works, th e issue may not be related to the WinRM setup; please continue reading for more troubleshooting suggestions. | If any of the above commands fail, the issue is probably related to the WinRM se tup. | |||
HTTP 401/Credentials Rejected | HTTP 401/Credentials Rejected | |||
+++++++++++++++++++++++++++++ | +++++++++++++++++++++++++++++ | |||
A HTTP 401 error indicates the authentication process failed during the initial | An HTTP 401 error indicates the authentication process failed during the initial | |||
connection. Some things to check for this are: | connection. You can check the following to troubleshoot: | |||
* The credentials are correct and set properly in your inventory with the ``ansi | ||||
ble_user`` and ``ansible_password`` variables. | ||||
* The user is a member of the local Administrators group, or has been explicitly | ||||
granted access. You can perform a connection test with the ``winrs`` command to | ||||
rule this out. | ||||
* The authentication option set by the ``ansible_winrm_transport`` variable is e | ||||
nabled under ``Service\Auth\*``. | ||||
* Verify that the credentials are correct and set properly in your inventory wit | * If running over HTTP and not HTTPS, use ``ntlm``, ``kerberos`` or ``credssp`` | |||
h | with the ``ansible_winrm_message_encryption: auto`` custom inventory variable to | |||
``ansible_user`` and ``ansible_password`` | enable message encryption. If you use another authentication option, or if it i | |||
s not possible to upgrade the installed ``pywinrm`` package, you can set ``Servi | ||||
ce\AllowUnencrypted`` to ``true``. This is recommended only for troubleshooting. | ||||
* Ensure that the user is a member of the local Administrators group or has been | * The downstream packages ``pywinrm``, ``requests-ntlm``, ``requests-kerberos``, | |||
explicitly | and/or ``requests-credssp`` are up to date using ``pip``. | |||
granted access (a connection test with the ``winrs`` command can be used to | ||||
rule this out). | * For Kerberos authentication, ensure that ``Service\Auth\CbtHardeningLevel`` is | |||
not set to ``Strict``. | ||||
* Make sure that the authentication option set by ``ansible_winrm_transport`` is | ||||
enabled under | * For Basic or Certificate authentication, make sure that the user is a local ac | |||
``Service\Auth\*`` | count. Domain accounts do not work with Basic and Certificate authentication. | |||
* If running over HTTP and not HTTPS, use ``ntlm``, ``kerberos`` or ``credssp`` | ||||
with ``ansible_winrm_message_encryption: auto`` to enable message encryption. | ||||
If using another authentication option or if the installed pywinrm version can | ||||
not be | ||||
upgraded, the ``Service\AllowUnencrypted`` can be set to ``true`` but this is | ||||
only recommended for troubleshooting | ||||
* Ensure the downstream packages ``pywinrm``, ``requests-ntlm``, | ||||
``requests-kerberos``, and/or ``requests-credssp`` are up to date using ``pip` | ||||
`. | ||||
* If using Kerberos authentication, ensure that ``Service\Auth\CbtHardeningLevel | ||||
`` is | ||||
not set to ``Strict``. | ||||
* When using Basic or Certificate authentication, make sure that the user is a l | ||||
ocal account and | ||||
not a domain account. Domain accounts do not work with Basic and Certificate | ||||
authentication. | ||||
HTTP 500 Error | HTTP 500 Error | |||
++++++++++++++ | ++++++++++++++ | |||
These indicate an error has occurred with the WinRM service. Some things | An HTTP 500 error indicates a problem with the WinRM service. You can check the | |||
to check for include: | following to troubleshoot: | |||
* Verify that the number of current open shells has not exceeded either | * The number of your currently open shells has not exceeded either ``WinRsMaxShe | |||
``WinRsMaxShellsPerUser`` or any of the other Winrs quotas haven't been | llsPerUser``. Alternatively, you did not exceed any of the other Winrs quotas. | |||
exceeded. | ||||
Timeout Errors | Timeout Errors | |||
+++++++++++++++ | +++++++++++++++ | |||
These usually indicate an error with the network connection where | Sometimes Ansible is unable to reach the host. These instances usually indicate | |||
Ansible is unable to reach the host. Some things to check for include: | a problem with the network connection. You can check the following to troublesho | |||
ot: | ||||
* Make sure the firewall is not set to block the configured WinRM listener ports | * The firewall is not set to block the configured WinRM listener ports. | |||
* Ensure that a WinRM listener is enabled on the port and path set by the host v | * A WinRM listener is enabled on the port and path set by the host vars. | |||
ars | * The ``winrm`` service is running on the Windows host and is configured for the | |||
* Ensure that the ``winrm`` service is running on the Windows host and configure | automatic start. | |||
d for | ||||
automatic start | ||||
Connection Refused Errors | Connection Refused Errors | |||
+++++++++++++++++++++++++ | +++++++++++++++++++++++++ | |||
These usually indicate an error when trying to communicate with the | When you communicate with the WinRM service on the host you can encounter some p | |||
WinRM service on the host. Some things to check for: | roblems. Check the following to help the troubleshooting: | |||
* The WinRM service is up and running on the host. Use the ``(Get-Service -Name | ||||
winrm).Status`` command to get the status of the service. | ||||
* The host firewall is allowing traffic over the WinRM port. By default this is | ||||
``5985`` for HTTP and ``5986`` for HTTPS. | ||||
* Ensure that the WinRM service is up and running on the host. Use | Sometimes an installer may restart the WinRM or HTTP service and cause this erro | |||
``(Get-Service -Name winrm).Status`` to get the status of the service. | r. The best way to deal with this is to use the ``win_psexec`` module from anoth | |||
* Check that the host firewall is allowing traffic over the WinRM port. By defau | er Windows host. | |||
lt | ||||
this is ``5985`` for HTTP and ``5986`` for HTTPS. | ||||
Sometimes an installer may restart the WinRM or HTTP service and cause this erro | ||||
r. The | ||||
best way to deal with this is to use ``win_psexec`` from another | ||||
Windows host. | ||||
Failure to Load Builtin Modules | Failure to Load Builtin Modules | |||
+++++++++++++++++++++++++++++++ | +++++++++++++++++++++++++++++++ | |||
If powershell fails with an error message similar to ``The 'Out-String' command | Sometimes PowerShell fails with an error message similar to: | |||
was found in the module 'Microsoft.PowerShell.Utility', but the module could not | ||||
be loaded.`` | .. code-block:: powershell | |||
then there could be a problem trying to access all the paths specified by the `` | ||||
PSModulePath`` environment variable. | The 'Out-String' command was found in the module 'Microsoft.PowerShell.Utili | |||
A common cause of this issue is that the ``PSModulePath`` environment variable c | ty', but the module could not be loaded. | |||
ontains a UNC path to a file share and | ||||
because of the double hop/credential delegation issue the Ansible process cannot | ||||
access these folders. The way around | ||||
this problems is to either: | ||||
* Remove the UNC path from the ``PSModulePath`` environment variable, or | In that case, there could be a problem when trying to access all the paths speci | |||
* Use an authentication option that supports credential delegation like ``credss | fied by the ``PSModulePath`` environment variable. | |||
p`` or ``kerberos`` with credential delegation enabled | ||||
A common cause of this issue is that ``PSModulePath`` contains a Universal Namin | ||||
g Convention (UNC) path to a file share. Additionally, the double hop/credential | ||||
delegation issue causes that the Ansible process cannot access these folders. T | ||||
o work around this problem is to either: | ||||
* Remove the UNC path from ``PSModulePath``. | ||||
or | ||||
* Use an authentication option that supports credential delegation like ``credss | ||||
p`` or ``kerberos``. You need to have the credential delegation enabled. | ||||
See `KB4076842 <https://support.microsoft.com/en-us/help/4076842>`_ for more inf ormation on this problem. | See `KB4076842 <https://support.microsoft.com/en-us/help/4076842>`_ for more inf ormation on this problem. | |||
Windows SSH Setup | Windows SSH Setup | |||
````````````````` | ````````````````` | |||
Ansible 2.8 has added an experimental SSH connection for Windows managed nodes. | Ansible 2.8 has added an experimental SSH connection for Windows managed nodes. | |||
.. warning:: | .. warning:: | |||
Use this feature at your own risk! | Use this feature at your own risk! Using SSH with Windows is experimental. T | |||
Using SSH with Windows is experimental, the implementation may make | his implementation may make | |||
backwards incompatible changes in feature releases. The server side | backwards incompatible changes in future releases. The server-side component | |||
components can be unreliable depending on the version that is installed. | s can be unreliable depending on your installed version. | |||
Installing OpenSSH using Windows Settings | Installing OpenSSH using Windows Settings | |||
----------------------------------------- | ----------------------------------------- | |||
OpenSSH can be used to connect Window 10 clients to Windows Server 2019. | You can use OpenSSH to connect Window 10 clients to Windows Server 2019. OpenSSH | |||
OpenSSH Client is available to install on Windows 10 build 1809 and later, while | Client is available to install on Windows 10 build 1809 and later. OpenSSH Serv | |||
OpenSSH Server is available to install on Windows Server 2019 and later. | er is available to install on Windows Server 2019 and later. | |||
Please refer `this guide <https://docs.microsoft.com/en-us/windows-server/admini stration/openssh/openssh_install_firstuse>`_. | For more information, refer to `Get started with OpenSSH for Windows <https://do cs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_fir stuse>`_. | |||
Installing Win32-OpenSSH | Installing Win32-OpenSSH | |||
------------------------ | ------------------------ | |||
The first step to using SSH with Windows is to install the `Win32-OpenSSH <https | To install the `Win32-OpenSSH <https://github.com/PowerShell/Win32-OpenSSH>`_ se | |||
://github.com/PowerShell/Win32-OpenSSH>`_ | rvice for use with | |||
service on the Windows host. Microsoft offers a way to install ``Win32-OpenSSH`` | ||||
through a Windows | ||||
capability but currently the version that is installed through this process is | ||||
too old to work with Ansible. To install ``Win32-OpenSSH`` for use with | ||||
Ansible, select one of these installation options: | Ansible, select one of these installation options: | |||
* Manually install the service, following the `install instructions <https://git | * Manually install ``Win32-OpenSSH``, following the `install instructions <https | |||
hub.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH>`_ | ://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH>`_ from Micros | |||
from Microsoft. | oft. | |||
* Install the `openssh <https://chocolatey.org/packages/openssh>`_ package using Chocolatey: | * Use Chocolatey: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
choco install --package-parameters=/SSHServerFeature openssh | choco install --package-parameters=/SSHServerFeature openssh | |||
* Use ``win_chocolatey`` to install the service | * Use the ``win_chocolatey`` Ansible module: | |||
.. code-block:: yaml | .. code-block:: yaml | |||
- name: install the Win32-OpenSSH service | - name: install the Win32-OpenSSH service | |||
win_chocolatey: | win_chocolatey: | |||
name: openssh | name: openssh | |||
package_params: /SSHServerFeature | package_params: /SSHServerFeature | |||
state: present | state: present | |||
* Use an existing Ansible Galaxy role like `jborean93.win_openssh <https://galax y.ansible.com/jborean93/win_openssh>`_: | * Install an Ansible Galaxy role for example `jborean93.win_openssh <https://gal axy.ansible.com/jborean93/win_openssh>`_: | |||
.. code-block:: powershell | .. code-block:: powershell | |||
# Make sure the role has been downloaded first | ||||
ansible-galaxy install jborean93.win_openssh | ansible-galaxy install jborean93.win_openssh | |||
* Use the role in your playbook: | ||||
.. code-block:: yaml | .. code-block:: yaml | |||
# main.yml | ||||
- name: install Win32-OpenSSH service | - name: install Win32-OpenSSH service | |||
hosts: windows | hosts: windows | |||
gather_facts: false | gather_facts: false | |||
roles: | roles: | |||
- role: jborean93.win_openssh | - role: jborean93.win_openssh | |||
opt_openssh_setup_service: True | opt_openssh_setup_service: True | |||
.. note:: ``Win32-OpenSSH`` is still a beta product and is constantly | .. note:: ``Win32-OpenSSH`` is still a beta product and is constantly being upda | |||
being updated to include new features and bugfixes. If you are using SSH as | ted to include new features and bugfixes. If you use SSH as a connection option | |||
a connection option for Windows, it is highly recommend you install the | for Windows, we highly recommend you install the latest version. | |||
latest release from one of the 3 methods above. | ||||
Configuring the Win32-OpenSSH shell | Configuring the Win32-OpenSSH shell | |||
----------------------------------- | ----------------------------------- | |||
By default ``Win32-OpenSSH`` will use ``cmd.exe`` as a shell. To configure a | By default ``Win32-OpenSSH`` uses ``cmd.exe`` as a shell. | |||
different shell, use an Ansible task to define the registry setting: | ||||
* To configure a different shell, use an Ansible playbook with a task to define | ||||
the registry setting: | ||||
.. code-block:: yaml | .. code-block:: yaml | |||
- name: set the default shell to PowerShell | - name: set the default shell to PowerShell | |||
win_regedit: | win_regedit: | |||
path: HKLM:\SOFTWARE\OpenSSH | path: HKLM:\SOFTWARE\OpenSSH | |||
name: DefaultShell | name: DefaultShell | |||
data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe | |||
type: string | type: string | |||
state: present | state: present | |||
# Or revert the settings back to the default, cmd | * To revert the settings back to the default shell: | |||
.. code-block:: yaml | ||||
- name: set the default shell to cmd | - name: set the default shell to cmd | |||
win_regedit: | win_regedit: | |||
path: HKLM:\SOFTWARE\OpenSSH | path: HKLM:\SOFTWARE\OpenSSH | |||
name: DefaultShell | name: DefaultShell | |||
state: absent | state: absent | |||
Win32-OpenSSH Authentication | Win32-OpenSSH Authentication | |||
---------------------------- | ---------------------------- | |||
Win32-OpenSSH authentication with Windows is similar to SSH | Win32-OpenSSH authentication with Windows is similar to SSH authentication on Un | |||
authentication on Unix/Linux hosts. You can use a plaintext password or | ix/Linux hosts. You can use a plaintext password or SSH public key authenticatio | |||
SSH public key authentication, add public keys to an ``authorized_key`` file | n. | |||
in the ``.ssh`` folder of the user's profile directory, and configure the | ||||
service using the ``sshd_config`` file used by the SSH service as you would on | For the key-based authentication: | |||
a Unix/Linux host. | ||||
* Add your public keys to an ``authorized_key`` file in the ``.ssh`` folder of t | ||||
When using SSH key authentication with Ansible, the remote session won't have ac | he user's profile directory. | |||
cess to the | ||||
user's credentials and will fail when attempting to access a network resource. | * Configure the SSH service using the ``sshd_config`` file. | |||
This is also known as the double-hop or credential delegation issue. There are | ||||
two ways to work around this issue: | When using SSH key authentication with Ansible, the remote session will not have | |||
access to user credentials and will fail when attempting to access a network re | ||||
source. This is also known as the double-hop or credential delegation issue. To | ||||
work around this problem: | ||||
* Use plaintext password auth by setting ``ansible_password`` | * Use plaintext password authentication by setting the ``ansible_password`` vari | |||
* Use ``become`` on the task with the credentials of the user that needs access | able. | |||
to the remote resource | * Use the ``become`` directive on the task with the credentials of the user that | |||
needs access to the remote resource. | ||||
Configuring Ansible for SSH on Windows | Configuring Ansible for SSH on Windows | |||
-------------------------------------- | -------------------------------------- | |||
To configure Ansible to use SSH for Windows hosts, you must set two connection v ariables: | To configure Ansible to use SSH for Windows hosts, you must set two connection v ariables: | |||
* set ``ansible_connection`` to ``ssh`` | * set ``ansible_connection`` to ``ssh`` | |||
* set ``ansible_shell_type`` to ``cmd`` or ``powershell`` | * set ``ansible_shell_type`` to ``cmd`` or ``powershell`` | |||
The ``ansible_shell_type`` variable should reflect the ``DefaultShell`` | The ``ansible_shell_type`` variable should reflect the ``DefaultShell`` configur | |||
configured on the Windows host. Set to ``cmd`` for the default shell or set to | ed on the Windows host. Set ``ansible_shell_type`` to ``cmd`` for the default sh | |||
``powershell`` if the ``DefaultShell`` has been changed to PowerShell. | ell. Alternatively, set ``ansible_shell_type`` to ``powershell`` if you changed | |||
``DefaultShell`` to PowerShell. | ||||
Known issues with SSH on Windows | Known issues with SSH on Windows | |||
-------------------------------- | -------------------------------- | |||
Using SSH with Windows is experimental, and we expect to uncover more issues. | Using SSH with Windows is experimental. Currently existing issues are: | |||
Here are the known ones: | ||||
* Win32-OpenSSH versions older than ``v7.9.0.0p1-Beta`` do not work when ``power | * Win32-OpenSSH versions older than ``v7.9.0.0p1-Beta`` do not work when ``power | |||
shell`` is the shell type | shell`` is the shell type. | |||
* While SCP should work, SFTP is the recommended SSH file transfer mechanism to | * While Secure Copy Protocol (SCP) should work, SSH File Transfer Protocol (SFTP | |||
use when copying or fetching a file | ) is the recommended mechanism to use when copying or fetching a file. | |||
.. seealso:: | .. seealso:: | |||
:ref:`about_playbooks` | :ref:`about_playbooks` | |||
An introduction to playbooks | An introduction to playbooks | |||
:ref:`playbooks_best_practices` | :ref:`playbooks_best_practices` | |||
Tips and tricks for playbooks | Tips and tricks for playbooks | |||
:ref:`List of Windows Modules <windows_modules>` | :ref:`List of Windows Modules <windows_modules>` | |||
Windows specific module list, all implemented in PowerShell | Windows specific module list, all implemented in PowerShell | |||
`User Mailing List <https://groups.google.com/group/ansible-project>`_ | `User Mailing List <https://groups.google.com/group/ansible-project>`_ | |||
End of changes. 77 change blocks. | ||||
281 lines changed or deleted | 288 lines changed or added |