news 2026/11/5 19:15:20

WMI英文开发文档实战指南:从查询到远程采集

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WMI英文开发文档实战指南:从查询到远程采集

简介:这份资源是面向 Windows 平台开发者与 IT 管理员的 WMI 英文官方开发文档,适合需要编写 C、C++、Visual Basic 或脚本程序来自动化管理任务的工程师,也适合希望系统理解 WMI 体系结构、类模型与查询语言的技术人员。文档围绕 WMI 基本概念、体系结构、对象模型、类与命名空间、WQL 查询语言等核心主题展开,涵盖 Win32_OperatingSystem、Win32_Process 等常用类说明,以及 root\cimv2 等命名空间用途,并给出检索已安装软件、活动进程等常见查询示例,可帮助读者掌握远程管理、数据采集与自动化脚本开发思路。资源包共 1 个文件,为 PDF 格式,整体约 57.3MB,内容完整、结构清晰,便于按章节检索与离线查阅。目前已有 111 人学习,适合作为 WMI 开发与运维场景下的案头参考文档。

1. WMI 英文开发文档:从“查不到、看不懂”到能上手写脚本

如果你在 Windows 上做过运维或桌面开发,大概率遇到过这种场景:想查一下本机装了什么杀毒软件、某个服务的启动类型、磁盘还剩多少空间,搜到的答案全指向同一个东西——WMI。可真正打开微软那套英文开发文档时,很多人第一反应是“这写的什么”。类名一长串,命名空间像路径,属性方法混在一起,示例代码还是 C++ 和 VBScript 混着来。这篇笔记就围绕 WMI 的英文开发文档展开,讲清楚这套文档到底怎么读、哪些页面是入口、怎么把它翻译成能跑的 PowerShell 或 C# 代码。适合两类人:一类是被临时派了台 Windows 机器要做资产采集的运维,另一类是想在 .NET 程序里读系统信息的开发者。读完你至少能做到:拿到一个需求,知道去文档哪个角落找对应的类,并且能自己验证属性值。

2. 先搞懂 WMI 文档的骨架:命名空间、类、实例三层结构

WMI 英文开发文档之所以劝退,核心原因是它默认你已经理解了 WMI 的信息模型。这个模型其实就三层:命名空间(Namespace)是分类目录,类(Class)是模板定义,实例(Instance)是运行时的一条具体数据。文档里绝大多数页面都在描述“某个命名空间下某个类有哪些属性和方法”,你只要抓住这条主线,阅读效率会立刻不一样。

2.1 命名空间:为什么 root\cimv2 是绕不开的起点

打开文档搜索任意一个常见类,比如 Win32_Process,你会发现它的完整路径写作root\cimv2:Win32_Process。这里的root\cimv2就是命名空间。WMI 把系统信息按领域分到不同命名空间里,root\cimv2是默认的、也是覆盖面最广的一个,绝大多数 Win32_ 开头的类都在这里。除此之外还有root\default(注册表相关)、root\securitycenter2(安全软件信息)、root\wmi(底层硬件和驱动事件)等。

读文档时第一个动作应该是确认命名空间。很多新手拿着类名去查,代码里却不写命名空间,结果 Get-WmiObject 返回空,还以为是权限问题。实际上 PowerShell 里不写命名空间时默认走root\cimv2,一旦你要查的类不在这个命名空间,就必须显式指定。比如查杀毒软件要用root\SecurityCenter2,这个在文档的类页面顶部通常会标注“Namespace: Root\SecurityCenter2”,养成先看这一行的习惯。

2.2 类页面怎么读:属性、方法、限定符各看什么

一个典型的 WMI 类文档页面包含几块内容:类描述、属性表(Properties)、方法表(Methods)、以及继承关系。属性表里每一行是一个属性名、数据类型和说明。这里有个容易忽略的点:数据类型写的是 CIM 类型(如 string、uint32、boolean、datetime),不是 C# 或 PowerShell 类型,映射关系需要自己转。比如 CIM 的 datetime 在 PowerShell 里拿到的是字符串格式20240501000000.000000+480,要转成 DateTime 对象得用[ManagementDateTimeConverter]::ToDateTime()。

方法表更要注意,WMI 的方法分实例方法和静态方法。静态方法通过类调用,比如Win32_Process.Create()用来创建进程;实例方法通过具体对象调用,比如某个进程对象的Terminate()。文档里方法签名会写清楚参数是 In 还是 Out,返回值是什么。我一般会先把方法签名抄下来,再去写调用代码,避免参数顺序搞错。

