找回密码
 加入
搜索
查看: 33390|回复: 60

在Autoit中使用WMI

 火... [复制链接]
发表于 2008-5-10 23:21:04 | 显示全部楼层 |阅读模式
一、什么是WMI

WMI是Windows 2K/XP管理系统的核心;对于其他的Win32操作系统,WMI是一个有用的插件。有了WMI,工具软件和脚本程序访问操作系统的不同部分时不需要使用不同的API;相反,操作系统的不同部分都可以插入WMI。

也就是说,利用WMI我们能更方便地管理 Windows 资源 — 例如磁盘、事件日志、文件、文件夹、文件系统、网络组件、操作系统设置、性能数据、打印机、进程、注册表设置、安全性、服务、共享、用户、组等等。。

二、对WMI中一些名词的解释

首先看到下面的一个例子,这段代码能够输出物理内存的大小(不是用已有的函数):
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$wbemObjectSet= $wbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")

For $wbemObject In $wbemObjectSet
ConsoleWrite("Total Physical Memory (kb): " & $wbemObject.TotalPhysicalMemory)
Next
在对代码解释前,我先解释一下一些名词的含义:

对象:所谓对象,就是建立COM组件时的返回值,像$wbemServices就是,我们称之为SwbemServicesWMI服务对象,至于$wbemObjectSet则叫做SwbemObject类实例集合对象,后文我还会提到SwbemLocator教本库对象。它们的层级关系如下:SwbemLocator教本库对象→SwbemServicesWMI服务对象→SwbemObject类实例集合对象→SwbemObject类的实例。

属性:以$wbemServices.InstancesOff为例,我们就说$wbemServices对象的InstancesOff属性。

类:WMI能实现的操作有很多种,不同种类的操作都是分开的,我们称之为类,上面代码中的"Win32_LogicalMemoryConfiguration"就是一个类。

命名空间:类也分很多种,功能相近的类分在一起就是命名空间,比如说上面代码中的\root\cimv2。而另一个常用的命名空间是root\DEFAULT。例如,事件日志、性能计数器、Windows 安装程序和 Win32 提供程序都存储在 root\cimv2 命名空间中。另一方面,注册表提供程序存储在 root\DEFAULT 命名空间中。

集合:$wbemObjectSet的数据类型属于集合,用FOR...IN...能对其进行列举。

三、使用WMI的基本步骤

1.获取SwbemServicesWMI服务对象,或者说连接到目标计算机的命名空间
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
2.获取类的集合对象
$wbemObjectSet= $wbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")
3.使用指定对象的属性进行操作
For $wbemObject In $wbemObjectSet
ConsoleWrite("Total Physical Memory (kb): " & $wbemObject.TotalPhysicalMemory)
Next
上面三步仅仅是对WMI操作的概括,实际操作时每一步都很复杂,下面将对这3步逐一进行讲解。

四、连接到命名空间的方法

方法1.用moniker名字法建立WMI服务的连接

这一方法也就是本文的例子所用到的,它的要点就是通过编写一个moniker字符串作为ObjGet函数的参数,然后返回一个SwbemServices对象。

关于moniker字符串的完整格式如下:

"winmgmts:[{SecuritySettings}!][\\ComputerName][\Namespace][:ClassName][.KeyProperty='Value']"

"winmgmts:"是前缀, 表示为WMI服务,必须使用;第二部分用来验证权限和假冒级别的,省略。第三部分为计算机名字:"\\.\"是本机的计算机名字,默认可省略,,其余同上;第四部分命名空间:缺省的命名空间为"root\CIMV2",默认可省略。也就是说我给的那个例子中的相关代码可简写为:$wbemServices = ObjGet("winmgmts:"),但我绝不建议这样做。

第五部分为类名。第六部分为属性值。注意:当该moniker字符串不包括最后2项时(即为:"winmgmts:[\\ComputerName][\Namespace]"),则ObjGet(moniker字符串)返回的是一个命名空间的已验证的连接(SwbemServices对象);当不包括最后1项时,返回的是一个类(SWbemObject对象);当包括最后2项时,返回的是一个类的单独实例(SWbemObject对象)。

方法2.通过建立SwbemLocator对象

这第二种方法我并不推荐,因为操作很繁琐,但是这种方法却能直观反应WMI操作的原理。下面是具体步骤:

