介绍如何在 PowerShell 中排查远程操作问题。

在使用 PowerShell 远程处理之前,请参阅 about_Remote about_Remote_Requirements ,获取有关配置和基本用法的指南。

必须具有管理权限才能查看或更改驱动器中 WSMan: 本地计算机的设置。 这包括对会话配置、受信任主机、端口或侦听器的更改。

必须使用“ 以管理员身份运行”选项运行 PowerShell。

如何以管理员身份运行

对于错误:

错误:访问被拒绝。 需要从提升的进程运行此 cmdlet。

若要使用“ 以管理员身份运行 ”选项开始Windows PowerShell,请右键单击“开始”菜单中的 PowerShell 图标,然后选择“ 以管理员身份运行 ”。

如何启用远程处理

对于错误:

  • 错误:访问被拒绝
  • 错误:与远程主机的连接被拒绝。 验证WS-Management服务是否在远程主机上运行,并配置为侦听正确的端口和 HTTP URL 上的请求。
  • 若要接收远程命令,必须在计算机上启用 PowerShell 远程处理。 Windows PowerShell远程处理默认在 Windows Server 2012 和更新版本的 Windows Server 上启用。 如果已禁用远程处理,可以运行 Enable-PSRemoting 以重新启用远程处理。 有关详细信息,请参阅 Enable-PSRemoting

    如何在企业中启用远程处理

    对于错误:

  • 错误:访问被拒绝
  • 错误:与远程主机的连接被拒绝。 验证WS-Management服务是否在远程主机上运行,并配置为侦听正确的端口和 HTTP URL 上的请求。
  • 若要使单台计算机能够接收远程 PowerShell 命令并接受连接,请使用 Enable-PSRemoting cmdlet。

    若要为企业中的多台计算机启用远程处理,可以使用以下缩放选项。

  • 启用 “允许自动配置侦听器” 组策略,以配置侦听器进行远程处理。
  • 配置并启用 Windows 防火墙:允许本地端口例外组策略
  • 将 WinRM 服务的启动类型设置为 Automatic ,然后启动该服务。
  • 如何使用组策略启用侦听器

    对于错误:

  • 错误:访问被拒绝
  • 错误:与远程主机的连接被拒绝。 验证WS-Management服务是否在远程主机上运行,并配置为侦听正确的端口和 HTTP URL 上的请求。
  • 启用 “允许自动配置侦听器 ”策略,为域中的所有计算机配置侦听器。

    以下组策略路径中可以找到该策略:

    Computer Configuration\Administrative Templates\Windows Components
        \Windows Remote Management (WinRM)\WinRM service
    

    启用策略并指定 IPv4 和 IPv6 筛选器。 允许使用通配符 (*) 。

    如何在公用网络上启用远程处理

    Enable-PSRemoting 当本地网络为公共网络且命令中未使用 SkipNetworkProfileCheck 参数时,将返回此错误。

    错误:无法检查防火墙的状态

    在服务器版本的 Windows 上, Enable-PSRemoting 在所有网络配置文件上都成功。 它创建防火墙规则,允许远程访问专用和域 (“家庭”和“工作”) 网络。 对于公用网络,它会创建允许从同一本地子网进行远程访问的防火墙规则。

    在客户端版本的 Windows 上, Enable-PSRemoting 在专用和域网络上成功。 默认情况下,它在公用网络上失败,但如果使用 SkipNetworkProfileCheck 参数, Enable-PSRemoting 则会成功并创建允许来自同一本地子网的流量的防火墙规则。

    在 Windows PowerShell 2.0 中,在运行 Windows 服务器版本的计算机上,Enable-PSRemoting创建允许在专用、域和公共网络上进行远程访问的防火墙规则。 在运行客户端版本的 Windows 的计算机上, Enable-PSRemoting 创建仅允许在专用和域网络上进行远程访问的防火墙规则。

    若要删除公用网络上的本地子网限制并允许从任何位置进行远程访问,请运行以下命令:

    Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -RemoteAddress Any
    

    Set-NetFirewallRule该 cmdlet 由 NetSecurity 模块导出。

    对于不同版本的 Windows,防火墙规则的名称可能不同。 使用 Get-NetFirewallRule 查看规则列表。 在启用防火墙规则之前,请查看规则中的安全设置,以验证配置是否适合你的环境。

    如何使用组策略启用防火墙例外

    对于错误:

  • 错误:访问被拒绝
  • 使用 Windows 防火墙:允许本地端口例外 策略为域中的所有计算机启用防火墙例外。

    策略位于以下组策略路径中:

    Computer Configuration\Administrative Templates\Network
        \Network Connections\Windows Firewall\Domain Profile
    

    此策略允许 Administrators 组的成员为 Windows 远程管理 (WinRM) 服务创建防火墙例外。

    如果策略配置不正确,可能会收到以下错误:

    客户端无法连接到请求中指定的目标。 验证目标上的服务是否正在运行并正在接受请求。

    策略中的配置错误导致 ListeningOn 属性的空值。 使用以下命令检查值。

    Get-WSManInstance winrm/config/listener -Enumerate
    
    cfg                   : http://schemas.microsoft.com/wbem/wsman/1/config/listener
    xsi                   : http://www.w3.org/2001/XMLSchema-instance
    Source                : GPO
    lang                  : en-US
    Address               : *
    Transport             : HTTP
    Port                  : 5985
    Hostname              :
    Enabled               : true
    URLPrefix             : wsman
    CertificateThumbprint :
    ListeningOn           : {}
    

    如何设置 WinRM 服务的启动类型

    对于错误:

    错误:访问被拒绝

    PowerShell 远程处理依赖于 Windows 远程管理 (WinRM) 服务。 服务必须正在运行才能支持远程命令。

    在 Windows 的服务器版本中,WinRM 服务启动类型为 Automatic。 但是,在客户端版本的 Windows 上,WinRM 服务默认处于禁用状态。

    使用以下示例将 WinRM 服务的启动类型设置为 Automatic 并启动该服务。 ComputerName 参数接受多个值。

    $invokeCimMethodSplat = @{
        ComputerName = 'Server01', 'Server02'
        Query = 'Select * From Win32_Service Where Name = "WinRM"'
        MethodName = 'ChangeStartMode'
        Arguments = @{StartMode  = 'Automatic'}
    Invoke-CimMethod @invokeCimMethodSplat
    

    如何重新创建默认会话配置

    对于错误:

    错误:访问被拒绝

    使用 Enable-PSRemoting时,它会在本地计算机上创建默认会话配置。 只要远程命令不包含 ConfigurationName 参数,远程用户就使用这些会话配置。

    如果计算机上的默认配置已取消注册或删除,请使用 Enable-PSRemoting cmdlet 重新创建它们。 可以重复使用此 cmdlet。 如果已配置功能,则不会生成错误。

    如果更改默认会话配置并想要还原原始会话配置,可以删除并重新创建配置。

    使用 Unregister-PSSessionConfiguration cmdlet 删除已更改的会话配置。 使用 Enable-PSRemoting 还原原始会话配置。 Enable-PSRemoting 不会更改现有会话配置。

    还原默认会话配置时 Enable-PSRemoting ,它不会为配置创建显式安全描述符。 相反,配置会继承 RootSDDL 的安全描述符,该描述符默认是安全的。

    若要查看 RootSDDL 安全描述符,请键入:

    Get-Item wsman:\localhost\Service\RootSDDL
    

    若要更改 RootSDDL,请使用 Set-Item 驱动器中的 WSMan: cmdlet。 若要更改会话配置的安全描述符,请将 Set-PSSessionConfiguration cmdlet 与 SecurityDescriptorSDDLShowSecurityDescriptorUI 参数一 起使用。

    有关驱动器的详细信息 WSMan: ,请参阅 about_WSMan_Provider

    如何提供管理员凭据

    对于错误:

    错误:访问被拒绝

    必须是连接到默认远程会话终结点的 Administrators 组的成员。 可以使用 、 Enter-PSSessionInvoke-Command cmdlet 的 New-PSSessionCredential 参数,通过备用凭据连接到远程终结点。

    以下示例演示如何为管理员用户提供凭据。

    Invoke-Command -ComputerName Server01 -Credential Domain01\Admin01
    

    有关 Credential 参数的详细信息,请参阅 New-PSSessionEnter-PSSessionInvoke-Command 的帮助。

    如何为非管理用户启用远程处理

    对于错误:

    错误:访问被拒绝

    默认情况下,只有计算机上的 Administrators 组的成员才有权使用默认会话配置。 因此,只有 Administrators 组的成员才能远程连接到计算机。

    若要允许其他用户连接到本地计算机,请授予用户对本地计算机上默认会话配置的 “执行” 权限。

    以下示例将打开一个属性表,使你可以更改本地计算机上默认 Microsoft.PowerShell 会话配置的安全描述符。

    Set-PSSessionConfiguration Microsoft.PowerShell -ShowSecurityDescriptorUI
    

    有关详细信息,请参阅 about_Session_Configurations

    如何为其他域中的管理员启用远程处理

    对于错误:

    错误:访问被拒绝

    当另一个域中的用户是本地计算机上的 Administrators 组的成员时,该用户无法使用管理员权限远程连接到本地计算机。 默认情况下,来自其他域的远程连接仅使用标准用户特权令牌运行。

    可以使用 LocalAccountTokenFilterPolicy 注册表项更改默认行为,并允许属于管理员组成员的远程用户使用管理员权限运行。

    LocalAccountTokenFilterPolicy 条目对所有受影响计算机的所有用户禁用用户帐户控制 (UAC) 远程限制。 在更改策略之前,请仔细考虑此设置的影响。

    使用以下命令将 LocalAccountTokenFilterPolicy 注册表值设置为 1。

    $newItemPropertySplat = @{
      Name = 'LocalAccountTokenFilterPolicy'
      Path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
      PropertyType = 'DWord'
      Value = 1
    New-ItemProperty @newItemPropertySplat
    

    如何在远程命令中使用 IP 地址

    对于错误:

    错误:WinRM 客户端无法处理请求。 如果身份验证方案不同于 Kerberos,或者客户端计算机未加入域,则必须使用 HTTPS 传输,或者必须将目标计算机添加到 TrustedHosts 配置设置。

    Enter-PSSessionInvoke-Command cmdlet 的 New-PSSessionComputerName 参数接受 IP 地址作为有效值。 但是,因为 Kerberos 身份验证不支持 IP 地址。 指定 IP 地址时,将使用 NTLM 身份验证。

    若要支持 NTLM 身份验证,必须满足以下要求:

  • 配置计算机进行 HTTPS 传输,或将远程计算机的 IP 地址添加到本地计算机上的 TrustedHosts 列表。
  • 在所有远程命令中使用 Credential 参数。 即使以当前用户身份进行连接,也需要这样做。
  • 如何从基于工作组的计算机远程连接

    错误:WinRM 客户端无法处理请求。 如果身份验证方案不同于 Kerberos,或者客户端计算机未加入域,则必须使用 HTTPS 传输,或者必须将目标计算机添加到 TrustedHosts 配置设置。

    当本地计算机不在域中时,必须满足以下要求:

  • 配置计算机进行 HTTPS 传输,或将远程计算机的 IP 地址添加到本地计算机上的 TrustedHosts 列表。
  • 验证是否在基于工作组的计算机上设置了密码。 如果未设置密码或密码值为空,则无法运行远程命令。
  • 在所有远程命令中使用 Credential 参数。 即使以当前用户身份进行连接,也需要这样做。
  • 如何将计算机添加到受信任的主机列表

    TrustedHosts 项可以包含以逗号分隔的计算机名称、IP 地址和完全限定域名的列表。 允许使用通配符。

    若要查看或更改受信任的主机列表,请使用 WSMan: 驱动器。 TrustedHost 项位于 节点中WSMan:\localhost\Client。 只有计算机上的 Administrators 组的成员才有权更改计算机上的受信任主机列表。

    TrustedHosts 项设置的值会影响计算机的所有用户。

    若要查看受信任主机的列表,请使用以下命令:

    Get-Item wsman:\localhost\Client\TrustedHosts
    

    以下示例使用通配符 (*) 将所有计算机添加到受信任主机列表中。

    Set-Item wsman:localhost\client\trustedhosts -Value *
    

    还可以使用通配符 (*) 将特定域中的所有计算机添加到受信任的主机列表中。 例如,以下命令将添加 Fabrikam 域中的所有计算机。

    Set-Item wsman:localhost\client\trustedhosts *.fabrikam.com
    

    以下示例将受信任的主机列表设置为单台计算机。

    $server = 'Server01.Domain01.Fabrikam.com'
    Set-Item wsman:\localhost\Client\TrustedHosts -Value $server
    

    若要将计算机名称添加到现有受信任主机列表中,请先将当前值保存在变量中。 然后将该值设置为包含逗号分隔列表(包括当前值和新值)的字符串。

    以下示例将 Server01 添加到受信任的主机的现有列表中。

    $newServer = 'Server01.Domain01.Fabrikam.com'
    $curValue = (Get-Item wsman:\localhost\Client\TrustedHosts).Value
    Set-Item wsman:\localhost\Client\TrustedHosts -Value "$curValue, $newServer"
    

    若要将特定计算机的 IP 地址添加到受信任的主机列表中,请使用以下命令格式:

    Set-Item wsman:\localhost\Client\TrustedHosts -Value <IP Address>
    
    Set-Item wsman:\localhost\Client\TrustedHosts -Value 172.16.0.0
    

    若要将计算机添加到远程计算机的 TrustedHosts 列表,请使用 Connect-WSMan 连接 以 WSMan: 驱动用于 Set-Item 添加计算机的远程计算机。

    有关 的详细信息,请参阅 Connect-WSMan 的帮助。

    如何在备用端口上配置远程处理

    对于错误:

    错误:与指定的远程主机的连接被拒绝。 验证WS-Management服务是否在远程主机上运行,并配置为侦听正确的端口和 HTTP URL 上的请求。

    默认情况下,PowerShell 远程处理使用端口 80 进行 HTTP 传输。 当用户未在远程命令中指定 ConnectionURIPort 参数时,将使用默认端口。

    使用 Set-Item cmdlet 更改侦听器叶节点中的 Port 值。

    例如,以下命令将默认端口更改为 8080。

    Set-Item wsman:\localhost\listener\listener*\port -Value 8080
    

    如何使用代理服务器配置远程处理

    对于错误:

    错误:客户端无法连接到请求中指定的目标。 验证目标上的服务是否正在运行并正在接受请求。

    由于 PowerShell 远程处理使用 HTTP 协议,因此它受 HTTP 代理设置的影响。 在具有代理服务器的企业中,用户无法直接访问 PowerShell 远程计算机。

    若要解决此问题,请在远程命令中使用代理设置选项。

  • 使用 cmdlet 的 ProxyAccessTypeProxyAuthenticationProxyCredential 参数 New-PSSessionOption 创建一个包含 PSSessionOption 对象的变量,该对象具有企业的代理设置。
  • 使用包含 PSSessionOption 对象的变量,并使用 、 Enter-PSSessionInvoke-Command 命令的 New-PSSessionSessionOption 参数。
  • $newPSSessionOptionSplat = @{
        ProxyAccessType = 'IEConfig'
        ProxyAuthentication = 'Negotiate'
        ProxyCredential = 'Domain01\User01'
    $SessionOption = New-PSSessionOption @newPSSessionOptionSplat
    $newPSSessionSplat = @{
        ConnectionUri = 'https://www.fabrikam.com'
        SessionOption = $SessionOption
    New-PSSession @newPSSessionSplat
    

    有关 cmdlet 的详细信息 New-PSSessionOption ,请参阅 New-PSSessionOption

    若要为当前会话中的所有远程命令设置这些选项,请将 $PSSessionOption 首选项变量设置为创建的 PSSessionOption 对象。 有关详细信息,请参阅 about_Preference_Variables

    若要为本地计算机上所有 PowerShell 会话中的所有远程命令设置这些选项,请将首选项变量添加到 $PSSessionOption PowerShell 配置文件。 有关 PowerShell 配置文件的详细信息,请参阅 about_Profiles

    如何在 64 位计算机上检测 32 位会话

    对于错误:

    错误: <术语工具名称> 未识别为 cmdlet、函数、脚本文件或可操作程序的名称。 请检查名称的拼写,如果包含路径,请验证该路径是否正确,并重试。

    如果远程计算机运行的是 64 位版本的 Windows,并且远程命令使用 32 位会话配置(如 Microsoft.PowerShell32),则 WinRM 将加载 WOW64 进程。 Windows 会自动将所有引用 $env:Windir\System32 重定向到 目录 $env:Windir\SysWOW64

    因此,无法找到目录中 System32 没有对应项 SysWow64 的目录中运行的工具。

    若要查找会话中使用的处理器体系结构,请使用 PROCESSOR_ARCHITECTURE 环境变量的值。

    $s = New-PSSession -ComputerName Server01 -ConfigurationName CustomShell
    Invoke-Command -Session $s {$env:PROCESSOR_ARCHITECTURE}
    

    有关详细信息,请参阅 about_Session_Configurations

    排查策略和首选项问题

    本部分讨论与本地和远程计算机上设置的策略和首选项相关的远程处理问题。

    如何更改Import-PSSession和Import-Module的执行策略

    对于错误:

    错误:导入模块:无法加载文件 <文件名> ,因为在此系统上禁用了脚本的执行。

    Import-PSSessionExport-PSSession cmdlet 创建包含未签名脚本文件和格式文件的模块。

    若要导入这些 cmdlet 创建的模块,当前会话中的执行策略不能为 RestrictedAllSigned。 有关详细信息,请参阅 about_Execution_Policies

    若要在不更改本地计算机的执行策略的情况下导入模块,请使用 的 Set-ExecutionPolicyScope 参数为单个进程设置限制较少的执行策略。

    例如,以下示例将当前进程的执行策略设置为 RemoteSigned 。 更改仅影响当前进程。

    Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
    

    还可以使用 的 ExecutionPolicy 参数 PowerShell.exe 启动具有较少限制的执行策略的单个会话。

    pwsh.exe -ExecutionPolicy RemoteSigned
    

    如何设置和更改配额

    可以使用配额来保护本地计算机和远程计算机,避免过度使用资源(意外和恶意)。 当配额与命令冲突时,PowerShell 将生成以下错误。

    错误:从远程客户端接收的总数据超出了允许的最大值。

    WSMan 提供程序具有以下配额设置:

  • 节点中的 WSMan:<ComputerName>MaxEnvelopeSizeKBMaxProviderRequests 设置以及节点中的 MaxConcurrentOperationsMaxConcurrentOperationsPerUserMaxConnections 设置WSMan:<ComputerName>\Service
  • 可以使用 cmdlet 的 MaximumReceivedDataSizePerCommandMaximumReceivedObjectSize 参数 New-PSSessionOption$PSSessionOption 首选项变量来保护本地计算机。
  • 若要保护远程计算机,请使用 cmdlet 的 MaximumReceivedDataSizePerCommandMBMaximumReceivedObjectSizeMB 参数 Register-PSSessionConfiguration 向会话配置添加限制。
  • 若要解决此错误,请更改远程命令以符合配额或增加配额以允许命令完成。

    例如,以下命令将远程计算机上的 Microsoft.PowerShell 会话配置中的对象大小配额从 10 MB (默认值) 增加到 11 MB。

    $setPSSessionConfigurationSplat = @{
        Name = 'Microsoft.PowerShell'
        MaximumReceivedObjectSizeMB = 11
        Force = $true
    Set-PSSessionConfiguration @setPSSessionConfigurationSplat
    

    有关WS-Management配额的详细信息,请参阅 about_WSMan_Provider

    如何解决超时错误

    可以使用超时来保护本地计算机和远程计算机免受过度资源使用(意外和恶意)。 在本地和远程计算机上设置超时时,PowerShell 使用最短的超时设置。

    当超时值不允许操作完成时,PowerShell 将终止该操作并生成以下错误。

    错误:WS-Management服务无法在 OperationTimeout 中指定的时间内完成操作。

    WSMan 提供程序具有以下超时设置。

  • 节点中的 WSMan:<ComputerName>MaxTimeoutMs 设置以及节点中的 WSMan:<ComputerName>\ServiceEnumerationTimeoutMsMaxPacketRetrievalTimeSeconds 设置。
  • 可以使用 cmdlet $PSSessionOption 和首选项变量的 CancelTimeoutIdleTimeoutOpenTimeoutOperationTimeout 参数New-PSSessionOption来保护本地计算机。
  • 还可以通过在会话的会话配置中以编程方式设置超时值来保护远程计算机。
  • 若要解决此错误,请将命令更改为在超时间隔内完成,或增加超时间隔以允许命令完成。

    以下示例在 MS () 中创建 OperationTimeout 值为 4 分钟的会话选项,然后使用会话选项创建远程会话。

    $pso = New-PSSessionOption -OperationTimeout 240000
    New-PSSession -ComputerName Server01 -SessionOption $pso
    

    有关WS-Management超时的详细信息,请参阅 about_WSMan_Provider

    如何中断无响应的命令

    某些本机程序(例如具有用户界面的程序、提示输入的控制台应用程序以及使用 Win32 控制台 API 的控制台应用程序)在 PowerShell 远程主机中无法正常工作。

    使用这些程序时,可能会看到意外行为,例如无输出、部分输出或未完成的远程命令。

    若要结束无响应的程序,请键入 Ctrl+cGet-Error在本地主机和远程会话中使用 查看可能已报告的任何错误。

    如何从操作失败中恢复

    在操作完成之前终止操作时,将返回以下错误。

    错误:由于线程退出或应用程序请求,I/O 操作已中止。

    通常,当 WinRM 服务停止或重启时,其他 WinRM 操作正在进行时,就会发生这种情况。

    若要解决此问题,请验证 WinRM 服务是否正在运行,然后重试该命令。

  • 使用“ 以管理员身份运行” 选项启动 PowerShell。

  • 运行以下命令:

    Start-Service WinRM

  • 重新运行生成错误的命令。

    Linux 和 macOS 限制

    PowerShell 远程处理是使用通过 SSH 进行远程处理的 Linux 和 macOS。 有关详细信息,请参阅 通过 SSH 进行 PowerShell 远程处理

  • about_Remote
  • about_Remote_Requirements
  • about_Remote_Variables
  • Import-Module
  • Export-PSSession
  • Import-PSSession
  •