连接到远程计算机上的 WMI

WMI 可用于管理和访问远程计算机上的 WMI 数据。 WMI 中的远程连接受Windows防火墙和 DCOM 设置的影响。 用户帐户控制 (UAC) 还可能需要对某些设置进行更改。 但是,设置正确后,对远程系统的调用与本地 WMI 调用非常相似。 但是,可以选择使用不同的凭据、备用身份验证协议和其他安全功能,使其更加复杂。

为远程连接配置计算机

在使用 WMI 访问远程系统之前,可能需要检查一些安全设置,以确认你有权访问。 具体而言:

  • Windows包含许多安全功能,这些功能可能会阻止对远程系统上的脚本的访问。 因此,可能需要在进行 WMI 调用之前修改系统的 Active Directory 和Windows防火墙设置。 有关详细信息,请参阅 设置远程 WMI 连接排查远程 WMI 连接问题

  • 必须为远程连接启用正确的 DCOM 设置才能正常工作。 更改 DCOM 设置可以允许低权限用户访问计算机进行远程连接。 有关详细信息,请参阅 保护远程 WMI 连接

此外,在某些情况下,你可能希望通过固定端口运行 WMI。 为此,还需要更改设置。 有关详细信息,请参阅 设置 WMI 的固定端口

Connecting to a Remote Computer

在核心上,使用 WMI 连接到远程系统包括确保你具有访问系统的适当权限,并且连接已正确配置。 有了这两个元素后,连接本身相对简单。 例如,如果使用默认安全凭据,则可以使用以下代码访问远程系统上的 WMI:

使用 PowerShell 远程连接到 WMI

使用大多数 WMI cmdlet 通用 的 -ComputerName 参数,例如 Get-WmiObject

$strComputer = "Computer_B"
$colSettings = Get-WmiObject Win32_OperatingSystem -ComputerName $strComputer

使用 VBScript 远程连接到 WMI

使用一个名字对象,其中包含对 GetObject 的调用中远程系统的名称。

strComputer = "Computer_B"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

使用 C 远程连接到 WMI#

对于当前版本的 WMI 托管接口 (Microsoft.Management.Infrastructure) ,请使用 CimSession 对象表示与远程主机的连接。

using Microsoft.Management.Infrastructure;
...
string Namespace = @"root\cimv2";
string OSQuery = "SELECT * FROM Win32_OperatingSystem";
CimSession mySession = CimSession.Create("Computer_B");
IEnumerable<CimInstance> queryInstance = mySession.QueryInstances(Namespace, "WQL", OSQuery);

使用 C 远程连接到 WMI#

对于 WMI 托管接口的 v1 版本 (System.Management) ,请使用 ManagementScope 对象表示与远程主机的连接。

using System.Management;
...
ManagementScope scope = new ManagementScope("\\\\Computer_B\\root\\cimv2");
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

示例:从远程计算机 (C++) 获取 WMI 数据

使用 IWbemLocator::ConnectServer 方法在 strNetworkResource 参数中指定远程计算机的名称。

    hres = pLoc->ConnectServer(
        _bstr_t(L"\\\\COMPUTER_B\\root\\cimv2"),
        _bstr_t(useToken?NULL:pszName),    // User name
        _bstr_t(useToken?NULL:pszPwd),     // User password
        NULL,                              // Locale             
        NULL,                              // Security flags
        _bstr_t(useNTLM?NULL:pszAuthority),// Authority        
        NULL,                              // Context object 
        &pSvc                              // IWbemServices proxy
        );

前面的代码示例可以说是可以使用 WMI 执行的最基本的远程连接。 具体而言,这些示例假设如下:

  • 你是远程计算机上的管理员。 由于 用户帐户控制,远程系统上的帐户必须是管理员组中的域帐户。 有关详细信息,请参阅用户帐户控制和 WMI。
  • 当前本地计算机上的密码不为空。 这实质上是Windows安全要求,你必须使用密码登录到系统。
  • 本地计算机和远程计算机位于同一域中。 如果需要跨域边界,则需要提供其他信息或使用略有不同的编程模型。
  • 你正在使用自己的帐户访问远程计算机。 如果尝试访问其他帐户,则需要提供其他凭据。 (请注意,不允许使用不同于当前帐户的凭据在本地访问 WMI。)
  • 这两台计算机都在运行 IPv6。 WMI 支持连接到运行 IPv6 的计算机。 但是,本地计算机和“Computer_B”都必须运行 IPv6。 任一计算机也可能运行 IPv4。 有关详细信息,请参阅 WMI 中的 IPv6 和 IPv4 支持
  • 脚本不需要委托 - 也就是说,不需要通过目标远程计算机访问其他远程计算机。 有关详细信息,请参阅 使用 WMI 委派
  • 你正尝试进行特定调用,而不是创建远程进程。 有关详细信息,请参阅 使用 WMI 远程创建进程

考虑到这些限制,远程 WMI 调用与本地 WMI 调用非常相似- 唯一的区别是必须指定远程系统的名称。 但是,可以选择更改其中的许多功能:使用不同的凭据,或通过第三方计算机路由呼叫,或访问其他域。