1.建立SwbemLocator对象
$objLocator = ObjCreate("WbemScripting.SWbemLocator")
2.通过ConnectServer属性登录到目标计算机,下面的代码是登录到本机
$objService = $objLocator.ConnectServer(".", "root\cimv2")
3.设置impersonation等级
$objService.Security_.ImpersonationLevel = 3
5.执行你的代码,还是以显示物理内存为例
$objLocator = ObjCreate("WbemScripting.SWbemLocator")
$objService = $objLocator.ConnectServer(".", "root\cimv2")
$objService.Security_.ImpersonationLevel = 3

;和第一个例子不同,这里使用了ExecQuery属性来获取Win32_LogicalMemoryConfiguration类的对象
$wbemObjectSet = $objService.ExecQuery("SELECT * FROM Win32_LogicalMemoryConfiguration")

For $wbemObject In $wbemObjectSet
ConsoleWrite("Total Physical Memory (kb): " & $wbemObject.TotalPhysicalMemory)
Next
五、获得类的集合对象的方法

方法1.使用InstancesOf方法

InstancesOf方法的语法参数格式如下:

SwbemServices.InstancesOf(strClass)

strClass为类名,例如"Win32_Service"。

范例:$wbemObjectSet = $wbemServices.InstancesOf("Win32_Service")

我在第一个例子里就是用这种方法来获取Win32_LogicalMemoryConfiguration类的实例集合。

方法2.使用ExecQuery方法

与InstancesOf方法不同,ExecQuery方法可以通过查询语句,只返回匹配部分实例和属性。ExecQuery方法的语法参数格式如下:

SwbemServices.ExecQuery(strQuery, [ strQueryLanguage = "WQL" ],[ iFlags ],[ objWbemNamedValueSet ]

strQuery为WQL(WMI Query Language)查询的字符串,具体语法可以查看这里,下面是几个例子:

SELECT * FROM Win32_LogicalDisk ; 即获取Win32_LogicalDisk类的全部集合对象

SELECT * FROM Win32_NTLogEvent WHERE Logfile = 'Application",,48 ; 从Win32_NTLogEvent类中获取名为"Application"的全部实例

SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Service' AND TargetInstance._Class = 'win32_TerminalService' ; 当Win32_NTLogEvent有新的实例建立时发出通知(这属于WMI事件,具体内容后文再提)

而ExecQuery方法的后几个参数很少会用到,有兴趣的话可以在这里了解更多。

使用范例:$wbemObjectSet = $wbemServices.ExecQuery("select * from Win32_Service")

方法3.使用Get方法

和上面两种方法不同,Get方法获得的是单个的对象。

比方说,下面的代码能列举出全部的系统服务:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$wbemObjectSet = $wbemServices.InstancesOf("Win32_Service")


For $wbemObject In $wbemObjectSet
ConsoleWrite("Name: " & $wbemObject.Name & @CrLf & _
"Display Name: " & $wbemObject.DisplayName & @CrLf & _
" Description: " & $wbemObject.Description & @CrLf & _
" Path Name: " & $wbemObject.PathName & @CrLf & _
" Start Mode: " & $wbemObject.StartMode & @CrLf & _
" State: " & $wbemObject.State & @CrLf & @CrLf )
Next
如果我改用Get方法的话,我们会得到单独的对象,下面的代码是只显示Name为ALG的服务的相关信息:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$wbemObjectSet = $wbemServices.Get("Win32_Service.Name='ALG'")

ConsoleWrite("Name: " & $wbemObjectSet.Name & @CrLf & _
   "Display Name: " & $wbemObjectSet.DisplayName & @CrLf & _
   " Description: " & $wbemObjectSet.Description & @CrLf & _
   " Path Name: " & $wbemObjectSet.PathName & @CrLf & _
   " Start Mode: " & $wbemObjectSet.StartMode & @CrLf & _
   " State: " & $wbemObjectSet.State & @CrLf & @CrLf )
在这两个例子中,后一个例子里的$wbemObjectSet的意义等同于前一个例子里的$wbemObject。

Get方法的格式如下:

SwbemServices.Get([strObjectPath][.KeyProperty='Value'])

strObjectPath是类的名字,KeyProperty是主键属性名,Value是指定的主键属性值。需要注意的是,你要获取的对象的KeyProperty='Value'必须有别于其他对象,否则就会出错。比如下面的代码就无法正常运行:
$wbemServices.Get("Win32_Service.State ='Stopped'")
方法4.直接用用moniker名字法

如果你仔细阅读过第4节的话,应该会发现用moniker名字法不但能建立命名空间,还可以获取类和单独的实例。

具体语法我就不再复述了,下面是两个范例:

1.获取Win32_Service类
$wbemObjectSet = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2:Win32_Service")
2.获取Win32_Service类下Name属性为winmgmt的对象
$wbemObject = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2:Win32_Service.name='winmgmt'")
六、深入了解命名空间

1.管理脚本的默认命名空间

默认情况下,我们用下面的代码就能连接到root\cimv2命名空间:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer )
这段代码没有指定目标命名空间,则脚本连接到由下列注册表设置识别的命名空间:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting\Default 命名空间

