PowerShell Remoting(PSRemoting)是所有 PowerShell 中最常用的功能之一。为什么呢?因为它非常有用!使用单个命令,您可以无缝连接到一个或数千台远程计算机并执行命令。
在这个终极指南中,您将深入了解 PSRemoting。您将了解到它是什么,它是如何工作的,以及使 PSRemoting 生效的所有各种技术。本指南将不会涵盖如何使用 PSRemoting。您将在整个指南中看到许多我们的操作指南的引用。
PSRemoting 的工作原理
简而言之,PSRemoting 允许您在远程计算机上运行命令,就像您坐在它们面前一样。PSRemoting 提供了一组功能,连接和验证用户,运行远程命令,并将该命令的任何输出返回到本地计算机。
将 PSRemoting 想象成 telnet 或 SSH,甚至是 psexec。这只是在 PowerShell 中运行命令的一种方式。
PSRemoting 在很大程度上依赖于一个称为会话的概念。会话是一个术语,用于描述在其中运行命令的远程 shell。创建这些会话的过程在后台经历了许多步骤。
当您启动 PSRemoting 会话时,以下大致步骤将执行:
- 客户端尝试连接到目标服务器上的 WinRM 监听器(有关 WinRM 监听器的更多信息见下文)。WinRM 监听器是运行在目标服务器上的一个微型 Web 服务。WinRM 是微软对称为 WSMan 的标准的实现。WSMan 是一个开放标准,当时由戴尔、英特尔和 Sun Microsystems 等许多其他大型科技公司共同创建。
- 当客户端通过 HTTP 或 HTTPS 协议连接到监听器时,身份验证过程开始。关于身份验证的每种方法的所有细节将在后面介绍,但现在只需知道客户端需要以某种方式向服务器传递凭据。
- 客户端连接并对服务器进行身份验证后,PSRemoting 将创建一个会话。
- 一旦 PSRemoting 创建了会话,它就准备好开始工作了。此时,客户端可以开始向服务器发送信息,并且服务器会返回任何必要的输出,这称为 序列化。此通信通常是加密的。

WinRM 监听器:可用于连接
A client needs somewhere to connect to when coming in from over the network. The client needs to “talk” to something that’s “listening” on the other side; that “listening” is the role of the WinRM listener.
您可以使用以下 winrm
命令发现运行在任何 Windows 计算机上的所有 WinRm 监听器。

