简介:这份资源是面向 Windows 平台开发者与 IT 管理员的 WMI 英文官方开发文档,适合需要编写 C、C++、Visual Basic 或脚本程序来自动化管理系统、查询硬件与进程信息的工程师,也适合希望深入理解 WMI 体系结构、对象模型与查询语言的技术人员。压缩包内共 1 个 PDF 文件,整体约 57.3MB,内容涵盖 WMI 基本概念、提供程序与存储库的架构关系、类与命名空间参考(如 root\cimv2、Win32_OperatingSystem、Win32_Process)、WQL 查询语法与示例,以及使用 .NET Framework 和 PowerShell 进行开发的指引。文档还包含 C++ 入门示例、远程管理场景说明与组件可用性排查思路,可作为日常开发与运维的案头参考。目前已有 111 人学习,适合作为系统管理自动化方向的英文范文与素材查阅。
1. 从一次远程进程排查说起:这份 WMI 英文开发文档到底能干什么
上周有个做企业运维的读者丢来一段脚本,说在本地跑得好好的,一放到远程机器上就报0x800706BA,问我是不是 WMI 服务挂了。我让他先别急着重启服务,把Get-WmiObject换成Get-CimInstance再试一次,结果直接通了。这个坑其实在 WMI 的英文开发文档里写得清清楚楚——远程连接走 DCOM 还是 WinRM,返回的错误码含义完全不同,只是大多数人从来没翻过原始文档,全靠搜索引擎里的二手答案拼凑。
这份 Windows Management Instrumentation 英文开发文档,就是微软官方那套 WMI 开发资料的完整汇编。它不讲“怎么点鼠标”,而是面向写代码的人:用 C、C++、VB 写应用,或者用带 Windows 脚本引擎的语言去操作 ActiveX 对象。文档覆盖了 WMI 的体系结构、CIM 对象模型、WQL 查询语言、类参考、Provider 编写、远程连接、安全描述符、故障排查等一整套内容。适合谁?适合那些不满足于抄一段 PowerShell 就完事、想搞清楚“为什么这么写”“换台机器为什么就翻车”的开发者与 IT 管理员。它最大的价值不是教你某个命令,而是给你一套能自己推导答案的参照系。
2. WMI 的骨架:CIM 对象模型、命名空间与 Provider 是怎么串起来的
很多人第一次接触 WMI,脑子里是一团浆糊:一会儿说类,一会儿说实例,一会儿又冒出个 Provider。其实把这三层关系理顺,后面写查询、写 Provider 都会顺很多。这一章就把文档里最核心的架构部分拆开讲,顺便说清楚为什么有些类在root\cimv2里能找到,换个命名空间就查不到。
2.1 从 WBEM 到 CIM:WMI 不是凭空造出来的
文档开篇就点明,WMI 是 WBEM(Web-Based Enterprise Management)在 Windows 上的实现,而 WBEM 是一套行业标准,目的是用统一的方式访问企业环境里的管理信息。WMI 用 CIM(Common Information Model)这个行业标准来表示系统、应用、网络、设备等被管理的组件。CIM 由 DMTF 维护,不是微软自己拍脑袋定的。
理解这一点很关键:你查到的每一个 WMI 类,背后都对应 CIM schema 里的一个定义。比如Win32_Process表示进程,Win32_OperatingSystem表示操作系统信息,这些类的属性、方法、关联关系,都是按照 CIM 的建模规则来的。文档里专门有一节讲 CIM,还提到从 Windows 7 开始 WMI 兼容 CIM Schema 2.17.1。这意味着如果你熟悉 CIM 的建模思路,看 WMI 类参考时就不是死记硬背,而是能推断出某个类大概会有哪些属性和关联。
CIM 的一个核心特点是语言无关、面向对象。它用类、实例、属性、方法来描述被管理对象,和 COM 的关系是:WMI 的所有接口都基于 COM,但 CIM 模型本身不绑定具体语言。所以你能用 C++ 调 COM 接口,也能用脚本语言通过 ActiveX 去访问,底层是同一套东西。
2.2 命名空间:为什么你的查询有时候“查不到类”
WMI 的类不是平铺在一个大池子里的,而是按命名空间组织。文档里明确列出,root\cimv2是最常用的命名空间,绝大多数日常管理类都在这里。但如果你要查跟存储相关的东西,可能要去看root\Microsoft\Windows\Storage;查安全相关,可能在root\SecurityCenter2。
我见过太多人写脚本时直接Get-WmiObject Win32_LogicalDisk,在本地没问题,一到远程或者换台机器就报“无效类”。原因往往不是类不存在,而是当前连接的命名空间不对。默认情况下,很多客户端会连到root\cimv2,但如果你显式指定了别的命名空间,或者远程机器的默认命名空间被改过,就会出问题。
文档里关于命名空间的说明散落在多个章节,我一般会这样整理:先确定你要操作的组件属于哪个技术域,再去对应的命名空间下找类。比如电源管理相关的类,文档提到有新的电源计量和预算类,这些类所在的命名空间就和传统的root\cimv2不同。写脚本时养成显式指定命名空间的习惯,能省掉很多“玄学”问题。
2.3 Provider:数据到底是谁提供的
WMI 本身不生产数据,它是个中间层。真正提供数据的是 Provider。文档里说得很直白:很多 Windows 功能都有对应的 WMI Provider,比如 Boot Configuration Data (BCD) Provider、Storage Volume Provider。Provider 实现了 WMI 类所描述的方法和属性,用来管理关联的 Windows 功能。
这就解释了为什么有些类查起来很快,有些类查起来很慢甚至超时。快的类,Provider 可能直接从内存或注册表读数据;慢的类,Provider 可能要去轮询硬件或者做复杂计算。文档里提到,从 Windows Vista 开始,性能计数器数据不再由 ADAP 进程转移到 WMI 性能类里,而是由 WMIPerfClass Provider 创建类、WMIPerfInst Provider 动态提供数据。这种架构变化直接影响你查询性能数据时的行为和延迟。
如果你要写自己的 Provider 来暴露新硬件或应用的数据,文档里有专门的“Providing Data to WMI”章节。不过对大多数做运维和脚本开发的人来说,更常见的是跟现有 Provider 打交道,理解它们的运作方式能帮你判断一个查询为什么慢、为什么失败。
2.4 远程连接:DCOM 与 WinRM 的选型逻辑
文档里有一句话很关键:WMI 的远程连接通过 DCOM 建立,替代方案是用 WinRM,后者基于 WS-Management 的 SOAP 协议来获取远程 WMI 管理数据。这句话背后是一整套选型逻辑。
DCOM 是传统方式,兼容性好,老脚本基本都走这条路。但它对防火墙不友好,需要开一堆动态端口,跨网段、跨域时经常出问题。WinRM 走 HTTP/HTTPS,端口固定,更适合现代网络环境。文档在“New mechanism to connect to remote computers”一节里提到,PowerShell 提供了连接远程 WMI 的简单机制。
我自己的习惯是:新写的脚本一律用Get-CimInstance而不是Get-WmiObject,因为前者默认走 WinRM,后者走 DCOM。如果必须用 DCOM,那就得确保防火墙规则、UAC 设置、DCOM 权限都配对了。文档里关于 UAC 和 WMI 的章节专门讲了 UAC 会影响返回哪些数据、远程访问是否允许、脚本必须以什么方式运行。这些细节不搞清楚,远程查询失败时你连从哪查起都不知道。
3. 上手实操:用 WQL 查询、PowerShell 取数和 C++ 调 COM 接口
理论部分立住了,接下来就是动手。这一章按“查询语言 → 脚本调用 → 原生接口”的顺序推进,每一步都给可复现的代码和参数说明。文档里虽然以英文为主,但代码示例是跨语言的,我挑最实用的几条路径展开。
3.1 WQL 语法:像 SQL 但不是 SQL
WQL 是 WMI 的查询语言,文档里说它“类似于 SQL”,但只支持一部分 SQL 特性。最常用的就是SELECT语句,用来检索类的实例。基本结构是:
SELECT 属性列表 FROM 类名 WHERE 条件比如要查本机所有正在运行的进程名和进程 ID:
SELECT Name, ProcessId FROM Win32_Process如果要加过滤条件,比如只查名为explorer.exe的进程:
SELECT Name, ProcessId FROM Win32_Process WHERE Name = 'explorer.exe'WQL 支持的操作符包括=、<>、>、<、LIKE、IS NULL等。LIKE支持%和_通配符,但注意它和 SQL 的LIKE在大小写敏感性上可能因 Provider 而异。文档里没有专门用一整章讲 WQL 语法,相关内容分散在脚本访问和类参考里,我建议对照Win32_Process、Win32_Service、Win32_OperatingSystem这几个常用类的属性表来练手。
一个容易翻车的地方:WQL 不支持JOIN。如果你要关联两个类的数据,比如查进程和它对应的用户账户,得分别查询然后在脚本里做关联,或者用 WMI 的关联类(Association Class)。文档里在讲 CIM 模型时提到了关联的概念,但具体到 WQL 层面,关联查询是通过特定的关联类来实现的,不是标准 SQL 的 JOIN 写法。
3.2 PowerShell 取数:Get-WmiObject 与 Get-CimInstance 的差别
文档里明确说,很多管理员和 IT 专业人员通过 Windows PowerShell 访问 WMI,Get-WMIcmdlet 可以检索本地或远程 WMI 存储库的信息。但文档写于较早的时期,现在更推荐用Get-CimInstance。
先看传统写法:
# 使用 Get-WmiObject 查询本地操作系统信息 # -Class 指定 WMI 类名,默认命名空间为 root\cimv2 Get-WmiObject -Class Win32_OperatingSystem | Select-Object Caption, Version, OSArchitecture, LastBootUpTime再看 CIM 写法:
# 使用 Get-CimInstance 查询同样的信息 # 默认通过 WinRM 连接,本地查询也走 CIM 会话 Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, OSArchitecture, LastBootUpTime两者返回的数据基本一致,但有几个关键差别。第一,Get-WmiObject返回的是ManagementObject对象,Get-CimInstance返回的是CimInstance对象,后者在 PowerShell 里处理起来更自然,比如LastBootUpTime在 CIM 里直接是DateTime类型,而在 WMI 里是DMTF格式的字符串,需要转换。第二,远程连接方式不同,Get-WmiObject用 DCOM,Get-CimInstance默认用 WinRM。第三,Get-CimInstance支持-CimSession参数,可以复用会话,批量查询时性能更好。
如果要指定命名空间:
# 查询 root\SecurityCenter2 命名空间下的防病毒产品 # -Namespace 参数显式指定命名空间,避免默认命名空间找不到类 Get-CimInstance -Namespace 'root\SecurityCenter2' -ClassName AntiVirusProduct参数说明:-Namespace接受字符串,格式是root\子命名空间;-ClassName是 WMI 类名;-Filter可以用 WQL 的WHERE子句来减少返回数据量,比查出来再Where-Object效率高得多。
3.3 C++ 调 COM:从文档示例到能跑的代码
文档里提到,C++ 开发者可以在“Create a WMI application using C++”找到入门示例。如果你走的是 C++ 路线,核心步骤是初始化 COM、连接到 WMI 命名空间、执行查询、遍历结果集。
下面是一个最小化的 C++ 示例,演示如何查询Win32_OperatingSystem的Caption属性:
#include <windows.h> #include <wbemidl.h> #include <iostream> #include <comdef.h> #pragma comment(lib, "wbemuuid.lib") int main() { // 1. 初始化 COM,使用多线程单元模型 HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hr)) { std::cerr << "COM init failed" << std::endl; return 1; } // 2. 设置进程安全级别,允许访问 WMI hr = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL ); if (FAILED(hr)) { CoUninitialize(); return 1; } // 3. 创建 WMI 定位器,连接到 root\cimv2 命名空间 IWbemLocator* pLoc = NULL; hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); if (FAILED(hr)) { CoUninitialize(); return 1; } IWbemServices* pSvc = NULL; hr = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), // 命名空间 NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hr)) { pLoc->Release(); CoUninitialize(); return 1; } // 4. 设置代理安全级别 hr = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if (FAILED(hr)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; } // 5. 执行 WQL 查询 IEnumWbemClassObject* pEnumerator = NULL; hr = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT Caption FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if (FAILED(hr)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return 1; } // 6. 遍历结果 IWbemClassObject* pclsObj = NULL; ULONG uReturn = 0; while (pEnumerator) { hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if (uReturn == 0) break; VARIANT vtProp; hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0); if (SUCCEEDED(hr)) { std::wcout << L"OS Caption: " << vtProp.bstrVal << std::endl; VariantClear(&vtProp); } pclsObj->Release(); } // 7. 清理资源 pEnumerator->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return 0; }这段代码的逻辑链条是:初始化 COM → 设置安全级别 → 创建定位器 → 连接命名空间 → 设置代理安全 → 执行查询 → 遍历结果 → 释放资源。每一步的 HRESULT 都要检查,WMI 的错误信息往往藏在 HRESULT 里,不检查就只能看到“程序崩溃了”。
参数说明:ConnectServer的第一个参数是命名空间,ROOT\\CIMV2是默认的;ExecQuery的第三个参数控制查询行为,WBEM_FLAG_FORWARD_ONLY表示只向前遍历,WBEM_FLAG_RETURN_IMMEDIATELY表示立即返回,适合大数据量查询。CoSetProxyBlanket的安全级别设置很关键,设错了会报“拒绝访问”,文档里在讲安全的部分有详细说明。
3.4 用 MOF 文件描述自定义类
文档里提到 Managed Object Format (MOF) 是一种格式,让你能写人类可读的代码,操作系统可以把它翻译成一组 CIM 类。如果你要创建自己的 WMI 类来建模新硬件或应用,就得写 MOF 文件。
一个简单的 MOF 示例:
// 定义一个自定义类,继承自 CIM_ManagedElement [dynamic, provider("MyProvider")] class MyCustomDevice : CIM_LogicalDevice { [key] string DeviceID; string DeviceName; uint32 Status; };这个 MOF 定义了一个MyCustomDevice类,有一个键属性DeviceID,还有DeviceName和Status两个属性。[dynamic]限定符表示这个类的实例是动态提供的,provider("MyProvider")指定了提供数据的 Provider 名称。写完之后用mofcomp命令编译进 WMI 存储库:
mofcomp MyCustomDevice.mof编译成功后,就可以用 WQL 查询这个类了。文档里关于 MOF 的说明在“Managed Object Format”一节,但更详细的语法和限定符列表需要参考 DMTF 的 CIM 规范。
4. 避坑与排查:远程连接、权限、命名空间和性能的五个血泪教训
WMI 的坑大多不在语法上,而在环境配置和权限模型上。这一章整理五个我实际踩过或者帮别人排查过的问题,每个都按“现象 → 原因 → 解决”来写。文档里虽然有 Troubleshooting 章节,但英文原文读起来费劲,我把它翻译成实际场景。
4.1 远程查询报 0x800706BA:RPC 服务器不可用
现象:本地Get-WmiObject正常,远程执行时报0x800706BA,提示“RPC 服务器不可用”。
原因:这个错误码通常意味着 DCOM 连接被防火墙拦截,或者目标机器的 RPC 服务没跑起来。WMI 走 DCOM 时会动态分配端口,如果防火墙只开了 135 端口,后续的动态端口通信就会被阻断。
解决:两条路。一是改用 WinRM,用Get-CimInstance替代Get-WmiObject,WinRM 走固定端口 5985/5986,防火墙规则好配。二是如果必须用 DCOM,在目标机器上运行netsh firewall set service remoteadmin enable放行远程管理流量,或者手动配置 DCOM 的端口范围并在防火墙上放行。文档里在讲远程连接和故障排查时提到了这些方向,但没有给出具体的防火墙命令,需要结合 Windows 防火墙文档来操作。
4.2 查询返回空结果但不报错:UAC 和权限在作怪
现象:查询Win32_Service或Win32_Process时,返回的实例数量明显少于预期,或者某些属性为空,但没有任何错误提示。
原因:UAC 会影响 WMI 返回哪些数据。文档里专门有一节“User Account Control and WMI”,说明 UAC 影响返回的 WMI 数据、远程访问以及脚本必须以什么方式运行。如果你不是以管理员身份运行脚本,某些需要高权限的类或属性会返回空值。
解决:以管理员身份运行 PowerShell 或脚本宿主。如果是远程查询,确保使用的账户在目标机器上有足够的 WMI 权限。文档里提到 WMI 使用标准 Windows 安全对象和过程来控制对命名空间、打印机、服务等可保护对象的访问。可以在wmimgmt.msc里检查目标命名空间的安全设置,确保你的账户有“远程启用”和“读取”权限。
4.3 类找不到:命名空间没对上
现象:执行Get-WmiObject -Class Win32_OptionalFeature报“无效类”,但文档里明明有这个类。
原因:Win32_OptionalFeature是在 Windows 7 引入的,而且它所在的命名空间是root\cimv2,但如果目标机器是更早的版本,或者你连到了错误的命名空间,就会找不到。文档在“What's New in Windows 7”里提到这个类用于查询可选功能的状态。
解决:先确认目标操作系统版本是否支持你要用的类。文档里每个类都有 Requirements 部分,说明需要哪个操作系统版本。然后确认命名空间,用Get-CimInstance -Namespace root\cimv2 -ClassName Win32_OptionalFeature显式指定。如果还是找不到,用Get-CimClass -Namespace root\cimv2 -ClassName Win32_*列出所有可用类,看看目标类到底在不在。
4.4 查询性能数据超时:Provider 的动态数据机制
现象:查询Win32_PerfFormattedData_*系列类时,响应极慢,甚至超时。
原因:文档里解释了,从 Windows Vista 开始,性能计数器数据不再由 ADAP 进程预先转移到 WMI 存储库,而是由 WMIPerfClass Provider 创建类、WMIPerfInst Provider 动态提供数据。这意味着每次查询都要实时从性能计数器取数,数据量大时自然慢。
解决:缩小查询范围,用WHERE子句过滤,不要一次性拉全量数据。如果只是要几个关键指标,考虑直接用性能计数器 API 或者Get-Countercmdlet,绕过 WMI 这一层。文档里在“Performance Libraries and WMI”一节说明了这个架构变化,理解之后就能判断什么时候该用 WMI、什么时候该换工具。
4.5 脚本在 32 位和 64 位 PowerShell 下行为不一致
现象:同一个 WMI 查询脚本,在 64 位 PowerShell 里返回正常,在 32 位 PowerShell 里返回的实例数不对,或者某些属性值不同。
原因:WMI Provider 有 32 位和 64 位之分。默认情况下,64 位系统上的 32 位进程会看到 32 位的 Provider,反之亦然。如果你查询的是系统级信息,32 位进程可能看不到全部实例。
解决:明确脚本的运行环境。如果要用 64 位 Provider,确保在 64 位 PowerShell 里执行。文档里在讲 Provider 和操作系统可用性时提到了组件在不同系统上的可用性差异,但没有专门讲 32/64 位的问题,这个坑更多是靠经验积累。我一般的做法是,在脚本开头加一段判断,如果不是 64 位进程就重新启动到 64 位环境。
5. 进阶技巧:用 WMI 事件订阅做实时监控与文档查阅方法
前面讲的都是“拉”数据,也就是主动查询。WMI 还有一个很强的能力是“推”,也就是事件订阅。文档里在讲脚本访问和 Provider 时提到了事件机制,但内容比较分散。这一章把事件订阅的实操方法讲清楚,再顺带说下怎么高效查阅这份英文文档。
5.1 临时事件订阅:监控进程创建
临时事件订阅的生命周期跟订阅者进程绑定,进程退出订阅就失效。下面是一个用 PowerShell 监控进程创建的示例:
# 创建一个 WQL 事件查询,监控 Win32_Process 的实例创建 # __InstanceCreationEvent 是 WMI 的内置事件类 $query = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process'" # 注册临时事件订阅,-Action 指定每次事件触发时执行的脚本块 Register-CimIndicationEvent -Query $query -SourceIdentifier 'ProcessMonitor' -Action { $process = $Event.SourceEventArgs.NewEvent.TargetInstance Write-Host "新进程启动: $($process.Name) (PID: $($process.ProcessId))" } # 运行一段时间后取消订阅 Start-Sleep -Seconds 60 Unregister-Event -SourceIdentifier 'ProcessMonitor'参数说明:WITHIN 2表示轮询间隔为 2 秒,这个值决定了事件检测的实时性,设太小会增加系统负载,设太大可能漏掉短命进程。TargetInstance ISA 'Win32_Process'是 WQL 的ISA操作符,用来判断实例是否属于某个类。Register-CimIndicationEvent是 CIM 风格的事件注册,对应的传统命令是Register-WmiEvent。
5.2 永久事件订阅:写进 WMI 存储库的监控
临时订阅的缺点是进程退出就没了。如果你要做长期监控,比如服务器上某个服务停了就自动记录,需要用永久事件订阅。永久订阅由 WMI 服务本身维护,即使你的脚本退出了,订阅依然有效。
创建永久订阅需要三个组件:事件过滤器(Event Filter)、事件消费者(Event Consumer)、过滤器到消费者的绑定(Binding)。下面用 MOF 文件来定义:
// 事件过滤器:监控服务停止事件 instance of __EventFilter as $Filter { Name = "ServiceStopFilter"; Query = "SELECT * FROM __InstanceModificationEvent WITHIN 5 " "WHERE TargetInstance ISA 'Win32_Service' " "AND TargetInstance.State = 'Stopped'"; QueryLanguage = "WQL"; }; // 事件消费者:写日志到文件 instance of LogFileEventConsumer as $Consumer { Name = "ServiceStopLogger"; Filename = "C:\\Logs\\ServiceStop.log"; Text = "服务停止: %TargetInstance.Name%"; }; // 绑定:把过滤器和消费者关联起来 instance of __FilterToConsumerBinding { Filter = $Filter; Consumer = $Consumer; };把这段 MOF 保存为ServiceStopMonitor.mof,然后用mofcomp ServiceStopMonitor.mof编译。编译成功后,每当有Win32_Service实例的状态变为Stopped,就会往C:\Logs\ServiceStop.log写一条记录。
这里有几个坑要注意。第一,LogFileEventConsumer需要目标目录存在且 WMI 服务账户有写权限,否则事件触发了但写不进去。第二,永久订阅会一直留在 WMI 存储库里,不用了要记得删除,删除方法是编译一个包含#pragma delete instance的 MOF 或者用 PowerShell 的Remove-CimInstance。第三,WITHIN 5的轮询间隔对服务状态监控来说够用,但如果你要监控更短暂的事件,需要调小这个值,同时注意系统负载。
5.3 怎么高效查阅这份英文文档
这份文档是英文的,而且内容量大,直接从头读效率很低。我的习惯是把它当参考手册用,遇到具体问题时按以下路径查:
| 你要解决的问题 | 文档对应章节 | 查阅技巧 |
|---|---|---|
| 某个类有哪些属性 | WMI Reference → WMI Classes | 按类名搜索,看 Properties 和 Methods 表 |
| 查询语法怎么写 | Using WMI → Scripting Access to WMI | 搜 WQL 关键词,对照示例改 |
| 远程连接失败 | WMI Troubleshooting | 先看错误码,再看 UAC 和防火墙相关段落 |
| 写 Provider | Providing Data to WMI | 从 MOF 定义和 COM 接口两部分入手 |
| 安全描述符设置 | Access to WMI Securable Objects | 搜 SDDL 和 NamespaceSecuritySDDL |
另外,文档里每个类都有 Requirements 部分,说明支持的操作系统版本。如果你在旧系统上跑新类,先查这里能省很多时间。文档的“What's New”系列章节按操作系统版本列出了新增功能,做版本兼容性评估时很有用。
5.4 一个我常用的调试习惯
最后说一个我自己的习惯。每次写 WMI 相关脚本,不管多简单,我都会先跑一遍Get-CimClass确认类和命名空间存在,再跑一遍不带过滤条件的查询看返回结构,最后才加WHERE条件和远程连接参数。这个顺序看起来笨,但能避免“查不到就怀疑人生”的情况。从那以后我每次远程调试 WMI 都强制走一遍这个流程,先确认类在、再确认数据能出来、最后才调权限和网络。希望帮到你。
本文还有配套的精品资源,点击获取