设置 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_chocolateyAnsible 模块
- 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 沟通指南