设置 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
有关更多详细信息,请参阅 “内存不足”错误,该错误发生在安装了 WMF 3.0 的计算机上,并且自定义了 MaxMemoryPerShellMB 配额 文章。
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
在上面的示例中,激活了两个监听器。一个在端口 5985 上通过 HTTP 监听,另一个在端口 5986 上通过 HTTPS 监听。一些需要了解的关键选项是
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 监听器
使用
winrm quickconfig
用于 HTTP,或者winrm quickconfig -transport:https
用于 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
- 指定是否不验证通道绑定令牌(无)、验证但不强制(宽松)或验证并强制(严格)。只有在通过 HTTPS 使用 NT LAN Manager (NTLM) 或 Kerberos 连接时,才会使用 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
变量正确设置。用户是本地管理员组的成员,或者已被明确授予访问权限。您可以使用
winrs
命令执行连接测试,以排除此问题。由
ansible_winrm_transport
变量设置的身份验证选项已在Service\Auth\*
下启用。如果通过 HTTP 而不是 HTTPS 运行,请在
ansible_winrm_message_encryption: auto
自定义清单变量中使用ntlm
、kerberos
或credssp
来启用消息加密。如果您使用其他身份验证选项,或者无法升级已安装的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 侦听器。
Windows 主机上的
winrm
服务正在运行,并配置为自动启动。
连接拒绝错误
当您与主机上的 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 连接。
警告
请自行承担使用此功能的风险!在 Windows 上使用 SSH 是实验性的。此实现可能会在将来的版本中进行向后不兼容的更改。服务器端组件的可靠性取决于您的安装版本。
使用 Windows 设置安装 OpenSSH
您可以使用 OpenSSH 将 Windows 10 客户端连接到 Windows Server 2019。OpenSSH 客户端可在 Windows 10 版本 1809 及更高版本上安装。OpenSSH 服务器可在 Windows Server 2019 及更高版本上安装。
有关更多信息,请参阅 Windows 的 OpenSSH 入门。
安装 Win32-OpenSSH
要为 Ansible 安装 Win32-OpenSSH 服务,请选择以下安装选项之一:
按照微软提供的 安装说明 手动安装
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
在您的剧本中使用该角色
- 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 剧本以定义注册表设置。
- 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 身份验证
Win32-OpenSSH 与 Windows 的身份验证类似于 Unix/Linux 主机上的 SSH 身份验证。您可以使用明文密码或 SSH 公钥身份验证。
对于基于密钥的身份验证
将您的公钥添加到用户配置文件目录的
.ssh
文件夹中的authorized_key
文件中。使用
sshd_config
文件配置 SSH 服务。
当使用 SSH 密钥身份验证与 Ansible 时,远程会话将无法访问用户凭据,并且在尝试访问网络资源时将失败。这也被称为双跳或凭据委派问题。要解决此问题
通过设置
ansible_password
变量使用明文密码身份验证。在需要访问远程资源的用户凭据的任务上使用
become
指令。
为 Windows 上的 SSH 配置 Ansible
要配置 Ansible 以使用 Windows 主机的 SSH,您必须设置两个连接变量
将
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 已知问题
将 SSH 与 Windows 结合使用尚处于实验阶段。目前,存在的问题包括:
当
powershell
是 Shell 类型时,低于v7.9.0.0p1-Beta
的 Win32-OpenSSH 版本无法正常工作。虽然安全复制协议 (SCP) 应该可以正常工作,但 SSH 文件传输协议 (SFTP) 是在复制或获取文件时推荐使用的机制。
另请参阅
- Ansible 剧本
剧本简介
- Ansible 提示和技巧
剧本提示和技巧
- Windows 模块列表
Windows 特定模块列表,全部在 PowerShell 中实现
- 沟通
有问题吗?需要帮助吗?想分享您的想法吗?请访问 Ansible 沟通指南