WinRm 监听器有一些重要的组件。它们包括:
- A listening address – The listening address is the IP address that they bind to. This is the IP address that a client connects to.
- 传输类型 – 每个 WinRM 监听器都需要一种与客户端通信的方式;它们通过传输使用 HTTP 或 HTTPS 来实现这一点。
- 可选的证书指纹 – 当 WinRM 监听器使用 HTTPS 进行传输时,它必须知道用于对客户端进行身份验证的私钥;这个密钥是使用证书指纹找到的。
尽可能使用 HTTPS 监听器。设置 HTTPS 传输可以通过确保服务器的有效性并加密身份验证和传输流量来提高安全性。在发放证书时,尽可能使用来自认证机构的受信任证书,而不是自签名证书。
受信任的主机:验证服务器
PSRemoting 通过 WinRM 的身份验证工作原理
如上所述,PSRemoting 所进行的首要步骤之一是身份验证。身份验证是 PSRemoting 最复杂但也是最关键的部分之一。
当 PSRemoting 首次引入时,它只有一种身份验证机制,即 Windows 远程管理 (WinRM),但如今,您还可以使用 SSH 进行身份验证,您稍后会看到。
WinRM 支持两种不同类型的身份验证;用户名和密码或带有各种类型身份验证的证书用于用户名/密码组合。
基本身份验证
从最简单、但也是最不安全的身份验证开始,是基本认证。这种类型的认证是内置到HTTP协议中的标准。基本认证会将用户名和密码的Base64编码副本从客户端以HTTP头的形式发送到监听器。
因为基本认证只是编码了用户名和密码,并没有加密,所以在网络上传送凭证是很容易截获的。
除非你非常有必要,否则不要使用基本认证。WinRM可以使用许多其他更安全的身份验证方法!
凯伯罗斯认证
你的客户端和服务器都在Active Directory环境中吗?如果是的话,那么你已经在许多网络服务中使用了凯伯罗斯认证。
当WinRM客户端尝试连接到使用凯伯罗斯的WinRM监听器时:
- 服务器首先尝试从域控制器为客户端检索会话密钥或票证授予票证。
- 域控制器查找客户端和服务器,如果两者都是有效和受信任的,则发放令牌。
- 然后服务器使用受信任的令牌验证客户端的连接,而不是使用用户名和密码。
在 Kerberos 认证期间,域控制器在票据检索步骤中验证客户端和服务器,阻止了恶意用户冒充服务器。
Kerberos 是一种成熟且安全的认证方法,当客户端和服务器都是 Active Directory 域的成员时,默认的认证类型。但是,它要求客户端和服务器都加入到同一个 Active Directory 林或在林之间建立信任。
协商认证
WinRm 也可以尝试使用 Kerberos,如果不可用,则回退并尝试使用一种称为 NT Lan Manager (NTLM) 的认证协议。
当使用 NTLM 时:
- 服务器向客户端发送一个字符串。
- 然后客户端用用户密码的哈希值对字符串进行加密。
- 加密后的字符串随后发送回服务器,服务器将用户名、原始字符串和加密字符串发送给域控制器。
- 域控制器然后查找该用户的密码哈希值,并对字符串进行相同的加密过程以确保匹配。
NTLM 对于验证客户端是很好的,但与 Kerberos 不同,它不验证服务器。这打开了多种攻击方式的可能性,攻击者可以冒充服务器。
您可以通过使用服务器身份验证证书并将其分配给 HTTPS WinRM 监听器来提高 NTLM 的安全性。在这种设置中,客户端使用 NTLM 对域控制器进行身份验证,而服务器则使用受信任的证书进行身份验证。尽管此设置提供了客户端和服务器身份验证,但 NLTM 协议使用了一个带有过时密钥大小的较旧的加密密码。
因此,只有在将服务器添加到受信任主机列表或使用 HTTPS 监听器时,NLTM 才能使用。
摘要身份验证
在 WinRM 中使用的最不常见的身份验证方法之一是摘要身份验证。NTLM 和 Digest 是相似的身份验证方法。与 NTLM 类似,Digest 生成一个使用用户密码的哈希值加密的唯一字符串。然后,密码就不需要发送到服务器。
摘要使用 MD5 哈希算法来加密密码。由于选择了这个算法,摘要通常被视为过时,不应该被使用。MD5 存在各种已知的漏洞,使其不适合用于加密。
凭据安全支持提供程序 (CredSSP)
虽然我们可以深入讨论CredSSP的细节,但这并非必要。为什么呢?因为在涉及到PSRemoting和WinRM时,通常只会实现CredSSP有一个原因,即“第二次跳转问题”,你将在下面了解到。
当配置为CredSSP身份验证时,WinRM客户端和服务器都使用Negotiate身份验证来验证用户和客户端。但是一旦完成,用户的密码就会发送到服务器。
由于密码是在身份验证过程完成后发送的,所以现在它是加密的。CredSSP还使用TLS会话密钥对密码进行加密,使得加密字符串在会话之间是唯一的。
CredSSP很有帮助,因为在身份验证后,服务器可以代表您连接到其他任何东西。然而,当这种情况发生时,您完全信任您连接的服务器具有用户密码。
基于证书的身份验证
可以说,与PSRemoting一起使用的最安全的身份验证方法是基于证书的身份验证。在这种身份验证方法中,客户端和服务器之间进行了典型的密钥交换,并验证了证书。
WinRM通过在WinRm中映射服务器上的用户来对用户进行身份验证。在身份验证过程中传递的唯一内容是公钥,因此这是一种非常安全的身份验证方式
虽然是最安全的,基于证书的身份验证并不太常见。为什么呢?简单来说,因为设置它需要一些繁琐的工作。您必须:
- 建立一个证书颁发机构
- 创建一个用户身份验证证书
- 共享公钥
- 使用具有适当权限的本地用户帐户(可能是管理员组)
- 设置一个HTTPS监听器
- …以及其他步骤。
即使客户端和服务器都是Active Directory的一部分,也不能使用域用户进行证书身份验证。
Windows操作系统身份验证默认值
既然您已经看到有许多不同的身份验证选项可用,那么您如何知道哪些是开箱即用的呢?在下面的表格中,您将看到两列,指示WinRM客户端是否默认启用,以及该特定身份验证类型是否默认启用。
所有上述身份验证类型都是可配置的,但使用下表将让您对需要自行配置的内容有个好主意。
Method | Client | Service |
Basic | Enabled | Disabled |
Kerberos | Enabled | Enabled |
Negotiate | Enabled | Enabled |
CredSSP | Disabled | Disabled |
Digest | Enabled | Disabled |
Certificate | Enabled | Disabled |
第二跳或双跳问题
PSRemoting的最大问题之一被称为“第二跳问题”或“双跳”。当您通过PSRemoting连接到远程系统,然后需要连接到另一台远程计算机时,就会出现这种情况。
这种情况是有问题的,因为当WinRm客户端对第一个远程计算机进行身份验证时,服务器只验证原始客户端的身份,而不会将密码发送到服务器。当您尝试从第一个连接的服务器连接到第二台计算机时,最终服务器无法验证用户的身份。
您可以通过几种不同的方式解决双跳问题,其中之一是使用CredSSP或Kerberos委派。
使用CredSSP
解决双跳问题的最常见方法是使用CredSSP。CredSSP身份验证通过在第一个远程服务器上存储用户凭据来解决此问题,然后服务器转换的客户端可以将其传递给第二个远程服务器。
但是,使用CredSSP有一个问题。存储在第一个远程服务器上的用户凭据可能是明文存储,因此存在明显的安全问题。在较新的操作系统中,可以使用密码的哈希和Kerberos票证授予票证(TGT)来共同进行身份验证,就像明文密码一样,但这会降低一点风险。
使用 Negotiate,客户端和服务器之间传递信息以验证他们所说的身份,但用户的密码永远不会被访问。由于这个安全特性,第一个服务器在连接到第二个服务器时无法对您进行身份验证。
使用 Kerberos 委托
如前所述,Kerberos 是设置 PSRemoting 的常见方式。作为无处不在的 Active Directory 的一部分,并且默认情况下已设置好,它非常普遍。虽然单独使用 Kerberos 是验证 WinRM 的良好方式,但它无法解决双跳问题。
为了解决双跳场景,您可以使用第二种称为 Kerberos 委托的身份验证类型。虽然有许多种类的 Kerberos 委托,但唯一能够(并且足够安全)作为对 CredSSP 的替代方案的种类称为 Kerberos 有限 委托,更具体地说是基于资源的 Kerberos 有限委托。
基于资源的 Kerberos 有限委托是一种根据域资源(如计算机,在本例中)委托 Kerberos 身份验证令牌的形式,该令牌受限于特定列表的 Kerberos(Active Directory)对象。
为了配置此Kerberos委派,您需要编辑链中第三台计算机的ADComputer对象。例如,如果您要从ClientA远程连接到ServerB再到ServerC,您必须编辑ServerC的ADComputer对象,但您还需要知道ServerB将是什么。在此示例中,可以在PowerShell中运行以下命令:
使用基于资源的Kerberos委派适用于远程连接,如……或……,但在使用PSRemoting时无法正常工作。在使用PSRemoting通过WinRM连接到计算机时,将无法连接到第三台计算机。
设置基于资源的Kerberos受限委派是使用Set-ADComputer
cmdlet的一行PowerShell命令。例如,如果您通过PSRemoting从ServerB连接到ClientA并希望连接到ServerC,可以通过运行以下PowerShell命令实现。
WinRm在15分钟内缓存失败的连接。由于此功能,即使设置了基于资源的Kerberos受限委派,您可能仍无法连接到第三台计算机。为解决此问题,请等待或在第三台计算机上运行命令
klist purge -LI 0x3e7
以清除失败的Kerberos令牌。
有关PSRemoting通过SSH的身份验证原理
尽管WinRM身份验证是PSRemoting的最常见身份验证方法,但从PowerShell v6开始,您有另一种选择;SSH。使用SSH作为身份验证方法使您能够在Linux上使用PSRemoting。
与WinRM不同,SSH需要在客户端和服务器上进行一些额外的配置,例如在Windows客户端上设置SSH客户端和…
使用SSH处理身份验证意味着您受限于SSH支持的身份验证类型。这将主要限制为基于密码和基于公钥的两种主要类型。
SSH支持其他类型的身份验证,但它们通常被认为不如基于密码和基于公钥的选项安全,因此我们将重点介绍这两种。
密码身份验证
使用基于密码的身份验证是设置SSH身份验证与PSRemoting的最简单方法。基于密码的身份验证允许您提供密码来验证身份。
在SSH身份验证过程中,密码在建立SSH连接并在传输过程中进行加密后进行交换。与WinRM使用的某些身份验证方法(如Kerberos)不同,此身份验证方法确实会将整个密码发送到服务器。
你可以把SSH密码身份验证大致比作WinRM身份验证方法Basic使用HTTPS监听器。密码本身并没有以任何有意义的方式受到保护,但整个连接,包括密码在内,都是基于加密的,并且服务器是基于证书进行验证的。
基于证书的身份验证
虽然基于密码的身份验证易于设置和使用,但存在两个问题。
- 首先,没有安全地以无人值守格式进行身份验证的方法。
- 密码身份验证仍会在网络上发送密码。虽然密码在SSH连接内部是加密的,但服务器接收到了完整的密码。如果服务器以某种方式被 compromise,这可能会成为安全问题。
另一方面,基于证书的身份验证不会像密码那样在网络上发送任何敏感数据。相反,服务器有一个公钥副本,客户端有一个私钥副本,并且协商发生在服务器上。
A rough workflow goes as follows:
- 当客户端尝试进行身份验证时,它将公钥的ID或指纹发送到服务器。
- 如果服务器上列出了授权的公钥,它会用公钥加密的字符串进行响应。
- 然后客户端用私钥解密字符串。
- 私钥随后与会话ID进行哈希处理。
- 会话ID被发送回服务器,然后服务器将其与使用原始字符串和会话ID生成的哈希进行比较。
- 如果客户端的会话ID哈希与服务器上的会话ID匹配,则客户端经过验证并被允许连接。
使用公钥加密的任何内容只能使用关联的私钥解密。使用私钥加密的任何内容只能使用公钥解密。会话ID也被引入以提供所谓的完美前向保密(PFS)。
PFS在私钥被泄露时提供安全性,攻击者将无法解密来回传递的所有消息。独特的会话ID意味着用于加密通信的共享密钥在每个会话中都不同。
基于证书的SSH身份验证,如WinRm,确实需要额外的设置工作,例如生成私钥/公钥对并在远程服务器上授权公钥。
连接所需的用户权限
默认情况下,两个本地用户组可以使用PSRemoting远程连接到服务器;管理员和远程管理用户。
虽然您可以将用户帐户添加到远程服务器上的本地管理员组,但应始终提供最少权限。如果用户只需使用PSRemoting连接到远程计算机,则可以将用户帐户添加到远程管理用户组,而不是管理员组。
为了进一步控制PSRemoting访问权限,您还可以使用一个名为Just Enough Administration (JEA)的功能。JEA允许非管理员用户仅以PowerShell的受限语言模式下的管理员身份运行特定命令。
隐式与“显式”远程
如果您以前使用过PSRemoting,您可能熟悉诸如Invoke-Command
、New-PSSession
、Enter-PSSession
等命令。当您运行这些命令时,明显地您正在以某种方式连接到远程计算机。您正在显式使用PSRemoting。
当您运行特定于PSRemoting的命令时,您正在显式运行这些命令,但您知道还有另一种方式吗?您可以通过使用隐式PSRemoting而不是直接调用Invoke-Command
和其他cmdlet来利用PSRemoting。
隐式PSRemoting可能看起来像是在PowerShell会话中本地运行命令,但实际上它们是在远程计算机上运行的。一个很好的例子是使用未安装在您系统上的模块。您可以将命令从PSSession导出,而不是在本地安装它,这样可以让您像本地安装了一样运行它们。
在下面的截图中,您可以看到我没有Test-PendingReboot
命令。然后我连接到了远程计算机并导出了该命令。

接下来,如果导入了该模块,我就可以执行Test-PendingReboot
命令。下面显示了这一点,但您会注意到输出中显示的计算机名称不是PowerShell正在运行的设备的名称,而是导入该命令的设备的名称。