命名空间root\cimv2被初始配置为脚本默认的命名空间;但是,默认的脚本命名空间可以很容易地进行更改。因此,我们应该始终在WMI 脚本中标识一个托管资源的命名空间,而不是采用默认设置:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
如果我们想查看脚本的默认命名空间的话,可以用下面的代码:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$colWMISettings = $wbemServices.InstancesOf("Win32_WMISetting")

For $objWMISetting in $colWMISettings
ConsoleWrite("Default namespace for scripting: " & _
$objWMISetting.ASPScriptDefaultNamespace & @CrLf )
Next
同样的,你还可以用下面的代码来设置默认的命名空间:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

For $objWMISetting in $colWMISettings
$objWMISetting.ASPScriptDefaultNamespace = "root\cimv2"
$objWMISetting.Put_
Next
2.列出命名空间

读到这里,我们仅仅了解到root\cimv2这一个命名空间,不过通过WMI自身我们也能知道其他的命名空间。

WMI的命名空间信息可以通过__NAMESPACE类下的实例搜索到,下面的例子是用来搜索所有root\...形式的命名空间:
$objServices = ObjGet("winmgmts:\" & $strComputer & "\root")
$colNameSpaces = $objServices.InstancesOf("__NAMESPACE")

For $objNameSpace In $colNameSpaces
ConsoleWrite( $objNameSpace.Name & @CrLf )
Next
你可能已经注意到,上面的代码不提供目标计算机上所有可用的命名空间的完整描述。它只检索并显示在单一的、指定命名空间下的命名空间。为了在本地或远程的启用 WMI 的计算机上回显所有命名空间,我们可以通过递归来连接到并枚举每个命名空间:
#include <array.au3>
Dim $strCsvListOfNamespaces

EnumNameSpaces("root", $strCsvListOfNamespaces)

$arrNamespaces = StringSplit($strCsvListOfNamespaces, ",")

_ArrayDisplay($arrNamespaces)

Func EnumNamespaces($strNamespace, ByRef $tmpCsvListOfNamespaces)

If $tmpCsvListOfNamespaces = "" Then
$tmpCsvListOfNamespaces = $strNamespace
Else
$tmpCsvListOfNamespaces = $tmpCsvListOfNamespaces & "," & $strNamespace
EndIf

$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "" & $strNameSpace)

If not @error Then
   
$colNameSpaces = $objWMIService.InstancesOf("__NAMESPACE")

For $objNameSpace In $colNameSpaces
EnumNamespaces($strNameSpace & "" & $objNameSpace.Name, $tmpCsvListOfNamespaces)
Next
Else
$tmpCsvListOfNamespaces=""
EndIf

EndFunc
3.列出类

下面的代码列出了所有在root\cimv2命名空间中定义的类:
$strComputer = "."

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$colClasses = $wbemServices.SubclassesOf()

For $objClass In $colClasses
ConsoleWrite( $objClass.Path_.Path & @CrLf )
Next
4.列出指定对象的属性

下面的代码列出了Win32_Service类下的实例能使用的属性(还记得上面的那个列出服务的代码吗?里面所使用的属性可以这样查到):
$strComputer = "."
$strClass = "Win32_Service"

$wbemServices = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$objClass = $wbemServices.Get($strClass)

For $objProperty in $objClass.Properties_() ; Must use (), because method ends with an underscore
ConsoleWrite ($objProperty.Name& @CrLf )
Next
七、WMI编程常用资源

1.AutoIt Script-o-matic

你可以在这里下载到这个工具。这个工具能够列出指定命名空间下的全部类,并显示出该类的全部属性。你还能用这个工具导出AU3脚本。

2.MSDN

Scriptomatic 2.0 官方的WMI查询工具

WMI Reference WMI的全部信息

Querying with WQL WQL查询语法

WMI Tasks for Scripts and Applications 官方WMI范例

八、WMI的应用

这一节将主要分类举出WMI应用的例子,不过暂时不会涉及WMI事件。

