wmi与vbs
字数 1728 2025-08-29 08:32:09
WMI与VBS脚本编程深入解析
1. WMI基础概念
1.1 WMI逻辑结构
WMI(Windows Management Instrumentation)是Windows系统管理的核心组件,其逻辑结构如下:
- WMI使用者:脚本或其他使用WMI接口的应用程序
- WinMgmt服务:CIM对象管理器,作为WMI服务的核心组件
- CIM存储库:保存静态或动态信息(对象属性)和方法
- 事件源:操作系统、服务、应用程序、设备驱动程序等通过COM接口生成事件通知
WMI是事件驱动的,WinMgmt捕捉事件后刷新CIM库中的动态信息。WMI服务依赖于EventLog服务。
1.2 WMI命名空间
类似于注册表的根键,CIM库使用命名空间(Name Space)进行分类管理,常见命名空间包括:
root\cimv2:最常用的命名空间root\subscription:用于事件订阅
2. WMI访问方式
可以通过多种方式访问WMI:
-
命令行工具:
- wmic.exe
- winrm.exe
- winrs.exe
-
脚本语言:
- PowerShell
- Windows Script Host (WSH)
- VBScript
- JScript
-
编程接口:
- MOF (Managed Object Format)
- C/C++ via IWbem
- COM API
- .NET System.Management classes
3. VBScript操作WMI的两种方法
3.1 WMI Moniker方式
使用"winmgmts:"短名称定位WMI命名空间、类或实例:
strComputer = "."
set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
3.2 SWbemLocator对象方式
使用SWbemLocator对象提供更多功能:
set objLocator = CreateObject("WbemScripting.SWbemLocator")
set objSWbemServices = objLocator.ConnectServer(ipaddress, "root\default", username, password)
SWbemLocator特有功能:
- 提供远程计算机的用户凭据
- 在网页中运行WMI脚本
4. WMI权限管理
在VBScript中可以通过以下方式申请WMI权限:
objSWbemServices.Security_.Privileges.Add 23, True '允许远程关机
objSWbemServices.Security_.Privileges.Add 18, True '本地关机
重要权限代号:
- 5:在域中创建账号
- 7:管理审计并查看、保存和清理安全日志
- 9:加载和卸载设备驱动
- 10:记录系统时间
- 11:改变系统时间
- 18:在本地关机
- 22:绕过历遍检查
- 23:允许远程关机
5. WMI事件驱动机制
WMI事件处理机制分为四个部分:
- 事件生产者(Provider):负责生产事件
- 事件过滤器(Filter):通过自定义过滤器捕获感兴趣的事件
- 事件消费者(Consumer):处理事件,可以是可执行程序、DLL或脚本
- 事件绑定(Binding):将过滤器和消费者绑定
5.1 事件消费者类型
- 临时消费者:只在运行期间处理特定事件
- 永久消费者:作为类实例注册在WMI命名空间中,一直有效直到注销
6. WMI查询语言(WQL)
WMI提供三类WQL查询:
6.1 实例查询
查询WMI类的实例:
SELECT <class property name> FROM <class name> WHERE <condition>
示例:
set objSet = objService.InstancesOf("Win32_Process")
6.2 事件查询
用于WMI事件注册机制:
SELECT * FROM __InstanceCreationEvent WITHIN 15
WHERE TargetInstance ISA 'Win32_LogonSession' AND TargetInstance.LogonType = 2
6.3 元查询
查询WMI类架构:
SELECT * FROM Meta_Class WHERE __Class LIKE "win32%"
7. 事件消费者类型
WMI提供五种事件消费者:
- ActiveScriptEventConsumer:执行脚本
- LogFileEventConsumer:写入日志文件
- NTEventLogEventConsumer:写入Windows事件日志
- SMTPEventConsumer:发送邮件
- CommandLineEventConsumer:执行命令行程序
8. 实用示例
8.1 监控进程变化
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colMonitorProcess = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceModificationEvent WITHIN 10" & _
"WHERE TargetInstance ISA 'Win32_Service'")
8.2 任务管理器监控示例
当打开任务管理器时,5秒内启动计算器:
nslink = "winmgmts:\\.\root\cimv2:"
nslink2 = "winmgmts:\\.\root\subscription:"
' 创建CommandLineEventConsumer
set asec = getobject(nslink2 & "CommandLineEventConsumer").spawninstance_
asec.name = "stopped_spooler_restart_consumer"
asec.CommandLineTemplate = "C:\windows\system32\calc.exe"
set asecpath = asec.put_
' 创建事件过滤器
set evtflt = getobject(nslink2 & "__EventFilter").spawninstance_
evtflt.name = "stopped_spooler_filter"
evtflt.EventNameSpace = "root\cimv2"
qstr = "select * from __InstanceCreationEvent within 5 "
qstr = qstr & "where targetinstance isa 'win32_process' and "
qstr = qstr & "targetinstance.name='taskmgr.exe' "
evtflt.query = qstr
evtflt.querylanguage = "wql"
set fltpath = evtflt.put_
' 创建绑定
set fcbnd = getobject(nslink2 & "__FilterToConsumerBinding").spawninstance_
fcbnd.consumer = asecpath.path
fcbnd.filter = fltpath.path
fcbnd.put_
wscript.echo "success"
8.3 日志文件消费者示例
当打开任务管理器时,在C盘创建1.php文件:
set asec = getobject(nslink2 & "LogFileEventConsumer").spawninstance_
asec.name = "stopped_spooler_restart_consumer"
asec.Filename = "C:\1.php"
asec.Text = "<?php phpinfo();?>"
set asecpath = asec.put_
8.4 用户登录监控
当检测到用户登录事件(EventCode=680)时执行程序:
qstr = "select * from __InstanceCreationEvent within 5 "
qstr = qstr & "where targetinstance isa 'win32_NTLogEvent' and "
qstr = qstr & "targetinstance.EventCode='680' "
9. 安全注意事项
- WMI功能强大,不当使用可能影响系统安全
- 远程WMI访问需要适当权限配置
- 永久消费者会持续运行,需谨慎注册
- 在生产环境中使用前应充分测试
10. 总结
WMI提供了强大的系统管理能力,通过VBScript可以灵活地实现:
- 系统监控
- 事件响应
- 自动化管理
- 安全审计
掌握WMI与VBScript的结合使用,可以大幅提升Windows系统管理效率,但同时也需要注意其潜在的安全风险。