方法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范例