No.1.计算机硬件

1.查看可用的物理内存

你可以使用Win32_OperatingSystem类和FreePhysicalMemory属性.
$strComputer = "."

$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")

$colSettings = $objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

For $objOperatingSystem in $colSettings 
ConsoleWrite( "可用物理内存: " & _
$objOperatingSystem.FreePhysicalMemory )
Next
2.判断计算机是否有DVD驱动器

使用Win32_CDROMDrive类下的Name或者DeviceID属性。
$strComputer = "."

$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")

$colItems = $objWMIService.ExecQuery _
("Select * from Win32_CDROMDrive")

For $objItem in $colItems 
ConsoleWrite( "Device ID: " & $objItem.DeviceID &@CRLF _
& "Description: " & $objItem.Description &@CRLF _
& "Name: " & $objItem.Name &@CRLF &@CRLF)
Next
3.检查系统信息处理器数目

使用Win32_ComputerSystem类下的NumberOfProcessors属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colSettings = $objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For $objComputer in $colSettings 
ConsoleWrite( "System Name: " & $objComputer.Name & @CRLF )
ConsoleWrite( "Number of Processors: " & _
$objComputer.NumberOfProcessors )
Next
4.检查PCMCIA接口数量

使用Win32_PCMCIAController类下的 Count 属性
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery("Select * from Win32_PCMCIAController")

ConsoleWrite( "Number of PCMCIA slots: " _
& $colItems.Count)
5.列出没有工作的硬件

你可以使用 Win32_PnPEntity 类, 然后通过使用WQL 查询 WHERE ConfigManagerErrorCode <> 0 来判断
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery _
("Select * from Win32_PnPEntity " _
& "WHERE ConfigManagerErrorCode <> 0")

For $objItem in $colItems
ConsoleWrite( "Class GUID: " & $objItem.ClassGuid & @CRLF )
ConsoleWrite( "Description: " & $objItem.Description & @CRLF )
ConsoleWrite( "Device ID: " & $objItem.DeviceID & @CRLF )
ConsoleWrite( "Manufacturer: " & $objItem.Manufacturer & @CRLF )
ConsoleWrite( "Name: " & $objItem.Name & @CRLF )
ConsoleWrite( "PNP Device ID: " & $objItem.PNPDeviceID & @CRLF )
ConsoleWrite( "Service: " & $objItem.Service & @CRLF & @CRLF )
Next
6.列出所有鼠标的信息

使用 Win32_PointingDevice 类,这样会列出所有指针设备,而不仅仅是鼠标
.$strComputer = "."
$objWMIService = ObjGet( _
"winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery( _
"Select * from Win32_PointingDevice")
For $objItem in $colItems
ConsoleWrite( "Description: " & $objItem.Description & @CRLF )
ConsoleWrite( "Device ID: " & $objItem.DeviceID & @CRLF )
ConsoleWrite( "Device Interface: " _
& $objItem.DeviceInterface & @CRLF )
ConsoleWrite( "Double Speed Threshold: " _
& $objItem.DoubleSpeedThreshold & @CRLF )
ConsoleWrite( "Handedness: " & $objItem.Handedness & @CRLF )
ConsoleWrite( "Hardware Type: " & $objItem.HardwareType & @CRLF )
ConsoleWrite( "INF File Name: " & $objItem.InfFileName & @CRLF )
ConsoleWrite( "INF Section: " & $objItem.InfSection & @CRLF )
ConsoleWrite( "Manufacturer: " & $objItem.Manufacturer & @CRLF )
ConsoleWrite( "Name: " & $objItem.Name & @CRLF )
ConsoleWrite( "Number Of Buttons: " _
& $objItem.NumberOfButtons & @CRLF )
ConsoleWrite( "PNP Device ID: " & $objItem.PNPDeviceID & @CRLF )
ConsoleWrite( "Pointing Type: " & $objItem.PointingType & @CRLF )
ConsoleWrite( "Quad Speed Threshold: " _
& $objItem.QuadSpeedThreshold & @CRLF )
ConsoleWrite( "Resolution: " & $objItem.Resolution & @CRLF )
ConsoleWrite( "Sample Rate: " & $objItem.SampleRate & @CRLF )
ConsoleWrite( "Synch: " & $objItem.Synch & @CRLF & @CRLF )
Next
7.判断计算机是台式机还是笔记本

