Share via


如何追踪是谁在做WMI语句的查询

大家平时可能或多或少使用过WMI来帮助日常的系统维护,不知道有没有碰到过类似这种情形:

比如你知道有某个程序在通过WMI进行一些操作,你想知道这个程序是什么。 一个比较普通的情况就是有时候处理WMI查询的进程wmiprvse.exe CPU占用率很高,看起来在忙于处理来自于应用程序的WMI查询请求,这也许是正常或者不正常,但你可能会想,我是不是至少先知道是哪个程序发起查询呢?

在这之前,我们先看一下下面的WMI的架构图。最上面的一层是WMI consumer,也就是发起查询的程序,可以是程序或者脚本等。这个查询请求会被第二层里面的WMI 服务来处理,WMI服务会根据收到的请求,分发给对应的WMI provider,也就是最终完成查询请求的进程wmiprvse.exe。

具体的信息大家可以参考MSDN文章

https://msdn.microsoft.com/en-us/library/aa394553(v=VS.85).aspx

我们现在的目的就是,知道有WMI consumer,也就是某个程序在做查询,如何来找出是谁呢?

在Windows 2003 Server的系统上面,这个不是一件容易的事情,因为系统内部没有内置的方法,最早以前都是直接在客户的机器上面通过windbg对WMI 服务来做实时调试,很耗时间和精力。当后来这样的案例碰到比较多以后,我们最终写了一个专门的wbemcore.dll,它可以用来自动记录我们想要的信息,来避免实时调试花费大量时间。

从Windows Server 2008开始,这变得非常简单,因为系统已有内置的日志追踪来记录相关的信息。我们来看一下下面的例子:

 1. 打开事件察看器,在察看菜单上面开启”显示分析和调试日志”

 

2. 然后一直找到”应用程序和服务日志”->Microsoft->Windows->WMI-Activity, 右键Trace,选择”启用日志”。

 3. 现在我们通过内置的wbemtest工具来做一个简单的查询。运行wbemtest,点击连接,然后连到root\cimv2这个namespace,点击查询,输入Select * from win32_process。点击应用,完成查询。

4. 回到WMI-Activity,你可以找到类似于下面的一条记录:

可以看到,除了查询的语句,用户名等,进程的PID也会提供。 通过查找PID,我们可以看到这就是我们做测试的wbemtest.exe。

如果做查询的进程会频繁的启动然后退出的话,我们可以在后台运行一个perfmon日志来专门记录所有进程的PID,这样就可以方便的找出是谁。 如果是其他的机器进行的远程WMI查询,同样的信息会被记录。通过ClientMachine可以得到那台客户机的名字,进而去那台机器上面查看是哪个进程。

 

本博文仅供参考,微软公司对其内容不作任何责任担保或权利赋予。