创建 WMI 脚本

可以使用脚本查看或操作通过 WMI 提供的任何信息。 脚本可以用支持 Microsoft ActiveX 脚本托管的任何脚本语言编写,包括 Visual Basic Scripting Edition (VBScript) 、PowerShell 和 Perl。 Windows 脚本宿主 (WSH) 、Active Server Pages 和 Internet Explorer 均可承载 WMI 脚本。

备注

WMI 当前支持的主要脚本语言是 PowerShell。 但 WMI 还包含对 VBScript 和其他可访问 WMI 脚本编写 API的语言的强大脚本支持。

WMI 脚本语言

WMI 支持的两种主要语言是: PowerShell 和 VBScript (通过 Windows Script Host 或 WSH) 。

  • PowerShell 的设计与 WMI 紧密集成。 因此,wmi cmdlet 中会构建多个 WMI 基础元素: get-wmiobjectset-wmiinstanceinvoke-wmimethodRemove-get-wmiobject。 下表描述了用于访问 WMI 信息的一般过程。 请注意,尽管大多数示例都使用 Get-wmiobject,但许多 PowerShell WMI cmdlet 具有相同的参数,如 -凭据。 因此,其中许多进程还适用于其他对象。 有关 PowerShell 和 WMI 的更深入讨论,请参阅 使用 Get-WMiObject CmdletWINDOWS PowerShell-WMI 连接

  • 与此相反, VBScript 显式调用了 WMI 的 脚本编写 API。 其他语言(如 Perl)还可以使用 WMI 的脚本编写 API。 但出于本文档的目的,演示脚本编写 API for WMI 的大多数示例都使用 VBScript。 但当编程技术特定于 VBScript 时,它将被称为。

    VBScript 实质上是用于访问 WMI 的两种不同方法。 第一种是使用 SWbemLocator 对象连接到 WMI。 或者,可以使用 GetObject 和名字对象。 名字对象是一个字符串,可描述多个元素:你的凭据、模拟设置、你要连接到的计算机、WMI 命名空间 (IE、wmi 存储对象组的常规位置) ,以及你想要检索的 wmi 对象。 下面的许多示例都介绍了这两种方法。 有关详细信息,请参阅 构造名字对象字符串描述 WMI 对象的位置

    无论你使用哪种技术来连接到 WMI,你都可能会从脚本编写 API 中检索一个或多个对象。 最常见的是 SWbemObject,wmi 使用它来描述 wmi 对象。 或者,你可以使用 SWbemServices 对象来描述 wmi 服务本身,或使用 SWbemObjectPath 对象来描述 wmi 对象的位置。 有关详细信息,请参阅通过 SWbemObject 和脚本帮助程序对象编写脚本

使用 WMI 和脚本语言,如何实现 .。。

...连接到 WMI?

对于 VBScript 和 WMI 的脚本编写 API,请使用名字对象和调用 GetObject来检索 SWbemServices对象。 或者,你可以通过调用 SWbemLocator. ConnectServer连接到服务器。 然后,可以使用对象访问特定的 WMI 命名空间或 WMI 类实例。

对于 PowerShell,连接到 WMI 通常直接在 cmdlet 调用中完成;因此,无需执行其他步骤。

有关详细信息,请参阅 描述 WMI 对象的位置构造名字对象字符串使用 VBScript 连接到 WMI

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example: implicitly uses the local compuer (.) and default namespace ("root\cimv2")
Set objWMIService = GetObject("winmgmts:")

#Already has all the defaults set
get-WmiObject Win32_LogicalDisk

#Or, to be explicit,
get-WmiObject -class Win32_LogicalDisk -Computer "." -Namespace "root\cimv2" -Impersonation Impersonate

...从 WMI 检索信息?

对于 VBScript 和 WMI 的脚本编写 API,请使用检索函数,如 WbemServicesWbemServices。是。 您还可以将要在名字对象中检索的对象的类名放在一起,这可能更高效。

对于 PowerShell,请使用 -Class 参数。 请注意,-Class 为默认参数;因此,无需显式声明。

有关详细信息,请参阅 检索 WMI 类或实例数据

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")
Set colScheduledJobs = objService.InstancesOf("Win32_ScheduledJob")

' Second example
SSet Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

#default - you don't actually need to use the -Class parameter
Get-WMIObject Win32_WmiSetting

#but you can if you want to
Get-WMIObject -Class Win32_WmiSetting

...创建 WMI 查询?

对于 VBScript 和 WMI 的脚本 API,请使用 SWbemServices.ExecQuery 方法。