2.3 从文档到代码:用 PowerShell 验证一个类的属性

光看文档不够,得动手验证。下面这段代码查本机所有逻辑磁盘的信息,对应文档里的 Win32_LogicalDisk 类。我特意把命名空间写全,方便你对照。

# 显式指定命名空间,避免默认路径找不到类 $disks = Get-CimInstance -Namespace "root\cimv2" -ClassName Win32_LogicalDisk -Filter "DriveType=3" foreach ($disk in $disks) { # DeviceID 是盘符,Size 和 FreeSpace 单位是字节 $sizeGB = [math]::Round($disk.Size / 1GB, 2) $freeGB = [math]::Round($disk.FreeSpace / 1GB, 2) Write-Output "$($disk.DeviceID) 总容量: $sizeGB GB, 剩余: $freeGB GB" }

这段代码里-Filter "DriveType=3"是关键,DriveType 等于 3 表示本地固定磁盘,2 是可移动磁盘,5 是光驱。文档里 Win32_LogicalDisk 的 DriveType 属性会列出所有取值含义,不写 Filter 会把光驱和虚拟盘也查出来。另外注意我用了Get-CimInstance而不是老的Get-WmiObject,前者是微软现在推荐的方式,底层走 WSMan 协议,远程调用更稳。参数上-Namespace和-ClassName是最常用的两个,-Filter支持 WQL 语法,比查出来再 Where-Object 过滤效率高得多。

3. 把英文文档用起来:查询、事件、远程三块高频场景

理解了结构之后,真正干活时高频用到的就三块:查询系统信息、订阅 WMI 事件、远程采集。这三块在文档里各有对应的章节,但分散在不同位置,我按实际使用顺序把它们串起来。

3.1 用 WQL 查询:文档里没明说但必须会的过滤语法

WMI 查询语言 WQL 是 SQL 的子集,文档里对它的介绍藏在“Querying WMI”章节下,不算显眼。基本语法是SELECT 属性 FROM 类 WHERE 条件。和 SQL 最大的区别是 WQL 只支持 SELECT,不支持 JOIN 和 UPDATE。写查询时几个要点:字符串用单引号,日期用YYYYMMDDHHMMSS.ffffff+UUU格式,通配符用%和_。

# 查询最近 24 小时内启动的进程,CreationDate 是 CIM datetime 格式 $since = (Get-Date).AddHours(-24) $wqlTime = $since.ToString("yyyyMMddHHmmss.ffffff+000") $recentProcs = Get-CimInstance -Namespace "root\cimv2" ` -ClassName Win32_Process ` -Filter "CreationDate > '$wqlTime'" $recentProcs | Select-Object Name, ProcessId, CreationDate | Format-Table

这里 CreationDate 的比较是字符串比较,因为 WMI 内部按 CIM datetime 格式排序,所以格式必须严格对齐,少一位都可能查不出结果。我踩过的坑是时区偏移写成+480而不是+000,导致查出来的时间对不上。如果你不确定格式,可以先查一条数据出来看它的 CreationDate 长什么样,照着拼。

3.2 订阅 WMI 事件:用文档里的 __InstanceCreationEvent 做监控

WMI 事件是文档里比较难啃的一块,但做进程监控、文件变动监控时很有用。核心是几个系统类:__InstanceCreationEvent(实例创建)、__InstanceDeletionEvent(实例删除)、__InstanceModificationEvent(实例修改)。文档里对这些类的说明在“Monitoring Events”章节,配合WITHIN和GROUP子句控制轮询间隔和聚合。

# 监控新进程创建,每 2 秒轮询一次 $query = @" SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' "@ Register-CimIndicationEvent -Query $query -SourceIdentifier "NewProcess" -Action { $proc = $Event.SourceEventArgs.NewEvent.TargetInstance Write-Output "新进程: $($proc.Name) PID: $($proc.ProcessId)" }

WITHIN 2表示 WMI 每 2 秒检查一次变化,间隔越小实时性越高但 CPU 开销越大,生产环境一般设 5 到 10 秒。ISA是 WQL 的继承判断关键字,表示 TargetInstance 是 Win32_Process 或其子类。这里用Register-CimIndicationEvent注册后,事件会在后台线程处理,Action 脚本块里能拿到事件对象。注意这个注册是持久的,脚本退出前最好Unregister-Event清理,否则重复注册会报错。