使用 Win32_SystemEnclosure 类下的 ChassisType 属性
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colChassis = $objWMIService.ExecQuery _
("Select * from Win32_SystemEnclosure")
For $objChassis in $colChassis
For $objItem in $objChassis.ChassisTypes
ConsoleWrite( "Chassis Type: " & $objItem & @CRLF )
Next
Next
8.检查USB接口里插入的是什么设备

使用 Win32_USBHub 类并检查 Description 属性
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery( _
"Select * from Win32_USBHub")
For $objItem in $colItems
ConsoleWrite( "Device ID: " & $objItem.DeviceID & @CRLF )
ConsoleWrite( "PNP Device ID: " _
& $objItem.PNPDeviceID & @CRLF )
ConsoleWrite( "Description: " _
& $objItem.Description & @CRLF & @CRLF )
Next
9.检查系统有多少Tape设备

使用 Win32_TapeDrive 类然后使用 Count 途径
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery( _
"Select * from Win32_TapeDrive")
ConsoleWrite( "Number of tape drives: " _
& $colItems.Count & @CRLF )
No.2.计算机软件

1.卸载软件

如果软件是使用Microsoft Windows Installer (MSI) 安装的话,使用 Win32_Product 类和 Uninstall 途径
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colSoftware = $objWMIService.ExecQuery _
("Select * from Win32_Product " _
& "Where Name = 'Personnel database'")
For $objSoftware in $colSoftware
$objSoftware.Uninstall()
Next
2.列出全部的已安装的软件

如果软件是使用Microsoft Windows Installer (MSI) 安装的话,使用 Win32_Product 类
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colSoftware = $objWMIService.ExecQuery _
("Select * from Win32_Product")

For $objSoftware in $colSoftware
ConsoleWrite( "Name: " & $objSoftware.Name & @CRLF )
ConsoleWrite( "Version: " & $objSoftware.Version & @CRLF & @CRLF )
Next
3.检查用户安装的Microsoft Office的版本

使用 Win32_Product 类下的 Version 属性
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colSoftware = $objWMIService.ExecQuery("Select * from Win32_Product " & _
"Where IdentifyingNumber =" _
& " '{90280409-6000-11D3-8CFE-0050048383C9}'")
For $objItem in $colSoftware
ConsoleWrite( "Name: " & $objItem.Name & @CRLF )
ConsoleWrite( "Version: " & $objItem.Version & @CRLF & @CRLF )
Next
No.3.桌面管理

1.判断系统是否启动在安全模式的网络状态下下

使用 Win32_ComputerSystem 类并检查 PrimaryOwnerName 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colSettings = $objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For $objComputer in $colSettings 
ConsoleWrite( "System Name: " _
& $objComputer.Name & @CRLF )
ConsoleWrite( "Registered owner: " _
& $objComputer.PrimaryOwnerName & @CRLF )
Next
2.检查屏幕保护是否需要密码

使用 Win32_Desktop 类并检查 ScreenSaverSecure 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery("Select * from Win32_Desktop")
For $objItem in $colItems
ConsoleWrite( "Screen Saver Secure: " _
& $objItem.ScreenSaverSecure & @CRLF )
Next
3.获取屏幕分辨率

使用 Win32_DesktopMonitor 类并检查 ScreenHeight 和 ScreenWidth 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery( "Select * from Win32_DesktopMonitor")
For $objItem in $colItems
ConsoleWrite( "Screen Height: " _
& $objItem.ScreenHeight & @CRLF )
ConsoleWrite( "Screen Width: " _
& $objItem.ScreenWidth & @CRLF )
Next
4.获取系统开机的时间

使用 Win32_OperatingSystem 类的 LastBootUpTime 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colOperatingSystems = $objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

For $objOS in $colOperatingSystems
ConsoleWrite( $objOS.LastBootUpTime)
Next
.5.重启或关闭远程计算机

使用 Win32_OperatingSystem 类以及 Win32Shutdown 途径
$strComputer = "atl-dc-01"
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate,(Shutdown)}!\" & _
$strComputer & "\root\cimv2")
$colOperatingSystems = $objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")
For $objOperatingSystem in $colOperatingSystems
$ObjOperatingSystem.Shutdown(1)
Next
6.检查开机自启动项

使用 Win32_StartupCommand 类
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colStartupCommands = $objWMIService.ExecQuery _
("Select * from Win32_StartupCommand")
For $objStartupCommand in $colStartupCommands
ConsoleWrite( "Command: " & $objStartupCommand.Command & @CRLF _
& "Description: " & $objStartupCommand.Description & @CRLF _
& "Location: " & $objStartupCommand.Location & @CRLF _
& "Name: " & $objStartupCommand.Name & @CRLF _
& "SettingID: " & $objStartupCommand.SettingID & @CRLF _
& "User: " & $objStartupCommand.User & @CRLF & @CRLF )
Next
八、续接WMI的应用