对于 PowerShell,请使用 -Query 参数。 还可以使用 -filter 参数进行筛选。

有关详细信息,请参阅 查询 WMI

strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

Get-WmiObject -query "SELECT * FROM Win32_logicalDisk WHERE DeviceID = 'C:'"

#or

get-wmiObject -Class Win32_LogicalDisk -Filter "DeviceID = 'C:'"

...枚举 WMI 对象的列表?

对于 VBScript 和 WMI 的脚本编写 API,请使用 SWbemObjectSet 容器对象,该对象在脚本中被视为可枚举的集合。 可以从 SWbemServicesSWbemServices.ExecQuery的调用中检索 SWbemObjectSet

PowerShell 能够检索和处理与任何其他对象相同的枚举;WMI 没有什么特别之处。

有关详细信息,请参阅 访问集合

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDevice")

$logicalDevices = Get-WmiObject CIM_LogicalDevice
foreach ($device in $logicalDevices)
{
    $device.name
}

#or, to be more compact

Get-WmiObject cim_logicalDevice | ForEach-Object { $_.name }

...访问其他 WMI 命名空间?

对于 VBScript 和 WMI 的脚本编写 API,请在名字对象中陈述命名空间,或者可以在对 SwbemLocator. ConnectServer的调用中显式声明命名空间。

对于 PowerShell,请使用 -Namespace 参数。 默认命名空间为 "根 \ cimV2"; 但是,许多旧的类存储在 "根 \ 默认值" 中。

若要查找给定 WMI 类的位置,请查看引用页。 或者,可以使用 Get-wmiobject 手动浏览命名空间。

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer(".", "root\cimv2")

' Second example
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")

Get-WmiObject -list * -Namespace root\default

#or, to retrieve all namespaces,
Get-WmiObject -Namespace root -Class __Namespace

...检索类的所有子实例?

对于直接将脚本 API 用于 WMI 和 PowerShell 的语言,WMI 支持检索基类的子类。 因此,若要检索子实例,只需搜索父类。 下面的示例搜索 CIM _ 逻辑磁盘,它是一个预安装的 WMI 类,它表示基于 Windows 的计算机系统上的逻辑磁盘。 同样,搜索此父类还会返回 Win32 _ 逻辑磁盘的实例,Windows 使用这些实例来描述硬盘驱动器。 有关详细信息,请参阅 通用信息模型。 WMI 提供此类预安装类的整个架构,使你能够访问和控制托管对象。 有关详细信息,请参阅 Win32 类WMI 类

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Name
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.Name  }

...找到 WMI 对象?

对于 WMI 和 PowerShell 的脚本编写 API,WMI 使用命名空间、类名称和密钥属性的组合来唯一标识给定的 WMI 实例。 这称为 WMI 对象路径。 对于 VBScript, SWbemObject _属性描述脚本编写 API 返回的任何给定对象的路径。 对于 PowerShell,每个 WMI 对象将具有 _ _ 路径属性。 有关详细信息,请参阅 描述 WMI 对象的位置

除了命名空间和类名以外,WMI 对象还会有一个键属性,该属性与计算机上的其他实例进行唯一标识。 例如, DeviceID 属性是 Win32 _ 逻辑磁盘 类的键属性。 有关详细信息,请参阅 (MOF) 托管对象格式

最后,相对路径只是路径的缩写形式,并且包括类名称和密钥值。 在下面的示例中,路径可以是 " \ \ computerName \ Root \ cimv2: Win32 _ 逻辑磁盘 =" D: "",而相对路径应为 "Win32LogicalDisk =" d ""。

For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_.Relpath

'or to get the path
For Each Disk In GetObject("winmgmts:").InstancesOf ("CIM_LogicalDisk")
  WScript.Echo "Instance:", Disk.Path_
#retrieving the path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__PATH  }

#retrieving the relative path
Get-WmiObject CIM_LogicalDisk | ForEach-Object { "Instance: " + $_.__RELPATH  }

...设置 WMI 中的信息?

对于 VBScript 和 WMI 的脚本编写 API,请使用 SWbemObject _方法。

对于 PowerShell,可以使用 Put 方法,也可以使用 set-wmiinstance

有关详细信息,请参阅 修改实例属性

wbemCimtypeString = 8
Set objSWbemService = GetObject("Winmgmts:root\default")
Set objClass = objSWbemService.Get()
objClass.Path_.Class = "NewClass"

' Add a property
' String property
objClass.Properties_.add "PropertyName", wbemCimtypeString  
' Make the property a key property 
objClass.Properties_("PropertyName").Qualifiers_.add "key", true

