连接到远程计算机上的 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:
-
使用大多数 WMI cmdlet 通用的 -ComputerName 参数,例如 Get-WmiObject。
$strComputer = "Computer_B" $colSettings = Get-WmiObject Win32_OperatingSystem -ComputerName $strComputer
-
在 GetObject 调用中使用包含远程系统名称的名字对象。
strComputer = "Computer_B" Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colSettings = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
-
对于当前版本的 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);
-
对于 v1 版 WMI 托管接口 (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);
-
使用 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 调用非常相似 – 唯一的差别在于,必须指定远程系统的名称。 但是,你可以选择更改其中的许多功能:使用不同的凭据、通过第三方计算机路由调用,或访问不同的域。