No.4.进程

1.检查系统同时运行了多少个au3脚本

使用 Win32_Process 类并找出名字为AutoIt3.exe的进程.
$strComputer = "." 
$objWMIService = ObjGet( _
"winmgmts:\" & $strComputer & "\root\CIMV2") 
$colItems = $objWMIService.ExecQuery( _
"SELECT * FROM Win32_Process" & _
" WHERE Name = 'AutoIt3.exe'") 
For $objItem in $colItems 
ConsoleWrite( "-------------------------------------------" & @CRLF )
ConsoleWrite( "CommandLine: " & $objItem.CommandLine & @CRLF )
ConsoleWrite( "Name: " & $objItem.Name & @CRLF & @CRLF )
Next
2.修改进程的优先权

使用 Win32_Process 类和 SetPriority 途径
Const $ABOVE_NORMAL = 32768
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colProcesses = $objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = 'Notepad.exe'")
For $objProcess in $colProcesses
$objProcess.SetPriority($ABOVE_NORMAL) 
Next
3.列出每个进程所占用的内存

使用 Win32_Process 类和诸如 KernelModeTime, WorkingSetSize, PageFileUsage, 与 PageFaults 的属性
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colProcesses = $objWMIService.ExecQuery _
("Select * from Win32_Process")
For $objProcess in $colProcesses
ConsoleWrite( "Process: " & $objProcess.Name & @CRLF )
$sngProcessTime = (String($objProcess.KernelModeTime) + _
String($objProcess.UserModeTime)) / 10000000
ConsoleWrite( "Processor Time: " & $sngProcessTime & @CRLF )
ConsoleWrite( "Process ID: " & $objProcess.ProcessID & @CRLF )
ConsoleWrite( "Working $Size: " _
& $objProcess.WorkingSetSize & @CRLF )
ConsoleWrite( "Page File Size: " _
& $objProcess.PageFileUsage & @CRLF)
ConsoleWrite( "Page Faults: " & $objProcess.PageFaults & @CRLF & @CRLF )
Next
No.5.磁盘和文件系统

1.列出每个用户所占用的磁盘空间

使用 Win32_DiskQuota 类和 User 以及 DiskSpaceUsed 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colQuotas = $objWMIService.ExecQuery _
("Select * from Win32_DiskQuota")
For $objQuota in $colQuotas
ConsoleWrite( "Volume: "& @Tab _
& $objQuota.QuotaVolume & @CRLF )
ConsoleWrite( "User: "& @Tab & $objQuota.User & @CRLF )
ConsoleWrite( "Disk Space Used: " _
& @Tab & $objQuota.DiskSpaceUsed & @CRLF )
Next
2.检查软驱里是否有软盘

使用 Win32_LogicalDisk 类并检查 FreeSpace 属性
$strComputer = "."
$objWMIService = ObjGet( _
"winmgmts:\" & $strComputer & "\root\cimv2")
$colItems = $objWMIService.ExecQuery _
("Select * From Win32_LogicalDisk Where DeviceID = 'A:'")

For $objItem in $colItems
$intFreeSpace = $objItem.FreeSpace
If $intFreeSpace = "" Then
ConsoleWrite( "There is no disk in the floppy drive." & @CRLF )
Else
ConsoleWrite( "There is a disk in the floppy drive." & @CRLF )
EndIf
Next
3.判断磁盘是否为可移动驱动器

使用 Win32_LogicalDisk 类并检查 DriveType 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colDisks = $objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For $objDisk in $colDisks
ConsoleWrite( "DeviceID: "& @Tab _
& $objDisk.DeviceID & @CRLF )
Switch $objDisk.DriveType
Case 1
ConsoleWrite( "No root directory. " _
& "Drive type could not be " _
& "determined." & @CRLF )
Case 2
ConsoleWrite( "DriveType: "& @Tab _
& "Removable drive." & @CRLF )
Case 3
ConsoleWrite( "DriveType: "& @Tab _
& "Local hard disk." & @CRLF )
Case 4
ConsoleWrite( "DriveType: "& @Tab _
& "Network disk." & @CRLF )
Case 5
ConsoleWrite( "DriveType: "& @Tab _
& "Compact disk." & @CRLF ) 
Case 6
ConsoleWrite( "DriveType: "& @Tab _
& "RAM disk." & @CRLF ) 
Case Else
ConsoleWrite( "Drive type could not be" _
& " determined." & @CRLF )
EndSwitch
Next
4.检查驱动器的文件系统类型

使用 Win32_LogicalDisk 类和 FileSystem 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colDisks = $objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For $objDisk in $colDisks
ConsoleWrite( "DeviceID: " & $objDisk.DeviceID & @CRLF ) 
ConsoleWrite( "File System: " _
& $objDisk.FileSystem & @CRLF )
Next
5.检查磁盘的可用空间

使用 Win32_LogicalDisk 类和 FreeSpace 属性.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:" _
& "{impersonationLevel=impersonate}!\" _
& $strComputer & "\root\cimv2")
$colDisks = $objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk")
For $objDisk in $colDisks
ConsoleWrite( "DeviceID: " & $objDisk.DeviceID & @CRLF ) 
ConsoleWrite( "Free Disk Space: " _
& $objDisk.FreeSpace & @CRLF ) 
Next
6.进行磁盘整理

使用 Win32_Volume 类和 Defrag 途径.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" _
& $strComputer & "\root\cimv2")
$colVolumes = $objWMIService.ExecQuery ("Select * from Win32_Volume Where Name = 'K:\\'")
For $objVolume in $colVolumes
$errResult = $objVolume.Defrag()
Next
No.6.网络

