建立 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-WmiObject、 Set-WmiInstance、 Invoke-WmiMethod和 Remove-WmiObject。 下表描述用來存取 WMI 資訊的一般程式。 請注意,雖然這些範例大部分都使用 Get-WMIObject,但許多 PowerShell WMI Cmdlet 都有相同的參數,例如 -Class 或 -Credentials。 因此,其中許多進程也適用于其他物件。 如需 PowerShell 和 WMI 的更深入討論,請參閱使用 Get-WMiObject Cmdlet和Windows 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.Get 或 WbemServices.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.InstancesOf或SWbemServices.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方法中的UserName和Password參數。
針對 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