' Write the new class to the root\default namespace in the repository
Set objClassPath = objClass.Put_
WScript.Echo objClassPath.Path

'Create an instance of the new class using SWbemObject.SpawnInstance
Set objNewInst = GetObject("Winmgmts:root\default:NewClass").Spawninstance_

objNewInst.PropertyName = "My Instance"

' Write the instance into the repository
Set objInstancePath = objNewInst.Put_
WScript.Echo objInstancePath.Path

$mySettings = get-WMIObject Win32_WmiSetting
$mySettings.LoggingLevel = 1
$mySettings.Put()

#or

Set-WMIInstance -class Win32_WMISetting -argument @{LoggingLevel=1}

...使用不同的凭据?

对于 VBScript 和 WMI 的脚本编写 API,请使用 SWbemLocator. ConnectServer方法中的 UserNamePassword 参数。

对于 PowerShell,请使用 -Credential 参数。

请注意,只能在远程系统上使用备用凭据。 有关详细信息,请参阅 保护脚本客户端

strComputer = "remoteComputerName" 
strDomain = "DOMAIN" 
Wscript.StdOut.Write "Please enter your user name:"
strUser = Wscript.StdIn.ReadLine 
Set objPassword = CreateObject("ScriptPW.Password")
Wscript.StdOut.Write "Please enter your password:"
strPassword = objPassword.GetPassword()
 
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, _
                                                     "Root\CIMv2", _
                                                     strUser, _
                                                     strPassword, _
                                                     "MS_409", _
                                                     "ntlmdomain:" + strDomain)
Set colSwbemObjectSet = objSWbemServices.ExecQuery("Select * From Win32_Process")
For Each objProcess in colSWbemObjectSet
    Wscript.Echo "Process Name: " & objProcess.Name 
Next

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Credential FABRIKAM\administrator  `
-ComputerName $Computer

...访问远程计算机?

对于 VBScript 和 WMI 的脚本编写 API,请在调用 SWbemLocator. ConnectServer中显式声明计算机的名称,或选择其他名称。 有关详细信息,请参阅 通过 VBScript 远程连接到 WMI

对于 PowerShell,请使用 -ComputerName 参数。 有关详细信息,请参阅 通过 PowerShell 远程连接到 WMI

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer("myRemoteServerName", "root\cimv2")
Set colScheduledJobs = objService.ExecQuery("SELECT * FROM Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

'example 2

strComputer = "myRemoteServerName"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
    Wscript.Echo "Job ID: " & objJob.JobId & "Command: " & objJob.Command & VBNewLine

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_logicalDisk -ComputerName $Computer

...设置身份验证和模拟级别?

对于 VBScript 和 WMI 的脚本编写 API,请对返回的服务器对象使用 SWbemServices _属性,或在名字对象中设置相关值。

对于 PowerShell,请分别使用 -Authentication-模拟 参数。 有关详细信息,请参阅 保护脚本客户端

有关详细信息,请参阅 保护脚本客户端

' First example
Set Service = GetObject("WinMgmts:{impersonationLevel=impersonate}!Win32_Service=""ALERTER""")

' Second example
Set Locator = CreateObject("WbemScripting.SWbemLocator")
Set Service = Locator.ConnectServer       
service.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate  
Set objinstance = Service.Get("Win32_Service=""ALERTER""")

$Computer = "atl-dc-01"

Get-WmiObject -Namespace "root\cimv2" -Class Win32_Process -Impersonation Impersonate `
 -Authentication PacketIntegrity -Credential FABRIKAM\administrator -ComputerName $Computer

...在 WMI 中处理错误?

对于 WMI 脚本编写 API,提供程序可能会提供 SWbemLastError 对象,以提供有关错误的详细信息。

特别是在 VBScript 中,使用本机 Err 对象也支持错误处理。 你还可以访问 SWbemLastError对象,如上所述。 有关详细信息,请参阅 检索错误代码

对于 PowerShell,你可以使用标准 PowerShell 错误处理技术。 有关详细信息,请参阅 PowerShell 中的错误处理简介

'using Err
On Error Resume Next
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Wscript.Echo Err.Number

'using SWbemLastError

On Error Resume Next
Set obj = GetObject("winmgmts:root\cimv2:Win32_Process.Handle='one'")
Set LastError = createobject("wbemscripting.swbemlasterror")
Wscript.Echo "Operation = " & LastError.operation & VBCRLF & "ParameterInfo = " _
            & LastError.ParameterInfo & VBCRLF & "ProviderName = " & LastError.ProviderName