1.禁用网络连接

使用 Win32_NetworkAdapterConfiguration 和 ReleaseDHCPLease 途径.
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")
$colNetCards = $objWMIService.ExecQuery _
("Select * From Win32_NetworkAdapterConfiguration " _
& "Where IPEnabled = True";)
For $objNetCard in $colNetCards
$objNetCard.ReleaseDHCPLease()
Next
2.得到适配器信息

使用 Win32_NetworkAdapterConfiguration 类.
$strComputer = "."
$objWMIService = ObjGet( _
"winmgmts:\" & $strComputer & "\root\cimv2")
$IPConfigSet= $objWMIService.ExecQuery ("Select IPAddress from Win32_NetworkAdapterConfiguration" _
& " where IPEnabled=TRUE")

For $IPConfig in $IPConfigSet
If Not $IPConfig.IPAddress Then 
For $i=0 To UBound($IPConfig.IPAddress)
ConsoleWrite( $IPConfig.IPAddress( $i) & @CRLF )
Next
EndIf
Next
九、WMI事件

所谓WMI事件,即特定对象的属性发生改变时发出的通知,其中包括增加、修改、删除三种类型。

首先看到下面一个例子:
$strComputer = "."

$objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")

$strWQL = "SELECT * " & _
"FROM __InstanceCreationEvent " & _ 
"WITHin$2 " & _
"WHERE TargetInstance ISA 'Win32_Process' " & _
"AND TargetInstance.Name = 'notepad.exe'"

ConsoleWrite( "Waiting for a new instance of Notepad to start..." & @CrLf )
$objEventSource = $objWMIService.ExecNotificationQuery($strWQL)
$objEventObject = $objEventSource.NextEvent()
ConsoleWrite( "A new instance of Notepad was just started." & @CrLf )
当你运行记事本时程序就会发出一条提示。下面是对这段代码的解释:
$strComputer = "."

$objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")
连接到命名空间。
$strWQL = "SELECT * " & _
"FROM __InstanceCreationEvent " & _ 
"WITHin 2 " & _
"WHERE TargetInstance ISA 'Win32_Process' " & _
"AND TargetInstance.Name = 'notepad.exe'"
这是一段WQL查询代码,__InstanceCreationEvent 表示监视新实例的建立,在这里表示新进程建立。类似的东西还有__InstanceModificationEvent、__InstanceDeletionEvent、__InstanceOperationEvent,它们分别表示修改、删除、全部操作(既以上三种的综合)。WITHin 2 表示每两秒查询一次。TargetInstance ISA 'Win32_Process' 表示监控Win32_Process类。TargetInstance.Name = 'notepad.exe'表示监控Name属性为notepad.exe的实例。

$objEventSource = $objWMIService.ExecNotificationQuery($strWQL)
$objEventObject = $objEventSource.NextEvent()

ExecNotificationQuery和ExecQuery的意义差不多一样,不过前者是专门用来获取WMI事件。$objEventSource.NextEvent() 表示不断进行WQL查询,直到通知产生,这段时间内脚本会暂停。

另外,用$objEventObject.Path_.Class你可以获取通知的种类,比如__InstanceCreationEvent。你还可以用$objEventObject.TargetInstance.+属性 来获取产生通知的实例的属性。

理论就讲到这里,剩下的东西相信大家看了下面的几个例子后就明白了。

下面是一段监视进程的范例:
$strComputer = "."

$objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")

$strQuery = "SELECT * " & _
"FROM __InstanceOperationEvent " & _ 
"WITHin 2 " & _
"WHERE TargetInstance ISA 'Win32_Process' " 

$objEventSource = $objWMIService.ExecNotificationQuery($strQuery)

ConsoleWrite( "进程监控开始..." & @CRLF )

While 1
$objEventObject = $objEventSource.NextEvent()
Switch $objEventObject.Path_.Class
Case "__InstanceCreationEvent" 
ConsoleWrite("新进程建立:" & $objEventObject.TargetInstance.Name & @CrLf )
Case "__InstanceDeletionEvent"
ConsoleWrite("进程被关闭:" & $objEventObject.TargetInstance.Name & @CrLf )
EndSwitch
WEnd
下面是一段文件监控的例子:
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$colMonitoredEvents = $objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
& "TargetInstance.GroupComponent= " _
& "'Win32_Directory.Name=""c:\\\\1""'")

