设置 Windows 主机
本文档讨论了 Ansible 与 Microsoft Windows 主机通信之前所需的设置。
主机要求
为了让 Ansible 与 Windows 主机通信并使用 Windows 模块,Windows 主机必须满足以下基本连接要求
使用 Ansible,您通常可以管理 Microsoft 当前和扩展支持下的 Windows 版本。您还可以管理桌面操作系统,包括 Windows 10 和 11,以及服务器操作系统,包括 Windows Server 2016、2019 和 2022。
您需要在 Windows 主机上安装 PowerShell 5.1 或更高版本,以及至少 .NET 4.0。
您需要创建并激活 WinRM 监听器。更多详细信息,请参阅 WinRM 监听器。
注意
某些 Ansible 模块有额外的要求,例如较新的操作系统或 PowerShell 版本。请查阅模块文档页面以确定主机是否满足这些要求。
升级 PowerShell 和 .NET Framework
Ansible 需要 PowerShell 版本 5.1 和 .NET Framework 4.6 或更高版本才能正常工作。较旧的不受支持的操作系统基础映像不满足这些要求。您可以使用 Upgrade-PowerShell.ps1 脚本来更新这些。
这是如何从 PowerShell 运行此脚本的示例
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Upgrade-PowerShell.ps1"
$file = "$env:temp\Upgrade-PowerShell.ps1"
$username = "Administrator"
$password = "Password"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force
&$file -Version 5.1 -Username $username -Password $password -Verbose
在脚本中,file
值可以是 PowerShell 版本 3.0、4.0 或 5.1。
完成后,您需要运行以下 PowerShell 命令
作为可选但良好的安全实践,您可以将执行策略设置回默认值。
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force
对 Windows 服务器使用 RemoteSigned
值,或对 Windows 客户端使用 Restricted
。
删除自动登录。
$reg_winlogon_path = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
Set-ItemProperty -Path $reg_winlogon_path -Name AutoAdminLogon -Value 0
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultUserName -ErrorAction SilentlyContinue
Remove-ItemProperty -Path $reg_winlogon_path -Name DefaultPassword -ErrorAction SilentlyContinue
该脚本确定您需要安装哪些程序(例如 .NET Framework 4.5.2)以及需要存在哪个 PowerShell 版本。如果需要重新启动并且设置了 username
和 password
参数,则该脚本将自动重新启动计算机然后登录。如果未设置 username
和 password
参数,则该脚本将提示用户在需要时手动重新启动并登录。当用户下次登录时,该脚本将从上次停止的地方继续,并且该过程将继续,直到不再需要任何操作为止。
注意
如果您在 Server 2008 上运行该脚本,则需要安装 SP2。对于 Server 2008 R2 或 Windows 7,您需要 SP1。
在 Windows Server 2008 上,您只能安装 PowerShell 3.0。较新版本会导致脚本失败。
username
和 password
参数以纯文本形式存储在注册表中。脚本完成后,运行清理命令以确保主机上没有存储凭据。
WinRM 内存热修复
在 PowerShell v3.0 上,存在一个限制 WinRM 服务可用内存量的错误。使用 Install-WMF3Hotfix.ps1 脚本在受影响的主机上安装热修复程序,作为系统引导或映像过程的一部分。如果没有此热修复程序,Ansible 将无法在 Windows 主机上执行某些命令。
要安装热修复程序
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$url = "https://raw.githubusercontent.com/jborean93/ansible-windows/master/scripts/Install-WMF3Hotfix.ps1"
$file = "$env:temp\Install-WMF3Hotfix.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file -Verbose
有关更多详细信息,请参阅 “内存不足”错误,在已设置自定义 MaxMemoryPerShellMB 配额并安装了 WMF 3.0 的计算机上 文章。
WinRM 设置
您需要配置 WinRM 服务,以便 Ansible 可以连接到它。WinRM 服务有两个主要组件控制 Ansible 如何与 Windows 主机交互:listener
和 service
配置设置。
注意
用于设置此服务的脚本 可在 GitHub 上下载。原因是使用它可能会给用户带来一些问题。将来很有可能会完全删除它。
WinRM 监听器
WinRM 服务在 一个或多个端口上侦听请求。每个端口都必须创建和配置一个监听器。
要查看在 WinRM 服务上运行的当前监听器
winrm enumerate winrm/config/Listener
这将输出类似以下内容
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
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
Listener
Address = *
Transport = HTTPS
Port = 5986
Hostname = SERVER2016
Enabled = true
URLPrefix = wsman
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::
ffff:ffff:fffe%2, fe80::203d:7d97:c2ed:ec78%3, fe80::e8ea:d765:2c69:7756%7
在上面的示例中,激活了两个监听器。一个在 HTTP 上侦听端口 5985,另一个在 HTTPS 上侦听端口 5986。一些有用的关键选项是
Transport
:监听器是通过 HTTP 还是 HTTPS 运行。我们建议您使用 HTTPS 上的监听器,因为数据在不需要任何进一步更改的情况下进行了加密。Port
:监听器运行的端口。默认情况下,HTTP 为5985
,HTTPS 为5986
。此端口可以根据需要更改,并与主机变量ansible_port
相对应。URLPrefix
:要侦听的 URL 前缀。默认情况下,它是wsman
。如果更改此选项,则需要将主机变量ansible_winrm_path
设置为相同的值。CertificateThumbprint
:如果您使用 HTTPS 监听器,这是 Windows 证书存储中用于连接的证书的指纹。要获取证书本身的详细信息,请在 PowerShell 中使用相关的证书指纹运行此命令
$thumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE"
Get-ChildItem -Path cert:\LocalMachine\My -Recurse | Where-Object { $_.Thumbprint -eq $thumbprint } | Select-Object *
设置 WinRM 监听器
有三种方法可以设置 WinRM 监听器
对 HTTP 使用
winrm quickconfig
,或对 HTTPS 使用winrm quickconfig -transport:https
。当在域环境之外运行时,需要简单的监听器时,这是最容易使用的选项。与其他选项不同,此过程还具有为所需端口打开防火墙并启动 WinRM 服务的额外好处。使用组策略对象 (GPO)。当主机是域的成员时,这是创建监听器的最佳方法,因为配置会自动完成,而无需任何用户输入。有关组策略对象的更多信息,请参阅 组策略对象文档。
使用 PowerShell 创建具有特定配置的监听器。这可以通过运行以下 PowerShell 命令来完成
$selector_set = @{ Address = "*" Transport = "HTTPS" } $value_set = @{ CertificateThumbprint = "E6CDAA82EEAF2ECE8546E05DB7F3E01AA47D76CE" } New-WSManInstance -ResourceURI "winrm/config/Listener" -SelectorSet $selector_set -ValueSet $value_set
要查看此 PowerShell 命令的其他选项,请参阅 New-WSManInstance 文档。
注意
创建 HTTPS 监听器时,必须在 LocalMachine\My
证书存储区中创建并存储证书。
删除 WinRM 监听器
要删除所有 WinRM 监听器
Remove-Item -Path WSMan:\localhost\Listener\* -Recurse -Force
要仅删除通过 HTTPS 运行的那些监听器
Get-ChildItem -Path WSMan:\localhost\Listener | Where-Object { $_.Keys -contains "Transport=HTTPS" } | Remove-Item -Recurse -Force
注意
Keys
对象是一个字符串数组,因此可以包含不同的值。默认情况下,它包含 Transport=
和 Address=
的键,它们对应于 winrm enumerate winrm/config/Listeners
命令中的值。
WinRM 服务选项
您可以控制 WinRM 服务组件的行为,包括身份验证选项和内存设置。
要获取当前服务配置选项的输出,请运行以下命令
winrm get winrm/config/Service
winrm get winrm/config/Winrs
这将输出类似以下内容
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false
Auth
Basic = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = true
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 2147483647
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 2147483647
MaxMemoryPerShellMB = 2147483647
MaxShellsPerUser = 2147483647
您无需更改这些选项中的大多数。但是,需要了解一些重要的选项是
Service\AllowUnencrypted
- 指定 WinRM 是否允许不进行消息加密的 HTTP 流量。只有当ansible_winrm_transport
变量为ntlm
、kerberos
或credssp
时,消息级加密才有可能。默认情况下,此值为false
,您只应在调试 WinRM 消息时将其设置为true
。Service\Auth\*
- 定义您可以与 WinRM 服务一起使用的身份验证选项。默认情况下,启用Negotiate (NTLM)
和Kerberos
。Service\Auth\CbtHardeningLevel
- 指定是否不验证通道绑定令牌(None),验证但不要求(Relaxed),或验证且要求(Strict)。只有在使用 NT LAN Manager (NTLM) 或 Kerberos 通过 HTTPS 连接时才使用 CBT。Service\CertificateThumbprint
- 用于加密 CredSSP 身份验证的 TLS 通道的证书指纹。默认情况下,此值为空。当 WinRM 服务启动时,会生成自签名证书,并在 TLS 进程中使用。Winrs\MaxShellRunTime
- 允许远程命令执行的最大时间(以毫秒为单位)。Winrs\MaxMemoryPerShellMB
- 每个 shell(包括其子进程)分配的最大内存量。
要在 PowerShell 中修改 Service
键下的设置,您需要在 winrm/config/Service
之后提供选项的路径
Set-Item -Path WSMan:\localhost\Service\{path} -Value {some_value}
例如,要更改 Service\Auth\CbtHardeningLevel
Set-Item -Path WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict
要在 PowerShell 中修改 Winrs
键下的设置,您需要在 winrm/config/Winrs
之后提供选项的路径
Set-Item -Path WSMan:\localhost\Shell\{path} -Value {some_value}
例如,要更改 Winrs\MaxShellRunTime
Set-Item -Path WSMan:\localhost\Shell\MaxShellRunTime -Value 2147483647
注意
如果在域环境中运行命令,则其中一些选项由 GPO 设置,并且无法在主机本身上更改。当您使用 GPO 配置键时,它会在值旁边包含文本 [Source="GPO"]
。
常见的 WinRM 问题
WinRM 有大量的配置选项,这使得其配置变得复杂。因此,Ansible 显示的错误实际上可能是主机设置的问题。
要识别主机问题,请从另一台 Windows 主机运行以下命令以连接到目标 Windows 主机。
要测试 HTTP
winrs -r:http://server:5985/wsman -u:Username -p:Password ipconfig
要测试 HTTPS
winrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfig
如果证书不可验证,则该命令将失败。
要测试 HTTPS,忽略证书验证
$username = "Username"
$password = ConvertTo-SecureString -String "Password" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$session_option = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
Invoke-Command -ComputerName server -UseSSL -ScriptBlock { ipconfig } -Credential $cred -SessionOption $session_option
如果上述任何命令失败,则问题可能与 WinRM 设置有关。
HTTP 401/凭据被拒绝
HTTP 401 错误表示初始连接期间身份验证过程失败。您可以检查以下内容以进行故障排除
凭据正确,并在清单中使用
ansible_user
和ansible_password
变量正确设置。该用户是本地 Administrators 组的成员,或者已被明确授予访问权限。您可以使用
winrs
命令执行连接测试以排除此问题。在
Service\Auth\*
下启用了ansible_winrm_transport
变量设置的身份验证选项。如果在 HTTP 而不是 HTTPS 上运行,请使用
ntlm
、kerberos
或credssp
以及ansible_winrm_message_encryption: auto
自定义清单变量以启用消息加密。如果您使用其他身份验证选项,或者无法升级已安装的pywinrm
包,则可以将Service\AllowUnencrypted
设置为true
。仅建议用于故障排除。下游包
pywinrm
、requests-ntlm
、requests-kerberos
和/或requests-credssp
使用pip
更新。对于 Kerberos 身份验证,请确保
Service\Auth\CbtHardeningLevel
未设置为Strict
。对于基本或证书身份验证,请确保该用户是本地帐户。域帐户不适用于基本和证书身份验证。
HTTP 500 错误
HTTP 500 错误表示 WinRM 服务存在问题。您可以检查以下内容以进行故障排除
您当前打开的 shell 数没有超过
WinRsMaxShellsPerUser
。或者,您没有超出任何其他 Winrs 配额。
超时错误
有时 Ansible 无法访问主机。这些实例通常表示网络连接存在问题。您可以检查以下内容以进行故障排除
防火墙未设置为阻止配置的 WinRM 监听器端口。
在主机变量设置的端口和路径上启用了 WinRM 监听器。
winrm
服务正在 Windows 主机上运行,并配置为自动启动。
连接被拒绝错误
当您与主机上的 WinRM 服务通信时,您可能会遇到一些问题。检查以下内容以帮助进行故障排除
WinRM 服务在主机上启动并运行。使用
(Get-Service -Name winrm).Status
命令获取服务状态。主机防火墙允许通过 WinRM 端口传输流量。默认情况下,HTTP 为
5985
,HTTPS 为5986
。
有时,安装程序可能会重新启动 WinRM 或 HTTP 服务,并导致此错误。解决此问题的最佳方法是使用另一台 Windows 主机的 win_psexec
模块。
加载内置模块失败
有时,PowerShell 会失败并显示类似于以下内容的错误消息
The 'Out-String' command was found in the module 'Microsoft.PowerShell.Utility', but the module could not be loaded.
在这种情况下,尝试访问 PSModulePath
环境变量指定的所有路径时可能会出现问题。
此问题的一个常见原因是 PSModulePath
包含指向文件共享的通用命名约定 (UNC) 路径。此外,双跳/凭据委派问题会导致 Ansible 进程无法访问这些文件夹。要解决此问题,请执行以下任一操作
从
PSModulePath
中删除 UNC 路径。
或
使用支持凭据委派的身份验证选项,如
credssp
或kerberos
。您需要启用凭据委派。
有关此问题的更多信息,请参阅 KB4076842。
Windows SSH 设置
Ansible 2.8 为 Windows 管理的节点添加了实验性的 SSH 连接。
警告
使用此功能,风险自负!将 SSH 与 Windows 结合使用是实验性的。此实现可能会在未来的版本中进行向后不兼容的更改。服务器端组件的可靠性可能会因您安装的版本而异。
使用 Windows 设置安装 OpenSSH
您可以使用 OpenSSH 将 Windows 10 客户端连接到 Windows Server 2019。OpenSSH 客户端可在 Windows 10 版本 1809 及更高版本上安装。OpenSSH 服务器可在 Windows Server 2019 及更高版本上安装。
有关更多信息,请参阅开始使用 Windows 版 OpenSSH。
安装 Win32-OpenSSH
要安装用于 Ansible 的 Win32-OpenSSH 服务,请选择以下安装选项之一
按照 Microsoft 提供的安装说明,手动安装
Win32-OpenSSH
。使用 Chocolatey
choco install --package-parameters=/SSHServerFeature openssh
使用
win_chocolatey
Ansible 模块
- name: install the Win32-OpenSSH service
win_chocolatey:
name: openssh
package_params: /SSHServerFeature
state: present
安装一个 Ansible Galaxy 角色,例如 jborean93.win_openssh
ansible-galaxy install jborean93.win_openssh
在您的 playbook 中使用该角色
- name: install Win32-OpenSSH service
hosts: windows
gather_facts: false
roles:
- role: jborean93.win_openssh
opt_openssh_setup_service: True
注意
Win32-OpenSSH
仍处于 Beta 测试阶段,并且不断更新以包含新功能和错误修复。如果您使用 SSH 作为 Windows 的连接选项,我们强烈建议您安装最新版本。
配置 Win32-OpenSSH shell
默认情况下,Win32-OpenSSH
使用 cmd.exe
作为 shell。
要配置不同的 shell,请使用 Ansible playbook,其中包含一个用于定义注册表设置的任务
- name: set the default shell to PowerShell
win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
data: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
type: string
state: present
要将设置恢复为默认 shell
- name: set the default shell to cmd
win_regedit:
path: HKLM:\SOFTWARE\OpenSSH
name: DefaultShell
state: absent
Win32-OpenSSH 身份验证
Windows 的 Win32-OpenSSH 身份验证类似于 Unix/Linux 主机上的 SSH 身份验证。您可以使用纯文本密码或 SSH 公钥身份验证。
对于基于密钥的身份验证
将您的公钥添加到用户配置文件目录的
.ssh
文件夹中的authorized_key
文件中。使用
sshd_config
文件配置 SSH 服务。
当使用 Ansible 的 SSH 密钥身份验证时,远程会话将无法访问用户凭据,并且在尝试访问网络资源时会失败。这也称为双跳或凭据委托问题。要解决此问题
通过设置
ansible_password
变量来使用纯文本密码身份验证。在需要访问远程资源的用户凭据的任务上使用
become
指令。
配置 Ansible 以在 Windows 上使用 SSH
要配置 Ansible 以将 SSH 用于 Windows 主机,您必须设置两个连接变量
将
ansible_connection
设置为ssh
将
ansible_shell_type
设置为cmd
或powershell
ansible_shell_type
变量应反映 Windows 主机上配置的 DefaultShell
。对于默认 shell,请将 ansible_shell_type
设置为 cmd
。或者,如果您将 DefaultShell
更改为 PowerShell,则将 ansible_shell_type
设置为 powershell
。
Windows 上使用 SSH 的已知问题
在 Windows 上使用 SSH 尚处于试验阶段。目前,存在的问题是
当
powershell
是 shell 类型时,旧于v7.9.0.0p1-Beta
的 Win32-OpenSSH 版本无法工作。虽然安全复制协议 (SCP) 应该可以工作,但 SSH 文件传输协议 (SFTP) 是复制或获取文件时推荐使用的机制。
另请参阅
- Ansible playbook
Playbook 简介
- Ansible 提示和技巧
Playbook 的技巧和诀窍
- Windows 模块列表
Windows 特定模块列表,全部使用 PowerShell 实现
- 交流
有疑问?需要帮助?想分享你的想法?请访问 Ansible 交流指南