一、什么是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 ,转载请注明本文地址—— |