3.3 远程采集:文档里的连接选项和认证方式

远程查 WMI 是运维刚需,文档里在“Connecting to WMI on a Remote Computer”页面列了一堆参数,实际常用的就几个:计算机名、认证级别、凭据。PowerShell 里用 CIM 会话(CimSession)来管理连接,比每次传参干净。

# 创建到远程主机的 CIM 会话,使用当前凭据 $sessionOption = New-CimSessionOption -Protocol Dcom $session = New-CimSession -ComputerName "Server01" ` -SessionOption $sessionOption ` -Credential (Get-Credential) # 复用会话查多个类,避免反复建连 Get-CimInstance -CimSession $session -ClassName Win32_OperatingSystem | Select-Object CSName, LastBootUpTime Get-CimInstance -CimSession $session -ClassName Win32_ComputerSystem | Select-Object TotalPhysicalMemory Remove-CimSession $session

协议选 Dcom 还是 WSMan 取决于目标机器:WSMan 走 5985/5986 端口,需要目标开启 WinRM;Dcom 走 135 端口加动态端口,兼容性更好但防火墙配置麻烦。认证级别在New-CimSessionOption里用-Authentication指定,跨域场景常用 Negotiate。这里用Get-Credential弹窗输入密码,脚本自动化时应该用安全的方式存凭据,不要硬编码在脚本里。

4. 避坑与排查:WMI 开发文档里不会写的血泪经验

文档告诉你“怎么做”,但不会告诉你“为什么跑不通”。下面这几条是我在实际项目里反复遇到的,每条按现象、原因、解决来写。

4.1 现象:Get-CimInstance 返回空,但类明明存在

原因通常有三种:命名空间写错、权限不够、WMI 仓库损坏。先确认命名空间,用Get-CimClass -Namespace "root\cimv2" -ClassName "Win32_Process"看能不能找到类定义。如果类定义能找到但实例为空,检查当前用户是否在目标机器的管理员组或 Performance Monitor Users 组里。WMI 的读权限默认对 Users 组开放,但某些命名空间如root\SecurityCenter2需要更高权限。最后一种情况是 WMI 仓库文件损坏,表现为查询任何类都报错,解决方法是停掉 Winmgmt 服务,重命名C:\Windows\System32\wbem\Repository文件夹,再重启服务让系统重建。

4.2 现象:远程查询报“拒绝访问”或超时

先分清楚是认证失败还是网络不通。认证失败一般报 0x80070005,检查凭据和认证级别;网络不通报 0x800706BA,检查防火墙和端口。Dcom 方式需要目标机器开放 135 端口以及 1024 以上的动态端口范围,很多企业防火墙只开 135 不开动态端口,就会连不上。这时候改用 WSMan 协议,只需要开 5985 端口,配置更简单。另外注意,如果目标机器和发起机器不在同一域,需要在凭据里写目标机器名\用户名的格式。

4.3 现象:WQL 查询结果和预期不一致

最常见的是日期格式和字符串大小写。WQL 的字符串比较默认不区分大小写,但日期比较是字符串比较,格式必须完全一致。另一个坑是WHERE子句里不能用函数,比如WHERE ToLower(Name) = 'test'会报错,只能写成WHERE Name = 'test'然后自己在代码里过滤。还有LIKE操作符的通配符是%不是*,写Name LIKE 'svc%'是对的,写Name LIKE 'svc*'查不出东西。

4.4 现象:事件订阅一段时间后不再触发

WMI 事件订阅有资源限制,单个进程能注册的订阅数量有限,而且如果事件处理脚本执行时间过长,WMI 会丢弃后续事件。解决方法是把耗时操作放到后台任务里,Action 脚本块里只做入队。另外WITHIN间隔设得太小(比如 1 秒)在高负载机器上会导致事件堆积,我一般设 5 秒起步。如果订阅确实需要长期运行,建议用Register-WmiEvent配合-MaxTriggerCount限制触发次数,或者定期重建订阅。

4.5 现象:CIM 类型转换报错

从 WMI 拿到的数据在 PowerShell 里是 CimInstance 对象,属性值可能是数组、引用或特殊格式。比如Win32_Process的CommandLine属性在某些系统上返回 $null,直接做字符串操作会报错。再比如Win32_DiskDrive的Partitions属性是 uint32,但Win32_DiskPartition的Size是 uint64,做算术运算时要注意类型溢出。稳妥的做法是拿到值后先判断类型和空值,再转换。