While 1
$objEventObject = $colMonitoredEvents.NextEvent()

Select 
Case $objEventObject.Path_.Class()="__InstanceCreationEvent"
ConsoleWrite ("A new file was just created: " & $objEventObject.TargetInstance.PartComponent() & @CR)
Case $objEventObject.Path_.Class()="__InstanceDeletionEvent"
ConsoleWrite ("A file was just deleted: " & $objEventObject.TargetInstance.PartComponent() & @CR)
EndSelect
WEnd
下面是监控USB设备的例子:
$strComputer = "."
$objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\cimv2")

$colEvents = $objWMIService.ExecNotificationQuery _
("Select * From __InstanceOperationEvent Within 5 Where " _
& "TargetInstance isa 'Win32_LogicalDisk'")

While 1
$objEvent = $colEvents.NextEvent
If $objEvent.TargetInstance.DriveType = 2 Then 
Select 
Case $objEvent.Path_.Class()="__InstanceCreationEvent"
Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been added." & @CR)
Case $objEvent.Path_.Class()="__InstanceDeletionEvent"
Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been removed."& @CR)
EndSelect
EndIf
WEnd
——END ,转载请注明本文地址——

评分

参与人数 6威望 +5 金钱 +85 贡献 +25 收起 理由
ScriptFans + 10 感谢分享!
kingdsq + 10
komaau3 + 40 + 10 必须支持 感谢分享
qqgghh1 + 10 + 5
逍遥子 + 5 精品文章

查看全部评分

发表于 2008-5-10 23:48:21 | 显示全部楼层
沙发。。。非常佩服兄才的教程。在下汗颜一个。
发表于 2008-5-19 19:48:47 | 显示全部楼层
TAG:  WMI  USED IN AUTOIT
谢谢楼主教程,用得着
发表于 2008-5-20 21:25:42 | 显示全部楼层
真是好东西!多谢了!
发表于 2008-5-21 10:14:49 | 显示全部楼层
呵呵~坐下慢慢学习一下!
发表于 2008-5-22 16:44:20 | 显示全部楼层
谢谢楼主,收藏了
发表于 2008-5-24 00:06:15 | 显示全部楼层
收藏了,慢慢学习
发表于 2008-7-31 21:03:49 | 显示全部楼层
谢谢,收藏了.值得学
发表于 2008-8-1 06:24:01 | 显示全部楼层
第一次这么全面接触WMI 谢谢楼主
发表于 2009-7-4 00:07:28 | 显示全部楼层
专业名词多啊,一时还消化不了
发表于 2009-7-4 01:13:25 | 显示全部楼层
太厉害了,学都学不完啊
发表于 2009-7-14 14:14:09 | 显示全部楼层
留名 以后漫漫看
发表于 2009-7-19 22:25:44 | 显示全部楼层
高手用的。暂时留个记号
发表于 2009-7-20 11:09:21 | 显示全部楼层
收藏了,慢慢学习
发表于 2009-7-22 22:53:17 | 显示全部楼层
第一次了解。。非常好。。感谢,希望日后能够用到!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-25 23:50 , Processed in 0.100613 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表