设置 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
有关更多详细信息,请参阅“Out of memory” error on a computer that has a customized MaxMemoryPerShellMB quota set and has WMF 3.0 installed文章。
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 监听器
使用
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
- 指定通道绑定令牌是否未验证(无)、验证但不要求(宽松)或验证并要求(严格)。CBT 仅在使用 NT LAN Manager (NTLM) 或 Kerberos 通过 HTTPS 连接时使用。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
命令执行连接测试以排除此问题。由
ansible_winrm_transport
变量设置的身份验证选项是否在Service\Auth\*
下启用。如果通过 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 侦听器。
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 连接。
警告
请自行承担使用此功能的风险!使用 SSH 连接 Windows 属于实验性功能。此实现可能会在将来的版本中做出向后不兼容的更改。服务器端组件的可靠性可能取决于您安装的版本。
使用 Windows 设置安装 OpenSSH
您可以使用 OpenSSH 将 Windows 10 客户端连接到 Windows Server 2019。Windows 10 1809 版本及更高版本可安装 OpenSSH 客户端。Windows Server 2019 及更高版本可安装 OpenSSH 服务器。
有关详细信息,请参阅 Windows OpenSSH 入门。
安装 Win32-OpenSSH
要安装 Win32-OpenSSH 服务以供 Ansible 使用,请选择以下安装选项之一
按照 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
在您的剧本中使用该角色
- name: install Win32-OpenSSH service
hosts: windows
gather_facts: false
roles:
- role: jborean93.win_openssh
opt_openssh_setup_service: True
注意
Win32-OpenSSH
仍处于测试阶段,并且不断更新以包含新功能和错误修复。如果您使用 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 的已知问题
在 Windows 上使用 SSH 处于实验阶段。当前,存在以下问题
当
powershell
是 shell 类型时,低于v7.9.0.0p1-Beta
版本的 Win32-OpenSSH 无法正常工作。虽然安全复制协议 (SCP) 应该可以正常工作,但建议使用 SSH 文件传输协议 (SFTP) 来复制或获取文件。
另请参阅
- Ansible 剧本
剧本简介
- Ansible 提示和技巧
剧本的技巧和窍门
- Windows 模块列表
Windows 特定模块列表,全部在 PowerShell 中实现
- 用户邮件列表
有问题吗?访问 Google 群组!
- 实时聊天
如何加入 Ansible 聊天频道