5. 进阶技巧:用 C# 直接调 System.Management 读文档里的类

PowerShell 适合快速验证,但要做成工具或集成到 .NET 应用里,就得用 C# 的System.Management命名空间。这个库在 .NET Framework 里是内置的,.NET Core 和 .NET 5+ 需要额外装System.ManagementNuGet 包。下面这段代码演示怎么查本机所有服务的状态,对应文档里的 Win32_Service 类。

using System; using System.Management; class WmiDemo { static void Main() { // 构造 WQL 查询,指定命名空间和类名 string query = "SELECT Name, State, StartMode FROM Win32_Service"; ManagementObjectSearcher searcher = new ManagementObjectSearcher( "root\\cimv2", query); foreach (ManagementObject service in searcher.Get()) { // 属性通过索引器访问,返回 object 类型需转换 string name = service["Name"]?.ToString() ?? "未知"; string state = service["State"]?.ToString() ?? "未知"; string startMode = service["StartMode"]?.ToString() ?? "未知"; Console.WriteLine($"{name} | {state} | {startMode}"); } } }

这段代码里ManagementObjectSearcher的构造函数第一个参数是命名空间,第二个是 WQL 查询。searcher.Get()返回ManagementObjectCollection,遍历时每个ManagementObject就是一个实例。属性访问用service["属性名"],返回 object,需要自己转类型。注意ManagementObjectSearcher和ManagementObject都实现了 IDisposable,生产代码里应该用 using 包起来,否则长时间运行会泄漏 WMI 连接。

参数上,ManagementObjectSearcher还有几个重载可以传EnumerationOptions,用来控制超时、是否递归、是否只取本地等。比如远程查询时设options.Timeout = TimeSpan.FromSeconds(30),避免网络慢时卡死。另外ManagementObject的InvokeMethod可以调实例方法,比如对某个服务对象调StopService,参数用ManagementBaseObject封装,这个在文档的“Calling a Method”页面有完整示例。

一个我常用的技巧是:先用 PowerShell 把 WQL 查询调通,确认返回的属性和值都符合预期,再把查询语句原样搬到 C# 里。这样能避免在 C# 里反复编译调试,效率高很多。另外文档里每个类的属性表都标了是否可读可写,写操作前一定确认属性是 Read-Write 还是 Read-Only,否则会抛ManagementException。

最后说个习惯:我每次用一个新的 WMI 类之前,都会先在 PowerShell 里跑一遍Get-CimClass看它的属性和方法列表,再对照文档确认命名空间和数据类型。这个动作花不了一分钟,但能省掉后面半小时的排查。WMI 英文文档看着厚,其实常用的类就那么几十个,把查询、事件、远程这三块吃透,剩下的就是查表填空。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 20:51:06

Sunshine 自托管游戏串流主机:10 分钟搭好低延迟串流服务器

Sunshine 自托管游戏串流主机:10 分钟搭好低延迟串流服务器 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine 是一款自托管的游戏串流宿主程序,配合…

作者头像 李华
网站建设 2026/10/23 15:38:17

TTSR解析:用Transformer为图像超分迁移参考纹理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 14:59:18

Qt环境下bsdiff增量更新:从移植到qlz压缩的完整实践

简介:面向需要在 Qt 应用中实现差分升级的开发者,这份资源将开源工具 bsdiff 移植到 Qt 环境,并使用快速压缩算法 qlz 生成 patch 包。其基本思路是比较新旧版本文件,只提取差异部分并压缩输出,特别适合嵌入式、网络带…

作者头像 李华
网站建设 2026/10/23 14:14:02

Codex 生成前端组件实战:从提示词到工程化对齐的秒级开发

1. 从"等组件"到"秒级出活":前端开发节奏正在被什么改变前端开发这行有个很微妙的痛点:真正写业务逻辑的时间,往往不到一半。剩下的一半,全耗在"搭组件"上——一个带搜索、分页、空状态、加载骨架的…

作者头像 李华
网站建设 2026/10/23 9:55:39

记录 Zabbix 6.4升级7.0.13

环境是Ubuntu 22.04 mysql nginx(系统不同升级命令不同,具体命令详见官方文档)1、更新APT源wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latestubuntu22.04_all.deb2、安装zabbix源dpkg -i…

作者头像 李华