建立 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 腳本主機或 WSH) 。

  • PowerShell 的設計與 WMI 緊密整合。 因此,WMI 的大部分基礎元素都內建于 WMI Cmdlet: Get-WmiObjectSet-WmiInstanceInvoke-WmiMethodRemove-WmiObject。 下表描述用來存取 WMI 資訊的一般程式。 請注意,雖然這些範例大部分都使用 Get-WMIObject,但許多 PowerShell WMI Cmdlet 都有相同的參數,例如 -Class-Credentials。 因此,其中許多進程也適用于其他物件。 如需 PowerShell 和 WMI 的更深入討論,請參閱使用 Get-WMiObject CmdletWindows PowerShell - WMI 連線

  • 相反地,VBScript會明確呼叫WMI 的腳本 API,如上所述。 其他語言,例如 Perl,也可以使用 WMI 的腳本 API。 不過,為了本檔的目的,大部分示範 WMI 腳本 API 的範例都會使用 VBScript。 不過,當程式設計技術專屬於 VBScript 時,將會加以呼叫。

    VBScript 基本上有兩種不同的 WMI 存取方式。 第一個是使用 SWbemLocator 物件來連線到 WMI。 或者,您可以使用 GetObject 和 Moniker。 Moniker 是可描述許多元素的字串:您的認證、模擬設定、您要連線的電腦、WMI 命名空間 (,WMI 儲存物件群組的一般位置) ,以及您想要擷取的 WMI 物件。 下列許多範例都描述這兩種技術。 如需詳細資訊,請參閱 建構 Moniker 字串描述 WMI 物件的位置

    不論您用來連線到 WMI 的技術為何,您都可能會從腳本 API 擷取一或多個物件。 最常見的是 SWbemObject,WMI 用來描述 WMI 物件。 或者,您可以使用 SWbemServices 物件來描述 WMI 服務本身,或使用 SWbemObjectPath 物件來描述 WMI 物件的位置。 如需詳細資訊,請參閱 使用 SWbemObject 編寫腳本腳本協助程式物件

使用 WMI 和指令碼語言,如何...

...連線至 WMI?

針對 VBScript 和適用于 WMI 的腳本 API,擷取具有 Moniker 和GetObject呼叫的SWbemServices物件。 或者,您可以使用 對 SWbemLocator.ConnectServer的呼叫來連線到伺服器。 然後,您可以使用 物件來存取特定的 WMI 命名空間或 WMI 類別實例。

針對 PowerShell,連線到 WMI 通常會直接在 Cmdlet 呼叫中完成;因此,不需要其他步驟。

如需詳細資訊,請參閱 描述 WMI 物件的位置建構 Moniker 字串,以及 使用 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,請使用擷取函式,例如 WbemServices.GetWbemServices.InstancesOf。 您也可以將物件的類別名稱放在 Moniker 中擷取,這可能會更有效率。

針對 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 容器物件,它會在腳本中視為可列舉的集合。 您可以從SWbemServices.InstancesOfSWbemServices.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,請陳述 Moniker 中的命名空間,或者您可以在呼叫 SwbemLocator.ConnectServer時明確陳述命名空間。

針對 PowerShell,請使用 -Namespace 參數。 預設命名空間為 「root\cimV2」;不過,許多較舊的類別會儲存在 「root\default」 中。

若要尋找指定 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

...擷取類別的所有子實例?

對於直接使用 WMI 和 PowerShell 腳本 API 的語言,WMI 支援擷取基類的子類別。 因此,若要擷取子實例,您只需要搜尋父類別。 下列範例會搜尋CIM_LogicalDisk,這是預先安裝的 WMI 類別,代表Windows型電腦系統上的邏輯磁片。 因此,搜尋此父類別也會傳回Win32_LogicalDisk的實例,也就是Windows用來描述硬碟的實例。 如需詳細資訊,請參閱 一般資訊模型。 WMI 提供這類預先安裝類別的整個架構,可讓您存取和控制 Managed 物件。 如需詳細資訊,請參閱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.Path_ 屬性描述腳本 API 所傳回之任何指定物件的路徑。 針對 PowerShell,每個 WMI 物件都會有__PATH屬性。 如需詳細資訊,請參閱 描述 WMI 物件的位置

除了命名空間和類別名稱之外,WMI 物件也會有索引鍵屬性,可唯一識別該實例與電腦上的其他實例相較之下。 例如, DeviceID 屬性是 Win32_LogicalDisk 類別的索引鍵屬性。 如需詳細資訊,請參閱 MANAGED 物件格式 (MOF)

最後,相對路徑只是路徑的縮短形式,並包含類別名稱和索引鍵值。 在下列範例中,路徑可能是 「\\computerName\root\cimv2:Win32_LogicalDisk.DeviceID=」D:「」,而相對路徑會是 「」Win32LogicalDisk.DeviceID=「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.Put_ 方法。

針對 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,請在 Moniker 中明確陳述電腦的名稱,或在 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.Security_ 屬性,否則請在 Moniker 中設定相關值。

針對 PowerShell,分別使用 -Authentication-Impersonation 參數。 如需詳細資訊,請參閱 保護腳本用戶端

如需詳細資訊,請參閱 保護腳本用戶端

' 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