共用方式為


建立 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-WmiMethod,以及 Remove-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 取得 SWbemServices 物件,並呼叫 GetObject。 或者,您可以使用呼叫 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。 您也可以將對象的類別名稱放在名稱中,這樣可能會更加有效率。

針對 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 用來描述硬碟的實例。 如需詳細資訊,請參閱 Common Information Model。 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