简介:这份资源是面向 Windows 平台开发者与 IT 管理员的 WMI 英文官方开发文档,适合需要编写 C、C++、Visual Basic 或脚本程序来自动化管理系统、查询硬件与进程信息的工程师,也适合希望深入理解 WMI 体系结构、对象模型与查询语言的进阶学习者。压缩包内共 1 个 PDF 文件,整体约 57.3MB,内容涵盖 WMI 基本概念、提供程序与存储库的架构关系、类与命名空间参考(如 root\cimv2、Win32_OperatingSystem、Win32_Process)、WQL 查询语法与常见示例,以及 C++ 与 .NET 开发入门指引。文档结构清晰,按 About WMI、Using WMI、WMI Reference 等模块组织,便于按主题检索。目前已有 111 人学习,可作为日常开发与运维排错时的案头参考,帮助读者快速定位类定义、理解查询写法并搭建自动化管理脚本。
1. WMI 英文开发文档:从“查不到”到“查得准”的检索与落地路径
如果你在 Windows 上做过运维自动化、资产采集或者终端管控,大概率绕不开 WMI。但真正让人头疼的往往不是写代码,而是面对一份全英文的 WMI 开发文档时,不知道该从哪个类、哪个命名空间、哪个属性下手。标题里说的“Windows Management Instrumentation (WMI) 的英文开发文档”,本质上不是让你去通读一份手册,而是让你建立一套“按需检索、按类落地”的方法:知道 WMI 的文档结构长什么样,知道一个需求该去哪个命名空间找类,知道怎么用脚本把文档里的类定义变成可执行的查询。这套方法适合三类人:刚接触 Windows 自动化的开发者、需要批量采集主机信息的运维工程师、以及做跨平台管理工具时需要对接 WMI 的客户端开发者。下面按“先立住理论、再动手复现、最后避坑”的顺序拆开讲。
2. 先搞懂 WMI 文档的骨架:命名空间、类与 MOF 定义
2.1 为什么直接搜类名往往搜不到你要的东西
很多人第一次查 WMI 文档,习惯直接搜“怎么获取 CPU 温度”或者“怎么查磁盘序列号”,结果搜出来一堆论坛帖子和过时的脚本片段,官方文档反而排在后面。原因在于 WMI 的英文开发文档不是按“任务”组织的,而是按“命名空间 → 类 → 属性/方法”的层级组织的。你搜的是任务,文档给的是类定义,两者之间差了一层映射。
WMI 的核心命名空间常见的有几个:root\cimv2是绝大多数硬件和操作系统信息的入口,root\default放注册表操作相关的类,root\securitycenter2放杀毒软件和安全中心状态,root\wmi则是一些底层驱动暴露的类。英文文档里每个类都会标注它属于哪个命名空间,比如Win32_Processor属于root\cimv2,StdRegProv属于root\default。如果你在错误的命名空间里查类,就像在图书馆的文学区找微积分教材,不是没有,是你站错架了。
文档里每个类的页面结构其实很固定:类名、继承关系、所属命名空间、属性列表、方法列表、以及一段描述。属性列表里会写清楚数据类型(如uint32、string、datetime)、是否可写、以及单位。比如Win32_Processor的CurrentClockSpeed属性,文档会注明单位是 MHz,类型是uint32。这些细节在写查询和解析结果时非常关键,因为 WMI 返回的很多数值不带单位,你得自己对照文档换算。
2.2 用 MOF 定义反推文档里的类结构
WMI 的类定义最终都落在 MOF(Managed Object Format)文件里。英文开发文档里虽然不直接给你 MOF 源码,但类的属性、方法、限定符(Qualifier)描述和 MOF 是一一对应的。理解 MOF 的结构,能帮你更快读懂文档里的类页面。
一个典型的 MOF 类定义长这样:
// 以 Win32_LogicalDisk 为例的简化 MOF 结构 class Win32_LogicalDisk : CIM_LogicalDisk { string DeviceID; // 盘符,如 "C:" uint32 DriveType; // 驱动器类型,3 表示本地磁盘 string FileSystem; // 文件系统,如 "NTFS" uint64 FreeSpace; // 剩余空间,单位字节 uint64 Size; // 总容量,单位字节 string VolumeName; // 卷标 };这段 MOF 对应的文档页面会告诉你:DeviceID是键属性(Key),DriveType的取值需要查Win32_LogicalDisk的枚举说明,FreeSpace和Size是uint64,在脚本里要用大整数处理。如果你在文档里看到某个属性标注了Key,说明它是这个类的唯一标识,查询时可以用它来精确定位实例。看到Write限定符,说明这个属性可写,能通过Put方法修改。看到Units限定符,说明文档里标注的单位是可信的。
我一般会建议新手先花半小时把root\cimv2下最常用的十几个类在文档里过一遍,不用背,只要知道每个类大概管什么。比如Win32_OperatingSystem管操作系统版本和内存,Win32_ComputerSystem管主机名和域信息,Win32_NetworkAdapterConfiguration管网卡 IP 和 DNS。有了这个地图,后面查具体属性就是按图索骥。
2.3 文档里的“关联类”才是批量查询的关键
单独查一个类只能拿到一张表的数据,但实际需求往往是“把磁盘和分区关联起来”或者“把进程和所属用户关联起来”。WMI 文档里有一类特殊的类叫关联类(Association Class),名字通常以Win32_开头、以To连接两个类名,比如Win32_LogicalDiskToPartition关联磁盘分区和逻辑盘,Win32_ProcessStartup关联进程和启动配置。
关联类的文档页面会列出Antecedent和Dependent两个引用属性,分别指向关联的两端。写查询时用ASSOCIATORS OF语句就能跨类取数据。比如要查每个逻辑盘对应的物理分区:
-- 查询 C: 盘关联的物理分区信息 ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="C:"} WHERE AssocClass = Win32_LogicalDiskToPartition这条语句在文档里对应的是Win32_LogicalDiskToPartition类的说明页。如果你不知道关联类的存在,可能会写两次查询再在代码里做 join,效率低还容易漏数据。英文文档里关联类的入口通常藏在“Related Classes”或者“Associations”链接里,点进去才能看到完整的关联关系图。
3. 把文档里的类变成可执行查询:从 WQL 到脚本落地
3.1 WQL 不是 SQL,这几个差异必须先记住
WMI 查询语言(WQL)看起来像 SQL,但只支持SELECT,不支持JOIN、GROUP BY、UPDATE、DELETE。文档里每个类的“Queries”章节会给出示例 WQL,但不会强调这些限制。新手最容易翻车的地方是拿 SQL 思维写 WQL,比如想按DriveType分组统计磁盘数量,WQL 直接不支持,只能在脚本里取回结果后自己处理。
WQL 支持的操作符包括=、!=、<>、>、<、LIKE、IS NULL、IS NOT NULL,以及AND、OR、NOT。LIKE的通配符是%和_,和 SQL 一致。但要注意,WQL 的字符串比较默认不区分大小写,这点和很多数据库不同。文档里不会专门写这条,但你在查Win32_Service的Name属性时,用'winmgmt'和'WinMgmt'都能查到同一个服务。
另一个差异是 WQL 不支持ORDER BY。如果你需要按某个属性排序,只能在脚本里对结果集排序。文档里的示例查询通常只写SELECT * FROM Win32_XXX,不会提醒你这些限制,所以第一次写复杂查询时最好先用简单条件验证类名和属性名是否正确。
3.2 用 PowerShell 跑通第一个 WMI 查询
PowerShell 是验证 WMI 文档最顺手的工具,因为Get-CimInstance直接返回对象,属性名和文档里的类定义一一对应。下面这段脚本查本机所有本地磁盘的容量和剩余空间:
# 查询 root\cimv2 下的 Win32_LogicalDisk 类 # DriveType=3 表示本地固定磁盘,排除网络盘和光驱 $disks = Get-CimInstance -Namespace "root\cimv2" -ClassName Win32_LogicalDisk -Filter "DriveType=3" foreach ($disk in $disks) { # 文档中 FreeSpace 和 Size 单位是字节,这里换算成 GB $freeGB = [math]::Round($disk.FreeSpace / 1GB, 2) $totalGB = [math]::Round($disk.Size / 1GB, 2) $usedPct = [math]::Round(($disk.Size - $disk.FreeSpace) / $disk.Size * 100, 1) [PSCustomObject]@{ DeviceID = $disk.DeviceID FileSystem = $disk.FileSystem TotalGB = $totalGB FreeGB = $freeGB UsedPct = "$usedPct%" } }这段脚本的逻辑很直接:Get-CimInstance的-Namespace参数对应文档里的命名空间,-ClassName对应类名,-Filter对应 WQL 的WHERE子句。DriveType=3这个条件来自文档里Win32_LogicalDisk的DriveType属性枚举说明,3 代表本地磁盘。FreeSpace和Size都是uint64,PowerShell 会自动处理大整数,但如果你用 VBScript 或 Python 的subprocess调wmic,就要注意 32 位环境下的溢出问题。
参数说明:-Namespace默认是root\cimv2,但查注册表相关类时必须显式指定root\default。-Filter里只能用 WQL 支持的操作符,不能用ORDER BY。如果查询返回空,先检查类名拼写和命名空间,再用Get-CimClass确认类是否存在。
3.3 用 Python 的 wmi 模块对接文档里的类
如果脚本环境是 Python,常用的是wmi模块(底层调pywin32)。下面这段代码查本机所有正在运行的服务,并过滤出自动启动但未运行的服务:
import wmi # 连接本地 WMI,默认命名空间是 root\cimv2 c = wmi.WMI() # 查 Win32_Service 类,文档中 StartMode 和 State 是 string 类型 # StartMode='Auto' 表示自动启动,State!='Running' 表示未运行 services = c.Win32_Service(StartMode='Auto', State='Stopped') for svc in services: # 文档中 Name 是键属性,DisplayName 是可读名称 print(f"服务名: {svc.Name}") print(f"显示名: {svc.DisplayName}") print(f"启动模式: {svc.StartMode}") print(f"当前状态: {svc.State}") print("-" * 40)这段代码里c.Win32_Service(...)的参数直接对应 WQL 的WHERE条件,StartMode='Auto'和State='Stopped'都是文档里Win32_Service类的属性。注意State的取值是字符串,不是数字,文档里会列出所有可能值:Running、Stopped、Paused、Start Pending等。如果你写成State=1,查询会返回空,因为类型不匹配。
参数说明:wmi.WMI()可以传namespace参数切换命名空间,比如wmi.WMI(namespace="root\\default")查注册表。moniker参数可以指定远程主机,但需要目标主机开启 WMI 远程访问并配置好权限。查询返回的是对象列表,每个对象的属性名和文档里的类定义完全一致,可以直接用getattr动态取值。
3.4 从文档里找方法:不只是查属性,还要会调方法
WMI 文档里很多类除了属性还有方法,方法页面会列出参数、返回值、以及调用示例。比如Win32_Process的Create方法可以创建进程,Win32_OperatingSystem的Win32Shutdown方法可以关机重启。方法调用比属性查询复杂,因为要传参数、处理返回值。
下面用 PowerShell 调Win32_Process的Create方法启动一个记事本:
# 获取 Win32_Process 类的实例,用于调用静态方法 $processClass = Get-CimClass -Namespace "root\cimv2" -ClassName Win32_Process # 调用 Create 方法,参数是命令行 # 文档中 Create 方法返回 uint32,0 表示成功 $result = Invoke-CimMethod -CimClass $processClass -MethodName "Create" -Arguments @{ CommandLine = "notepad.exe" } if ($result.ReturnValue -eq 0) { Write-Output "进程创建成功,PID: $($result.ProcessId)" } else { Write-Output "进程创建失败,返回码: $($result.ReturnValue)" }这段代码的关键是Invoke-CimMethod的-Arguments参数,键名必须和文档里方法参数名完全一致。Win32_Process.Create的文档页面会列出CommandLine、CurrentDirectory、ProcessStartupInformation三个参数,其中CommandLine是必填。返回值ReturnValue是uint32,文档里会列出所有返回码的含义,0 是成功,2 是拒绝访问,8 是未知失败,9 是路径未找到,21 是参数无效。
参数说明:Invoke-CimMethod既可以调静态方法(通过-CimClass),也可以调实例方法(通过-InputObject)。静态方法不需要先获取实例,直接传类名即可。如果方法有多个参数,-Arguments里用哈希表传,键名大小写不敏感,但建议和文档保持一致。
4. 避坑与排查:WMI 文档里不会写的那些事
4.1 查不到类或属性:先确认命名空间和权限
现象:照着文档里的类名写查询,返回空或者报“无效类”。原因通常有两个:一是命名空间不对,比如StdRegProv在root\default而不是root\cimv2;二是当前用户没有访问该命名空间的权限,尤其是root\securitycenter2和root\wmi下的类。解决方法是先用Get-CimClass -Namespace "root" -ClassName "*"列出所有命名空间,再逐层往下找。权限问题可以用管理员身份运行脚本验证,如果管理员能查到就说明是权限问题,需要在目标账户上授予 WMI 访问权限。
4.2 属性值类型对不上:uint64 和 datetime 是重灾区
现象:查询返回的数值和预期不符,比如磁盘容量变成负数,或者时间显示成一串数字。原因是 WMI 的uint64在 32 位脚本环境下会溢出,datetime返回的是CIM_DATETIME格式的字符串(如20250101000000.000000+480),不是标准时间格式。解决方法是:在 PowerShell 里用[uint64]强制转换,在 Python 里用int接收,时间字段用datetime.strptime按%Y%m%d%H%M%S解析。文档里每个属性的类型都写得很清楚,写代码前先看一眼类型,能省掉很多调试时间。
4.3 远程查询失败:DCOM 和防火墙是两道坎
现象:本地查询正常,换成远程主机就报“RPC 服务器不可用”或“拒绝访问”。原因是 WMI 远程依赖 DCOM 和 RPC,目标主机需要开启相关服务并配置防火墙规则。解决方法是:在目标主机上确认Winmgmt服务运行中,防火墙放行WMI-In规则,如果跨网段还需要在dcomcnfg里配置远程访问权限。另外,远程查询时命名空间要写全,比如\\目标IP\root\cimv2,不能只写root\cimv2。如果目标主机是域内机器,用域账户查询通常比本地账户顺利。
4.4 查询性能差:全表扫描和频繁连接是主因
现象:查一个属性要等好几秒,批量查几十台机器时脚本卡死。原因是SELECT *会拉取所有属性,而很多属性你根本用不到;另外每次查询都新建 WMI 连接也会消耗时间。解决方法是:在 WQL 里只SELECT需要的属性,比如SELECT DeviceID, Size FROM Win32_LogicalDisk;批量查询时复用同一个连接对象,Python 里用wmi.WMI()只连一次,PowerShell 里用New-CimSession建立会话后反复使用。文档里不会写性能建议,但这些习惯能显著提升脚本效率。
4.5 文档版本与系统版本不匹配:属性可能不存在
现象:文档里明明有的属性,在实际系统上查不到,或者返回NULL。原因是 WMI 文档通常对应较新的 Windows 版本,而你的目标系统可能是旧版,某些属性是后来才加的。解决方法是:在目标系统上用Get-CimClass查看类的实际属性列表,和文档对比。如果属性不存在,要么换一个兼容属性,要么在代码里做版本判断。比如Win32_OperatingSystem的OperatingSystemSKU属性在旧版系统上可能没有,可以用Version属性做分支处理。
5. 进阶技巧:用文档里的限定符做自动化校验
5.1 限定符是文档里的隐藏参数表
WMI 类的每个属性和方法都可以带限定符(Qualifier),英文文档里通常在属性表格的“Qualifiers”列展示。常见的限定符有Key(键属性)、Read(只读)、Write(可写)、Units(单位)、Values(枚举值)、MappingStrings(对应 CIM 标准)。这些限定符不只是说明,还能在代码里动态读取,用来做自动化校验。
比如你想写一个通用的资产采集脚本,不想到处硬编码属性名和单位,可以用Get-CimClass读取类的限定符,自动生成采集逻辑。下面这段 PowerShell 演示如何列出Win32_LogicalDisk所有属性的限定符:
# 获取 Win32_LogicalDisk 类定义 $class = Get-CimClass -Namespace "root\cimv2" -ClassName Win32_LogicalDisk # 遍历属性,输出属性名、类型和限定符 foreach ($prop in $class.CimClassProperties) { $qualifiers = $prop.Qualifiers | ForEach-Object { "$($_.Name)=$($_.Value)" } [PSCustomObject]@{ PropertyName = $prop.Name CimType = $prop.CimType Qualifiers = ($qualifiers -join "; ") } }这段代码的输出里,DeviceID会显示Key=True,FreeSpace会显示Units=Bytes,DriveType会显示Values={0,1,2,3,4,5,6}。有了这些信息,你可以在脚本里自动判断哪些属性是键、哪些属性有单位换算、哪些属性是枚举类型需要映射成可读文本。文档里这些限定符是分散在每个属性页面的,用代码一次性拉出来,效率高很多。
参数说明:CimClassProperties返回的是属性集合,每个属性对象的Qualifiers属性是限定符集合。CimType是 WMI 数据类型,和文档里的类型列对应。注意Values限定符的值是一个数组,在 PowerShell 里会展开成多个值,拼接时要注意格式。
5.2 用 MappingStrings 做跨平台字段映射
MappingStrings限定符是 WMI 文档里最容易被忽略但很有用的东西。它标注了 WMI 属性对应的 CIM 标准路径,比如Win32_Processor.DeviceID的MappingStrings是CIM|Processor.DeviceID。如果你在做跨平台管理工具,需要把 WMI 数据映射到 CIM 标准模型,这个限定符就是现成的映射表。
我一般会在采集脚本里加一段逻辑:如果属性有MappingStrings,就用标准路径作为输出字段名;如果没有,就用 WMI 属性名。这样同一套采集结果既能对接 WMI 原生查询,也能对接基于 CIM 标准的其他数据源。文档里不会专门讲这个用法,但限定符列表里一直有它。
5.3 把文档查询变成可复用的类浏览器
最后分享一个我常用的技巧:用 PowerShell 写一个交互式类浏览器,输入类名就能看到属性、方法、限定符和示例 WQL。这样查文档不用来回翻网页,直接在终端里搞定。核心逻辑就是Get-CimClass加格式化输出,再根据CimClassMethods生成方法调用示例。这个工具本身不复杂,但能把你对 WMI 文档的检索效率提升一个档次。
我自己的习惯是:遇到不熟悉的类,先跑一遍类浏览器看属性列表,再用Get-CimInstance取一条实例数据对照,最后才写正式查询。这样比直接翻英文文档快,也不容易漏掉关键属性。希望帮到你。
本文还有配套的精品资源,点击获取