Invoke-Command 和直接查询的区别

Difference between Invoke-Command and query directly

我目前正在编写一个从服务器查询磁盘信息的脚本。我遇到了一个问题,我真的不知道这里发生了什么。愿你能帮助我。

以下代码有效(已替换 ComputerName):

$space1 = Invoke-Command -ComputerName "xxxxxx" -ScriptBlock {
    Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='C:'"
}

此代码运行良好,可能需要大约 2 秒才能执行。 经过一些试验后,我找到了一种查询速度更快的方法。对于所有其他服务器,它工作正常,但对于这台服务器,它根本不起作用。这是代码:

$space1 = Get-WmiObject -ComputerName "xxxxxx" -Class Win32_LogicalDisk -Filter "DeviceID='C:'"

此代码需要大约 40 秒才能完成 运行,然后以以下错误结束:

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT:
0x800706BA)
At line:1 char:10
+ $test1 = Get-WmiObject -ComputerName "xxxxxx" -Class Win32_LogicalD ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

有人可以向我解释为什么它在 Invoke-Command 上工作正常,但当我直接在 Get-WmiObject 上使用 ComputerName 参数时却不行吗?如前所述,对于我所有的其他服务器,它工作正常并且代码速度更快,所以我想一直使用这个代码。

到目前为止我做了什么:

我认为问题可能是:

我认为服务器上禁用了 RPC 协议。有人知道如何检查吗?通过 Google...

还没有找到任何有效的方法

特别之处:

CimInstance 命令有效。他们是否也使用 RPC 协议,还是使用其他协议?没有找到关于那个的任何信息。这是我测试的代码:

Get-CimInstance -ComputerName "ccccc" -ClassName Win32_OperatingSystem

Microsoft 的 WMI troubleshooting guide 将该错误归类为防火墙问题:

Error
0x800706BA–HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)
Firewall issue or server not available.

Possible Issues
The computer really doesn't exist The Windows Firewall is blocking the connection

Solution
Connecting to Vista: netsh advfirewall firewall set rule group="windows management instrumentation (wmi)" new enable=yes. Connecting to downlevel: Allow the "Remote Administration" rule in Windows Firewall.

一方面Get-WmiObject与另一方面Get-CimInstanceInvoke-Command的区别在于前者使用DCOM进行网络通信,而后者使用WinRM。有关 WMI 和 CIM 之间差异的详细信息,请参阅脚本专家博客上的文章 "Should I use CIM or WMI with Windows PowerShell"

另一方面,DCOM protocol is based on RPC and uses port 135/tcp for the RPC endpoint mapper, which then assigns a random port between 1024 and 65535 for the actual RPC connection. WinRM 仅使用两个端口之一:5985 用于 HTTP 连接,5986 用于 HTTPS 连接,因此它对防火墙更加友好,并且已经启用 WinRM/PowerShell 远程处理在防火墙中打开端口。这很可能是 Invoke-CommandGet-CimInstance 有效而 Get-WmiObject 无效的原因。

至于RPC协议被禁用:那是不可能的。 Windows 严重依赖 RPC 进行内部通信。如果你真的禁用了协议 Windows 就会停止工作。