天天看點

WMI 腳本入門WMI 腳本入門

WMI 腳本入門

釋出日期: 09/03/2004 | 更新日期: 09/03/2004

Greg Stemp、Dean Tsaltas 和 Bob Wells

Microsoft Corporation

Ethan Wilansky

網絡設計小組

摘要:

Scripting Guys 的第一個 Scripting Clinic專欄展示了如何使用 WMI 腳本庫建立大量有用的 Windows 系統管理腳本。

WMI 腳本入門WMI 腳本入門
本頁内容
WMI 腳本入門WMI 腳本入門
什麼是 WMI?
WMI 腳本入門WMI 腳本入門
快速啟動到 WMI 腳本
WMI 腳本入門WMI 腳本入門
WMI 體系結構
WMI 腳本入門WMI 腳本入門
托管資源
WMI 腳本入門WMI 腳本入門
WMI 基礎結構
WMI 腳本入門WMI 腳本入門
浏覽 CIM
WMI 腳本入門WMI 腳本入門
就到這裡吧

Microsoft®Windows®Management Instrumentation (WMI) 大概是我們已知的 Microsoft 儲存最好的秘密。盡管如此,但毫無疑問,WMI 是 Microsoft 主要的針對 Windows 的管理支援技術。這對您來說意味着什麼呢?那麼,如果您管理 Windows 伺服器和工作站,或者如果您建立 Windows 管理應用程式,您就需要了解 WMI。本文是教授您 WMI,更确切地說,是教您如何使用 WMI 腳本庫來建立大批 Windows 系統管理腳本的系列文章中的第一篇。

在開始之前,我們應該用一點時間來感謝 Andrew Clinick,他讓我們有機會來傳承 Scripting Clinic。可以說,當 Andrew 在其最近的專欄中說他計劃移交更多内容的時候,他并不是在開玩笑!事實上,Andrew 正在轉移到另一個項目,是以他客氣地請我們從他停止的地方繼續。除了開始時由于 Andrew 為Scripting Clinic建立了很高的品質水準而感到有點勉強之外,我們很高興接手這一工作。

那麼,我們是誰呢?我們是 Scripting Guys,是編寫 System Administration Scripting Guide 一書的小組,這本書作為 Microsoft® Windows Server 2003 資源工具箱附帶的一部分。在專欄的大頭照中,左面是 Dean,右面是 Greg。有傳言說 Ethan 和 Bob 由于去做每周一次的肉毒杆菌除皺而錯過了拍照。是以,如果以後在網上看到他們的照片時,發現他們倆看起來非常英俊,我們在這兒要先告訴您,Ethan 和 Bob 真的是我們見過的最笨得令人讨厭的家夥!記得要注意啊。

什麼是 WMI?

WMI最初于 1998 年作為一個附加元件與 Windows NT 4.0 Service Pack 4 一起發行,是内置在 Windows 2000、Windows XP 和 Windows Server 2003 系列作業系統中核心的管理支援技術。基于由 Distributed Management Task Force (DMTF) 所監督的業界标準,WMI 是一種規範和基礎結構,通過它可以通路、配置、管理和監視所有的 — 幾乎所有的 Windows 資源。

要掌握 WMI 的強大功能和範圍,需要考慮以前(或者現在)如何管理并監視 Windows 工作站和伺服器。您可能用過或仍在使用衆多的圖形化管理工具來管理 Windows 資源 — 例如磁盤、事件日志、檔案、檔案夾、檔案系統、網絡元件、作業系統設定、性能資料、列印機、程序、系統資料庫設定、安全性、服務、共享、使用者、組等等。

盡管圖形化工具提供了一種功能管了解決方案,它們所共有的東西是什麼呢?一種答案是,在 WMI 之前,所有的 Windows 圖形化管理工具都依賴于 Win32 應用程式程式設計接口(Application Programming Interfaces,APIs)來通路和管理 Windows 資源。為什麼?因為在 WMI 之前,能夠以程式設計方式通路 Windows 資源的惟一方法就是通過 Win32 API。這種情況使 Windows 系統管理者無法通過一種簡便的方法利用常見的腳本語言來自動化常用的系統管理任務,因為大多數腳本語言都不能直接調用 Win32 API。通過提供一緻的模型和架構,WMI 改變了這種情況 — 通過模型和架構,所有的 Windows 資源均被描述并公開給外界。最好的一點是,系統管理者可以使用 WMI 腳本庫建立系統管理腳本,進而管理任何通過 WMI 公開的 Windows 資源!

使用 Windows Script Host 和 Microsoft Visual Basic Scripting Edition (VBScript),或任何支援 COM 自動化的腳本語言(例如,ActiveState Corporation 的 ActivePerl),可以編寫腳本來管理和自動化企業系統、應用程式和網絡的下列方面:

Windows Server 2003 Windows XP 專業版和 Windows 2000 系統管理 。您可以編寫腳本來檢索性能資料,管理事件日志、檔案系統、列印機、程序、系統資料庫設定、計劃程式、安全性、服務、共享以及很多其他的作業系統元件和配置設定。
網絡管理 。您可以建立基于 WMI 的腳本來管理網絡服務,例如 DNS、DHCP 和啟用 SNMP 的裝置。
實時健全監視 。使用 WMI 事件訂閱,您可以編寫代碼以在事件發生時監視并響應事件日志項,監視并響應檔案系統、系統資料庫修改及其他實時的作業系統更改。基本上對 WMI來說,WMI 事件訂閱和通知是在 SNMP 環境中 SNMP 陷阱是什麼。
Windows .NET 企業伺服器管理 。您可以編寫腳本來管理 Microsoft Application Center、Operations Manager、Systems Management Server、Internet Information Server、Exchange Server 和 SQL Server。
WMI 腳本入門WMI 腳本入門

傳回頁首

快速啟動到 WMI 腳本

為了讓您對 WMI 腳本是什麼有一些概念,讓我們來看看一個表面看來不怎麼重要的任務 — 檢索安裝在基于 Windows 的遠端計算機中的實體記憶體的總量。在 WMI 之前,如果沒有另外的第三方工具,是不能通過一個腳本來輕松完成這個任務的。實際上,在 WMI 之前,使用包括作業系統工具的工具确定安裝在計算機中記憶體數量的惟一方法是通過系統屬性對話框。今天,如果目标計算機上安裝了 WMI,并且有計算機的管理者通路權限,您就可以使用一個 WMI 腳本來檢索在遠端 Windows 計算機上安裝的實體記憶體量,如清單 1 中所示的一樣簡單。

清單 1 :使用 WMI VBScript 檢索總實體記憶體
strComputer = "atl-dc-01"

Set wbemServices = Getobject("winmgmts://" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")

For Each wbemObject In wbemObjectSet
    WScript.Echo "Total Physical Memory (kb): " & wbemObject.TotalPhysicalMemory
Next
      

要運作清單 1 中的示例腳本,将其複制并粘貼到您最常用的文本編輯器中(notepad.exe 也可以),将配置設定給 strComputer 變量的值更改為域中一個有效的啟用 WMI 的計算機,儲存腳本(擴充名為 .vbs),并如

1

所示運作腳本。

WMI 腳本入門WMI 腳本入門
1 GetMemory.vbs 輸出

有點不可思議,無須任何錄入,您應該會看到目标計算機的實體記憶體量回顯到控制台。

現在,在你說“天哪!真的用六行腳本來檢索一台計算機中的記憶體數量?”之前,讓我們先禮貌地插幾句話,因為至今尚不明顯的是,您可以使用與在清單 1 中所示範的相同的基本步驟,從任何通過 WMI 公開的 Windows 資源檢索配置和狀态資訊。

假設您想要檢索安裝在一台遠端計算機上的所有服務的名稱、狀态和啟動類型。清單 2 中的示例腳本完全使用清單 1 中使用過的相同的基本步驟來完成。

清單 2 :使用 WMI VBScript 檢索服務資訊
strComputer = "atl-dc-01"

Set wbemServices = Getobject("winmgmts://" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_Service")

For Each wbemObject In wbemObjectSet
    WScript.Echo "Display Name:  " & wbemObject.DisplayName & vbCrLf & _
                 "   State:      " & wbemObject.State       & vbCrLf & _
                 "   Start Mode: " & wbemObject.StartMode
Next
      

運作清單 2 生成如

2

中所示的輸出。

WMI 腳本入門WMI 腳本入門
2 GetServices.vbs 輸出

假設您對服務不感興趣,但是需要從 Windows 事件日志檢索記錄。再次使用清單 1 中的腳本模闆,您可以很容易地讀取 Windows 事件日志,如清單 3 中所示範。在您運作清單 3 之前我們要指出的是,如果您的事件日志包含數千個記錄,示例腳本可能需要用很長的時間運作。

清單 3 :讀取 Windows 事件日志記錄
strComputer = "atl-dc-01"

Set wbemServices = Getobject("winmgmts://" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_NTLogEvent")

For Each wbemObject In wbemObjectSet
    WScript.Echo "Log File:        " & wbemObject.LogFile        & vbCrLf & _
                 "Record Number:   " & wbemObject.RecordNumber   & vbCrLf & _
                 "Type:            " & wbemObject.Type           & vbCrLf & _
                 "Time Generated:  " & wbemObject.TimeGenerated  & vbCrLf & _
                 "Source:          " & wbemObject.SourceName     & vbCrLf & _
                 "Category:        " & wbemObject.Category       & vbCrLf & _
                 "Category String: " & wbemObject.CategoryString & vbCrLf & _
                 "Event:           " & wbemObject.EventCode      & vbCrLf & _
                 "User:            " & wbemObject.User           & vbCrLf & _
                 "Computer:        " & wbemObject.ComputerName   & vbCrLf & _
                 "Message:         " & wbemObject.Message        & vbCrLf
Next
      

如果我們仔細檢查清單 1、2 和 3,我們會得出關于這三個腳本的兩個非常重要的觀察結果。第一個觀察結果是,所有三個腳本都執行相同的三個步驟:腳本連接配接到 WMI,檢索一個 WMI 托管資源,并回顯資源的幾個屬性。第二個重要的觀察結果是,在每個腳本中,惟一的更改是辨別目标資源的類名(即分别為

Win32_LogicalMemoryConfiguration

Win32_Service

Win32_NTLogEvent

),以及資源的相應屬性。

腳本中使用的三個步驟,對于任何用于檢索 WMI 托管資源資訊的 WMI 腳本來說是共同的。讓我們稍詳細一些地看一下每個步驟。

步驟 1:連接配接到 WMI 服務

在任何 WMI 腳本中,第一個步驟都是建立一個到目标計算機上的 Windows 管理服務的連接配接。連接配接到在本地或遠端計算機上的 WMI 與調用 VBScript 的

Getobject

函數并将 WMI 腳本庫的名字對象的名稱(即“winmgmts:”,後跟目标計算機的名稱)傳遞到

Getobject

一樣簡單。

用這種方法連接配接到 WMI,傳回一個對

SWbemServices

對象的引用,我們使用清單 1、2、3 中的名為 wbemServices 的變量來引用該對象。

SWbemServices

是在 WMI 腳本庫中定義的一打左右的對象中的一個。WMI 腳本庫提供一組用于通路 WMI 基礎結構的通用對象腳本。一旦有一個對

SWbemServices

對象的引用,您就可以調用任何提供了

SWbemServices

的方法;

InstancesOf

就是此種方法中的一個。

步驟 2:檢索 WMI 托管資源的執行個體

普遍認為,第二個步驟主要取決于要執行的任務。在檢索 WMI 托管資源的資訊中,步驟 2 與調用

SWbemServices

對象的

InstancesOf

方法一樣簡單。正如方法名所示,

InstancesOf

傳回由資源的類名辨別的托管資源的所有執行個體。

InstancesOf

以一個

SWbemObjectSet

集合的形式傳回所需的資源,通過使用名為 wbemObjectSet 的變量我們在清單 1、2、3 中引用它。

SWbemObjectSet

是 WMI 腳本庫中定義的另一個腳本對象。

步驟 3:顯示 WMI 托管資源的屬性

最後一個步驟是枚舉

SWbemObjectSet

集合的内容。

SWbemObjectSet

中的每個項都是一個

SWbemObject

(WMI 腳本庫中的另外一個對象) — 表示所需資源的一個單個執行個體。使用

SWbemObject

來通路托管資源類定義中定義的方法和屬性。

那麼,如果從 WMI 檢索資訊的腳本編寫步驟都是相同的,

Win32_LogicalMemoryConfiguration

Win32_Service

Win32_NTLogEvent

類是什麼呢?此外,它們來自哪裡?哪些其他的類是可用的?還有,如何使用它們?這些問題的答案分散在構成 WMI 體系結構的各元件中。讓我們來看一下。

WMI 腳本入門WMI 腳本入門

傳回頁首

WMI 體系結構

WMI 體系結構由三個主層組成,如

3

所示:

托管資源
WMI 基礎結構
使用者
WMI 腳本入門WMI 腳本入門
3 WMI 體系結構

我們将從最低層開始,因為資源是駐留在那裡的。

WMI 腳本入門WMI 腳本入門

傳回頁首

托管資源

托管資源是任意邏輯或實體元件,通過使用 WMI 進行公開和管理。可以使用 WMI 管理的 Windows 資源包括:計算機系統、磁盤、外圍裝置、事件日志、檔案、檔案夾、檔案系統、網絡元件、作業系統子系統、性能計數器、列印機、程序、系統資料庫設定、安全性、服務、共享、SAM 使用者群組、Active Directory、Windows 安裝程式、Windows 驅動程式模式 (WDM) 裝置驅動程式,以及 SNMP 管理資訊基 (MIB) 資料等。WMI 托管資源通過一個提供程式與 WMI 通訊。當開始編寫腳本來與 WMI 托管資源互動時,您經常會看到一個術語執行個體,它被用于引用在運作中的腳本中的托管資源的虛拟表示形式。

WMI 腳本入門WMI 腳本入門

傳回頁首

WMI 基礎結構

中間層是 WMI 基礎結構。WMI 由三個主要元件構成:公共資訊模型對象管理器(Common Information Model Object Manager,CIMOM)、公共資訊模型(Common Information Model,CIM)儲存庫,以及提供程式。這三個 WMI 元件共同提供通過其定義、公開、通路和檢索配置和管理資料的基礎結構。雖然小,但是對編寫腳本來說絕對不可或缺的第四個元件是 WMI 腳本庫。

WMI 提供程式

WMI 提供程式在 WMI 和托管資源之間扮演着中間方的角色。提供程式代表使用者應用程式和腳本從 WMI 托管資源請求資訊,并發送指令到 WMI 托管資源。例如,清單 1 和清單 2 使用内置 Win32 提供程式來檢索記憶體和服務相關資訊。清單 3 使用内置的事件日志提供程式來從 Windows 事件日志檢索記錄。

通過将托管資源公開給基于 WMI 标準的、統一通路模型的 WMI 基礎結構,提供程式隐藏托管資源獨有的實作詳細資訊。WMI 提供程式使用托管資源本機 API 與其相應的托管資源通訊,使用 WMI 程式設計接口與 CIMOM 通訊。例如,内置的事件日志提供程式調用 Win32 事件日志 API 來通路事件日志。

基于 WMI 的可擴充體系結構,軟體開發人員可以開發并內建附加提供程式來公開其産品特有的管理函數。監視 Exchange 連接配接器狀态的 Exchange Server 2000 提供程式就是一個這樣的示例。同樣,Application Center、Operations Manager、Systems Management Server、Internet Information Server 和 SQL Server 都包含 WMI 提供程式。

提供程式通常作為駐留在 %SystemRoot%/system32/wbem 目錄中的動态連結庫 (DLL) 實作。WMI 包括很多針對Windows 2000、Windows XP 以及 Windows Server 2003 系列作業系統的内置提供程式。内置提供程式(也被稱為标準提供程式),從已知的作業系統源(如 Win32 子系統、事件日志、性能計數器、系統資料庫等)提供資料和管理函數。表 1 中列出一些包含在 Windows 2000、Windows XP 和 Windows Server 2003 系列作業系統中的 WMI 提供程式。

表 1:部分标準的 WMI 提供程式清單
提供程式 DLL 命名空間 說明
Active Directory 提供程式 dsprov.dll root/directory/ldap 将 Active Directory 對象映射到 WMI。
事件日志提供程式 ntevt.dll root/cimv2 管理 Windows 事件日志,例如,讀取、備份、清除、複制、删除、監視、重命名、壓縮、解壓縮和更改事件日志設定。
性能計數器提供程式 wbemperf.dll root/cimv2 提供對原始性能資料的通路。
系統資料庫提供程式 stdprov.dll root/default 讀取、寫入、枚舉、監視、建立、删除系統資料庫項和值。
SNMP 提供程式 snmpincl.dll root/snmp 提供對 SNMP MIB 資料的通路,并從 SNMP 托管裝置捕獲。
WDM 提供程式 wmiprov.dll root/wmi 提供對 WDM 裝置驅動程式中資訊的通路。
Win32 提供程式 cimwin32.dll root/cimv2 提供關于計算機、磁盤、外圍裝置、檔案、檔案夾、檔案系統、網絡元件、作業系統、列印機、程序、安全性、服務、共享、SAM 使用者及組,以及更多資源的資訊。
Windows 安裝程式提供程式 msiprov.dll root/cimv2 提供對已安裝軟體資訊的通路。

Windows XP 和 Windows Server 2003 包含很多附加的标準提供程式。如需标準提供程式的完整清單,參見 WMI Software Developers Kit (SDK) 文檔中的 WMI 提供程式參考。

CIMOM

CIMOM(讀作 see-mom)處理使用者和提供程式之間的互動。這一術語是來自于基于 Web 的企業管理軟體和由 Distributed Management Task Force 維護的公共資訊模型規範。

您可以将 CIMOM 想象為 WMI 資訊代理。所有的 WMI 請求和資料都經過 CIMOM。Windows Management Instrumentation 服務 (winmgmt.exe),在 Windows XP 和 Windows Server 系列作業系統上提供了 CIMOM 角色,在通用服務主機程序 (svchost.exe) 的控制下運作。

在運作 Windows 2000 或 Windows NT 4.0 Service Pack 4 的計算機上,WMI 服務作為一個單獨的服務程序運作。在運作 Windows Millennium Edition (Me)、Windows 98 或 Windows 95 OSR 2.5 的計算機上,WMI 作為一個标準可執行程序運作。

除了提供公共接口(使用者通過它通路 WMI)之外,CIMOM 還向 WMI 基礎結構提供下列核心服務:

提供注冊 。WMI 利用 CIMOM 提供注冊位置和功能資訊。此資訊存儲在 CIM 儲存庫中。
請求傳送 。CIMOM 使用提供程式注冊資訊,将使用者請求傳送到合适的提供程式。
遠端通路 。使用者通過連接配接到遠端系統上的 CIMOM 通路啟用 WMI 的遠端系統。一旦連接配接建立,使用者可以執行與在本地可以執行的操作相同的操作。
安全性 。在本地計算機或是遠端計算機上,允許使用者在連接配接到 WMI 之前通過驗證每個使用者的通路标記,CIMOM 控制對 WMI 托管資源的通路。WMI 并不覆寫或阻止由作業系統提供的安全性。
查詢處理 。允許使用者使用 WMI 查詢語言(WMI Query Language,WQL)發出關于任何 WMI 托管資源的查詢。例如,您可以查詢所有發生在過去 24 小時的,符合一個特定事件 ID 的事件的事件日志。CIMOM 隻在提供程式本身不支援查詢操作的情況下執行查詢計算。
事件處理 。允許使用者訂閱表示對 WMI 托管資源更改的事件。例如,您可以訂閱表明邏輯磁盤驅動器上的空間何時下降到可接受的門檻值以下的事件。CICOM 按一個指定的間隔輪詢托管資源,并在滿足訂閱條件時生成一個事件通知。

管理應用程式、管理工具和腳本調入 CIMOM 以挖掘資料、訂閱事件或執行一些其他的與管理相關的任務。CIMOM 獲得必需的提供程式和類資訊以滿足來自 CIM 的使用者的請求。CIMOM 使用從 CIM 獲得的資訊,将使用者的請求傳遞到合适的提供程式。

CIM 儲存庫

WMI 的基本思想是 — 可以用一個架構統一表示來自不同源的配置和管理資訊。CIM 就是這個架構,還調用了模型化托管環境和定義每個由 WMI 公開的資料塊的對象儲存庫或類存儲。該架構基于 DMTF 公共資訊模型标準。

與建立在類概念基礎上的 Active Directory 的架構非常相似,CIM 由類 組成。類是一個 WMI 托管資源的一個藍圖。然而,不同于 Active Directory 類表示建立并存儲在目錄中的對象,CIM 類通常表示動态資源。就是說,資源的執行個體并不存儲在 CIM 中,而是通過基于使用者請求的提供程式動态檢索。其原因很簡單,大多數 WMI 托管資源的操作狀态更改很頻繁,因而必須按需讀取以確定檢索的是最新的資訊。

在 CIM 的上下文中,儲存庫這一術語有些被誤解。盡管 CIM 是一個儲存庫,而且能夠存儲靜态資料,但其主要角色是存儲托管資源的藍圖。

與 Active Directory 類相似之處還有就是,CIM 類是分級組織的,每一級的子類從父類繼承。DMTF 維護一組核心和公共基類,系統和應用程式軟體開發人員(如 Microsoft 的那些)從這些類派生和建立系統(或應用程式)特定的擴充類。

類被分組到命名空間 中,命名空間是表示一個特定的管理區域的類邏輯組。例如,命名空間

root/cimv2

包括大部分表示通常與計算機和作業系統相關聯的資源的類。在前面的腳本中使用的類(

Win32_LogicalMemoryConfiguration

Win32_Service

Win32_NTLogEvent

)駐留在命名空間

root/cimv2

,它們隻是在 CIM 中定義的數百個類中的三個。

CIM 類由屬性和方法構成。屬性描述 WMI 托管資源的配置和狀态,方法是在 WMI 托管資源上執行操作的可執行函數。

不要将由 CIM 定義的方法和屬性與由 WMI 腳本庫中的自動化對象提供的方法和屬性相混淆。

從實體校對看,CIM 駐留在 %SystemRoot%/system32/wbem/Repository/FS/ 目錄中,由下列 4 個檔案組成:

index.btr 。二叉樹 (btree) 索引檔案。
index.map 。事務控制檔案。
objects.data 。存儲托管資源定義的 CIM 儲存庫。
objects.map 。事務控制檔案。

在 Microsoft Windows 2000 和 Windows NT 4.0 Service Pack 4 中,CIM 存儲在 %SystemRoot%/system32/wbem/Respository/cim.rep 中。在 Windows Millennium Edition (Me)、Windows 98 和 Windows 95 OSR 2.5 作業系統中,CIM 存儲在 %windir%/system/wbem/Respository/cim.rep 中。

雖然 CIM 基于面向對象的設計原則,但是您無須成為資訊模組化或架構設計的專家,就可以有效地使用 WMI 并編寫基于 WMI 的腳本。重要的是您了解 CIM 的基礎結構群組織,并了解如何浏覽和解釋它的内容。

WMI 腳本庫

WMI 腳本庫提供自動化對象集,腳本語言(如 VBScript、Jscript 及 ActiveState 的 ActivePerl)利用它通路 WMI 基礎結構。

WMI 腳本庫中的自動化對象為 WMI 基礎結構提供一個一緻且統一的腳本模型。如前面所示,一旦您了解如何使用 WMI 腳本庫檢索一個托管資源類型,您就可以輕松使用相同的步驟來檢索其它的 WMI 托管資源。例如,您可以使用前面列出的 3 個腳本中的任何一個,并很容易地修改這個腳本來檢索在遠端計算機上運作的程序 (Win32_Process) 資訊、處理器 (Win32_Processor) 資訊、作業系統 (Win32_OperatingSystem) 資訊,或者由 WMI 公開的數百個托管資源中的任何一個。

WMI 腳本庫在一個名為 wbemdisp.dll 的單個 DLL 中實作,該 DLL 實體駐留于 %SystemRoot%/system32/wbem 目錄中。WMI 腳本庫還包括一個名為 wbemdisp.tlb 的類型庫。您可以使用 WMI 腳本類型庫來從基于 XML 的 Windows 腳本檔案(擴充名為 .wsf 的 WSH 腳本)引用 WML 常數。

WMI 使用者

使用者是頂層。使用者是腳本、企業管理應用程式、基于 Web 的應用程式,或其他管理工具,它們通過 WMI 基礎結構通路并控制可用資訊。

很多管理應用程式擔當 WMI 使用者和 WMI 提供程式的雙重角色。有數種 Microsoft 管理産品都屬于這種情況,如 Application Center、Operations Manager 以及 Systems Management Server。

WMI 腳本入門WMI 腳本入門

傳回頁首

浏覽 CIM

我們已經讨論了相當一部分的内容,但是還留有一個細節沒有談到,那就是如何确定哪些資源是通過 WMI 公開的。幸運的是,您可以使用多種不同工具來浏覽 CIM 架構并檢查 WMI 托管資源的類定義。

WMI 控件 。WMI 控件 (wmimgmt.msc) 是一個 Microsoft 管理控制台 (MMC) 管理單元,它允許您在本地或遠端計算機上配置 WMI 設定。盡管您不能使用 WMI 控件浏覽 CIM,但是可以使用該工具的“安全性”頁籤來确定在本地或遠端計算機上可用的 CIM 命名空間。有關更多使用 WMI 控件的資訊,參閱 Windows 2000 幫助或 Windows XP 幫助和支援中心内的 WMI 控件概述。
WMI 測試器 。WMI 測試器 (wbemtest.exe) 是一個用于與 WMI 基礎結構互動的通用、圖形化工具。您可以使用 WMI 測試器來浏覽 CIM 架構并檢查托管資源類定義。WMI 測試器還可用于執行與基于 WMI 的腳本執行的相同的操作,例如檢索托管資源的執行個體和運作查詢。WMI 測試器是在所有啟用了 WMI 的計算機上預設的 WMI 安裝的一部分,是以 wbemtest.exe 是一個出色的 WMI 學習和疑難解答工具。有關使用 WMI 測試器的資訊,參閱 Windows XP 幫助和支援中哪诘?WMI 測試器概述。
WMI 指令行 。作為 Windows XP 的一部分釋出的 WMI 指令行工具 (wmic.exe) 提供一個到 WMI 基礎結構的指令行接口。可以使用 wmic.exe 執行來自指令行的常見 WMI 任務,包括浏覽 CIM 和檢查 CIM 類定義。有關使用 WMI 指令行工具的資訊,參閱 Windows XP 幫助和支援中心内的“使用 WMI 指令行 (WMIC) 工具”
CIM Studio 。作為 WMI SDK 的一部分,CIM Studio 提供一個基于 Web 的界面實作與 WMI 基礎結構互動。與 WMI 測試器一樣,您可以使用 CIM Studio 來浏覽 CIM 架構、檢視類定義并檢索托管資源的執行個體。通過 CIM Studio 的超級使用者界面可輕松檢視類關系和關聯,而且 CIM Studio 提供一個基本的搜尋工具 — 它們是 WMI 測試器工具所不具備的兩個功能。要使用 CIM Studio,您必需下載下傳并安裝 WMI SDK。您可以從 Windows Management Instrumentation (WMI) SDK 下載下傳 WMI SDK。
EnumClasses.vbs EnumInstances.vbs 。Windows 2000 Server 資源工具箱包括很多利用了 WMI 的強大功能的腳本。這裡所列出的三個腳本是常見腳本,可用于浏覽 CIM 架構、檢視類定義以及檢索托管資源的執行個體。

您應該檢視的一些附加資源包括:

WMI SDK 文檔 。WMI SDK 包含一個由标準的 WMI 提供程式提供的類的完整清單。您可以通路 MSDN 聯機庫中的 WMI SDK 文檔。
TechNet 腳本中心 。如果您願意,可以把它叫做無用的廢物,但是TechNet 腳本中心包含數百個來自即将推出的 System Administration Scripting Guide 中的基于 WMI 的示例腳本。

WMI 測試器 (wbemtest.exe) 演練

現在,您對可用于浏覽和檢視 CIM 的工具已經有了一些認識,讓我們使用 WMI 測試器 (wbemtest.exe) 來檢查

Win32_Process

類定義并修改清單 2,以便從在您的本地計算機上運作的程序檢索一些屬性。

1. 打開一個指令提示,鍵入 C:/>wbemtest.exe,按下 Enter 來開始 WMI 測試器工具。請注意,大部分按鈕在主 WMI 測試器視窗上是被禁用的,這說明此時您沒有連接配接到 WMI。
2. 單擊 Connect? 連接配接到本地或遠端計算機上的 WMI 服務。顯示“連接配接”對話框,它提供一個标記為 Namespace 的文本輸入區域,該區域預設值為 root/default 。将 Namespace 區域的值更改為 root/cimv2 ,單擊“連接配接”對話框的 Connect 按鈕傳回到主 WMI 測試器視窗。
3. 主視窗中左上角的命名空間辨別符應該顯示為 root/cimv2。請注意,所有的按鈕現在都已啟用,這說明在目前憑據環境下,您已經成功連接配接到本地主機上的 WMI。單擊 Enum Classes? 打開“超類資訊”對話框。
4. 在“超類資訊”對話框中,不要填寫 Enter superclass name 區域,單擊 Recursive 選項,單擊 OK

以枚舉 root/cimv2 名稱空間中定義的所有 CIM 類。

此時,您可能應該正在檢視一個列出了數百個類定義的“查詢結果”對話框。類的數量主要取決于您正在運作的 Windows 的版本。例如,如果使用 Windows 2000,則您應該會看到大約 600 個類定義。如果運作 Windows XP,則您應該會看到大約 900 個類定義。

請注意,列于“查詢結果”對話框頂部的類是以兩個下劃線為開頭的。這些是系統類。系統類是預定義的 CIM 類,支援内部 WMI 配置與操作,例如提供程式注冊、命名空間安全性及事件通知等。現在,忽略系統類,向下滾動“查詢結果”對話框直至看到以 CIM_ 開頭的類。

名稱以 CIM_ 開頭的類是由 DMTF 維護的核心與公共基類。繼續向下滾動直至到達以 Win32_ 開頭的類。

名稱以 Win32_ 開頭的類是 Microsoft 擴充類,表示 Windows 特定的托管資源。如果這是您第一次檢查

root/cimv2 命名空間,您可能希望熟悉 root/cimv2 命名空間中的類的完整集合,尤其是有 Win32_ 字首的類。
5. 向下滾動“查詢結果”對話框直至到達 Win32_Process 類,輕按兩下該類名打開 Win32_Process 對話框的對象編輯器。
6.

“對象編輯器”對話框顯示被標明類的定義和實作的詳細資訊(屬性和方法)。回憶一下我們之前讨論的内容 — 類定義是 WMI 可管理資源的藍圖。

選擇

Hide System Properties

複選框隐藏系統屬性。剩餘的 Win32_Process 屬性表示您可以從在本地或遠端計算機上運作的程序檢索的資訊。

要完成您的 WMI 腳本練習,嘗試去檢索

Name Handle ProcessID 屬性。使用前面的三個清單之一作為模闆,試着在進行到第 7 步之前運作腳本。 要在本地計算機上運作腳本,将 strComputer 變量的值設定為“.”(引号内的一個單點)。
7. 在運作新建立的 GetProcesses.vbs 腳本之後,您可以用 WIMI 測試器驗證腳本的結果。在 Win32_Process 對話框的對象編輯器中,單擊 Instances 。産生的查詢結果對話框列出在計算機上運作的程序的執行個體。輕按兩下一個指定的程序執行個體,檢視該執行個體的詳細資訊。
WMI 腳本入門WMI 腳本入門

傳回頁首

就到這裡吧

誠然,我們隻是觸及了 WMI 腳本撰寫的表層。十分坦誠地說,這是有意的。WMI 提供了如此之多的腳本編寫的可能性,是以很容易造成“隻見樹木,不見森林”的結果。不過不要擔心,随着本系列内容的展開,我們将填補所有的缺口。此時要提煉出的重要内容是:WMI 是 Windows 中單獨的、最重要的管理支援技術,您無需成為開發人員或者腳本編寫權威就可以開始編寫基于 WMI 的腳本。繼續修改您新建立的腳本以檢索另外的程序屬性,或再進一步 — 檢索其他托管資源。在我們下個月見面之前,您可能發現自己有了一個滿是自定義的系統管理腳本的工具箱。讓我們知道您做得到底怎麼樣。

清單 4 WMI 測試器演練的答案
strComputer = "."   ' Dot (.) equals local computer in WMI

Set wbemServices = Getobject("winmgmts://" & strComputer)
Set wbemObjectSet = wbemServices.InstancesOf("Win32_Process")

For Each wbemObject In wbemObjectSet
    WScript.Echo "Name:          " & wbemObject.Name      & vbCrLf & _
                 "   Handle:     " & wbemObject.Handle    & vbCrLf & _
                 "   Process ID: " & wbemObject.ProcessID
Next
      
Scripting Clinic Greg Stemp

是美國國内公認的腳本編寫權威之一,并且被大家廣泛譽為世界級……哈哈!嗯,他們 的履曆表中怎麼都當過足球教練?真的嗎?他被解雇 了?哦,很好!Greg Stemp 工作在……哦,來吧,難道我連這都不能說嗎?好吧!Greg Stemp 從 Microsoft 領薪水,在 Microsoft 他擁有并不顯赫的首席作家(System Administration Scripting Guide)的頭銜。

Bob Wells

漫無目的地四處遊走,向每個聽他說話的人大贊腳本編寫的好處。有傳言說,Bob 的兩隻達克思獵犬對腳本編寫比大多數人類知道的都多。業餘時間,Bob 向 System Administration Scripting Guide 投稿。

Ethan Wilansky

把他的很多工作時間花在了寫作和咨詢方面。他狂熱于腳本編寫、瑜伽、園藝和他的家庭(不一定按此順序)。他目前正緻力于一種建立能倒垃圾和洗餐盤的腳本的方法。

如果要建造一所房子,您需要知道如何閱讀和解釋建築圖。如果要制造一個電子器具,您需要知道如何閱讀和解釋示意圖。那麼如果要編寫一個 WMI 腳本,您猜到了,需要知道如何解釋 WMI 對于管理的藍圖 — CIM 儲存庫。CIM 儲存庫,在 WMI SDK 中也稱為 WMI 儲存庫,是存儲模組化 WMI 托管資源的類定義的 WMI 架構。

為了強調 CIM 和 CIM 類的重要性,仔細考慮在 WMI 腳本入門:第一部分中展示的 4 個腳本,以及下面的清單 1 和清單 2。清單 1 是來自第一部分的服務腳本的一個略有增強的版本,而清單2 是使用

Win32_OperatingSystem

類的相同腳本的另一個變體。

如果您對清單 1 和 2 有疑惑,我們建議您閱讀(或視具體情況重讀)本系列内容的第一部分。

清單 1 :使用 WMI VBScript 檢索服務資訊
strComputer = "."   ' Dot (.) equals local computer in WMI

Set objWMIService = GetObject("winmgmts://" & strComputer)
Set colServices = objWMIService.InstancesOf("Win32_Service")

For Each objService In colServices
    WScript.Echo "Name:           " & objService.Name        & vbCrLf & _
                 "Display Name:   " & objService.DisplayName & vbCrLf & _
                 "   Description: " & objService.Description & vbCrLf & _
                 "   Path Name:   " & objService.PathName    & vbCrLf & _
                 "   Start Mode:  " & objService.StartMode   & vbCrLf & _
                 "   State:       " & objService.State       & vbCrLf
Next
      
清單 2 :使用 WMI VBScript 檢索作業系統資訊
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer)
Set colOperatingSystems = objWMIService.InstancesOf("Win32_OperatingSystem")

For Each objOperatingSystem In colOperatingSystems
    Wscript.Echo "Name:            " & objOperatingSystem.Name   & vbCrLf & _
        "Caption:         " & objOperatingSystem.Caption         & vbCrLf & _
        "CurrentTimeZone: " & objOperatingSystem.CurrentTimeZone & vbCrLf & _
        "LastBootUpTime:  " & objOperatingSystem.LastBootUpTime  & vbCrLf & _
        "LocalDateTime:   " & objOperatingSystem.LocalDateTime   & vbCrLf & _
        "Locale:          " & objOperatingSystem.Locale          & vbCrLf & _
        "Manufacturer:    " & objOperatingSystem.Manufacturer    & vbCrLf & _
        "OSType:          " & objOperatingSystem. OSType         & vbCrLf & _
        "Version:         " & objOperatingSystem.Version         & vbCrLf & _
        "Service Pack:    " & objOperatingSystem.ServicePackMajorVersion  & _
                "." & objOperatingSystem.ServicePackMinorVersion & vbCrLf & _
        "Windows Directory: " & objOperatingSystem.WindowsDirectory
Next
      

在本系列文章第一部分中的每個腳本以及本文的清單 1 和 2 中,唯一有差別的特征是辨別 WMI 托管資源的類名和每個類屬性的子集。相同腳本模闆可以用來檢索全部的實體記憶體、服務、事件日志記錄、程序和作業系統資訊,這一事實證明了 CIM 類在 WMI 腳本中扮演的重要角色。一旦知道如何編寫一個腳本來管理一類 WMI 托管資源,您就可以對其他托管資源使用相同的基本技術。

當然,知道一個托管資源的類名以及該類的相應屬性隻是本文的一部分。在您能夠巧用 WMI 腳本的全部強大功能之前,您需要對 CIM 儲存庫和 CIM 類的結構了解得再多一些。為什麼呢?我們将給出兩個重要的理由。

1. 了解如何浏覽 CIM 将幫助您确定通過 WMI 公開的計算機和軟體資源。
2. 了解如何解釋托管資源的藍圖(類定義),将幫助您了解可以在托管資源上執行的任務。

無論使用什麼 WMI 工具,這兩點都成立,無論使用 WMI 腳本庫、WMI 指令行工具 (wmic.exe),或者企業管理應用程式,您都需要知道如何浏覽 CIM 并解釋 CIM 類。

一個不那麼明顯但是同樣重要的學習 CIM 的原因是,CIM 是 WMI 托管資源的極好的文檔資源。沒錯,如果需要關于 WMI 類的詳細資訊,可以使用 WMI SDK。但是,如果不 需要關于 WMI 類的詳細資訊呢?假設您隻想知道正在運作的 Microsoft Windows 版本是否支援一個指定的類、方法或屬性。那麼,看看目标計算機的 CIM 吧。

例如,我們經常被問及“為什麼 TechNet 的腳本中心裡的‘加入計算機到域’腳本在 Windows 2000 中不能用?”回答是,因為在 Windows 2000 中的

Win32_ComputerSystem

類(它是在腳本中使用的 WMI 類)不支援

JoinDomainOrWorkGroup

方法。在内置于 Windows XP 和 Windows Server 2003 的 WMI 版本中,

JoinDomainOrWorkGroup

方法被添加到

Win32_ComputerSystem

類中。

那麼如何了解或學習它呢?一種方法是使用我們在第一部分中列出的 WMI 工具集合。另一種更強大、靈活的方法是使用 WMI 腳本庫。關于 WMI,真正酷的事情之一是,您可以使用 WMI 腳本庫來學習 WMI。沒錯,用編寫 WMI 腳本來檢索 WMI 托管資源相同的方法,您也可以編寫 WMI 腳本來學習關于 WMI 本身的各種有趣的詳細資訊。您可以編寫 WMI 腳本來列出 CIM 儲存庫中所有的命名空間和類。您可以編寫腳本來列出一台啟用 WMI 的計算機上安裝的所有提供程式。您甚至可以編寫 WMI 腳本來檢索托管資源類定義。

無論選擇使用現有的工具或者建立自己的工具,您都需要對 CIM 儲存庫的結構有一個基本的了解。是以,讓我們從第一部分停止的地方開始,仔細了解一下 WMI 的管理藍圖 — CIM 儲存庫。在整個讨論中,我們将使用 WMI 腳本庫為您說明如何檢索 WMI 配置資訊和托管資源類定義。

管理藍圖

在第一部分中,我們說到 WMI 的基本思路是 — 來自不同來源的配置和管理資訊能夠用一種架構統一地表示,而 CIM 儲存庫就是針對 WMI 的架構。可以将架構想象為藍圖或者代表現實世界中存在的某事物的模型。就好像建築圖建構實體結構的模型(例如,房子),WMI CIM 建構構成計算機的硬體、作業系統和軟體的模型。CIM 是 WMI 的資料模型。

雖然 CIM 儲存庫能夠存儲一些資料(而且它确實存儲了),但是它的主要目的是建構管理環境的模型。CIM 不是為存儲它所定義的大量管理資訊而設計的。相反,大部分資料是根據需要動态地從 WMI 提供程式檢索的。一個例外是 WMI 操作資料。WMI 操作資料(例如,命名空間資訊、提供程式注冊資訊、托管資源類定義和永久事件訂閱)存儲于 CIM 儲存庫中。

1

提供了一個 CIM 儲存庫的内部結構群組織的概念化視圖。如

1

所示,CIM 使用類來建立資料模型。不可否認,CIM 包含的類遠超過關系圖中展示的 11 個 — 上次我們在 Windows Server 2003 上統計大約有 5000 個。要了解的重要内容是,CIM 儲存庫是定義 WMI 托管環境和每個通過 WMI 公開的可托管資源的類存儲。

1

中展示三個重要的 CIM 概念,您需要了解它們以成功地浏覽并解釋 WMI 架構。

1. CIM 儲存庫被劃分為多個命名空間。
2. 每個命名空間包含下面一個或多個類的組:系統類、核心和公共類和/或擴充類。
3. 有三種主要的類類型:抽象、靜态和動态。抽象類 是用于派生(定義)新的抽象和非抽象類的模闆,不能用于檢索托管資源的執行個體。靜态類 定義實體存儲在 CIM 儲存庫中的資料 — 最常見的是 WMI 配置和操作資料。動态類 是為從提供程式中動态檢索的 WMI 托管資源模組化的類。稱作關聯類的第四種類類型,也是受支援的。關聯類 是一個抽象、靜态或動态的類,描述兩個類或托管資源之間的關系。暫時别太擔心關于 CIM 類類型問題,我們很快就會在一個更實際的環境中讨論 CIM 類類型。

讓我們更詳細地看看每一個 CIM 概念。

WMI 腳本入門WMI 腳本入門
1 CIM 儲存庫的結構化視圖

WMI 架構

CIM 實體駐留在 Windows XP 和 Windows Server 2003 中名為 %SystemRoot%/system32/wbem/Repository/FS/objects.data 的檔案内。Windows 2000 和 Windows NT 4.0 Service Pack 4 将 CIM 存儲在 %SystemRoot%/system32/wbem/Repository/cim.rep 中。而在 Windows Millennium Edition (Me)、Windows 98 和 Windows 95 OSR 2.5 作業系統中,CIM 存儲在 %windir%/system/wbem/Repository/cim.rep 中。

命名空間定義

CIM 類被組織到命名空間中。命名空間是 CIM 使用的分區機制,控制托管資源類定義的範圍和可見性。CIM 中的每個命名空間包含一個表現特定技術或管理區域的相關類的邏輯組。命名空間中的所有類必須有一個唯一的類名,一個命名空間中的類不能從另一個命名空間中的類派生,這就是為什麼您将發現在多個命名空間中定義的相同的系統、核心以及公共類。

多數為 Windows 托管資源模組化的類駐留在 root/cimv2 命名空間中。不過,按照

1

中的建議,root/cimv2 不是您唯一需要注意的命名空間。例如,事件日志、性能計數器、Windows 安裝程式和 Win32 提供程式都将它們的托管資源類定義存儲在 root/cimv2 命名空間中。另一方面,系統資料庫提供程式将其類定義存儲在 root/DEFAULT 命名空間中。另外,新的 Windows Server 2003 DNS 提供程式将其托管資源類定義存儲在 root/MicrosoftDNS 命名空間中。

命名空間使用

那麼,命名空間如何影響您的 WMI 腳本呢?每個 WMI 腳本都作為初始化連接配接步驟(上個月我們簡要地讨論過)的一部分連接配接到一個命名空間,如下所示:

strComputer = "."
Set wbemServices = GetObject("winmgmts://" & strComputer)
      

如上,如果沒有指定目标命名空間,則腳本連接配接到由下列系統資料庫設定識别的命名空間:

HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/WBEM/Scripting/Default 命名空間

預設的命名空間設定是 WMI 腳本,%PATH% 環境變量的預設設定是作業系統。當您通過指令提示送出了一個指令而沒有指定指令的完全限定路徑時,作業系統使用 %PATH% 環境變量來定位該指令的可執行檔案。如果作業系統不能找到這個檔案,就會産生錯誤。

同樣,當您在 WMI 腳本中檢索一個托管資源時,如果沒有指定命名空間,CIMOM(WMI 服務)就在預設的命名空間尋找該托管資源的藍圖(類定義)。如果 CIMOM 在預設的命名空間中找不到托管資源類定義,就會産生一個 WBEM_E_INVALID_CLASS (0x80041010) 錯誤。

不要将預設的命名空間設定與 root/DEFAULT 命名空間相混淆。它們是不相關的,除非您将 root/DEFAULT 設定為您的預設命名空間。

命名空間 root/cimv2 被初始配置為腳本預設的命名空間;但是,預設的腳本命名空間可以很容易地進行更改。是以,您應該始終在您的 WMI 腳本中辨別一個托管資源的命名空間,而不是采用預設設定。如果上個月就遵照了我們自己的建議,所有 4 個清單(以及本文的清單 1 和 2)中的連接配接步驟就應該編寫如下:

strComputer = "."
Set wbemServices = GetObject("winmgmts://" & strComputer & "/root/cimv2")
      

将目标命名空間添加到連接配接字元串會告訴 CIMOM 在 CIM 中到哪裡去尋找托管資源類定義,很像完全限定路徑告訴作業系統到底去哪裡尋找一個檔案。當您指定了目标命名空間,預設的命名空間就不使用了。

管理腳本的預設命名空間

您可以像清單 3 和清單 4中展示的那樣,将 WMI 腳本庫與

Win32_WMISetting

類結合使用來讀取和更改腳本的預設命名空間。

Win32_WMISetting

是一個為 WMI 服務的操作參數模組化的動态類。可寫的屬性表示腳本的預設命名空間是

ASPScriptDefaultNamespace

清單 3 使用了相同的 3 個 WMI 腳本編寫步驟 — 連接配接、檢索和顯示 — 我們一直在使用的步驟,不過有一個明顯的改變。正如前面建議的,我們在傳遞到 Microsoft Visual Basic Scripting Edition (VBScript) 的

GetObject

函數的 WMI 連接配接字元串中,指定

Win32_WMISetting

類的完全限定命名空間。那麼,這裡您會認為 Microsoft 沒有遵循他們自己的建議。我們不但在清單 3 中遵循我們命名空間的建議,而且從此以後我們将限定命名空間。是的,如果想在您的 WMI 腳本中避免無效的類錯誤,它就是那麼的重要。

清單 3 :為使用 WMI VBScript ,檢索腳本的預設命名空間
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colWMISettings = objWMIService.InstancesOf("Win32_WMISetting")

For Each objWMISetting in colWMISettings
    Wscript.Echo "Default namespace for scripting: " & _
                 objWMISetting.ASPScriptDefaultNamespace 
Next
      

要運作清單 3 中的示例腳本,将這段腳本複制并粘貼到您最喜歡的文本編輯器中,儲存腳本(擴充名為 .vbs),然後如

2

所示運作腳本。您應該看到本地計算機的預設命名空間回顯到控制台中。

WMI 腳本入門WMI 腳本入門
2 GetDefaultNamespace.vbs 輸出

要設定腳本的預設命名空間,執行與清單 3 中的相同腳本編寫步驟,但要做一個重要的更改 — 好吧,如果您在數腳本行數的話就算兩個。您應該使用

SWbemObject

來設定後面跟有調用

SWbemObject

Put_

方法的屬性來将更改送出到 WMI 托管資源,而不要使用 WMI 腳本庫的

SWbemObject

從 WMI 托管資源的執行個體中讀取屬性。設定和送出操作在清單 4 中的 For Each 循環内執行,因為

SWbemServices InstancesOf

方法總是傳回一個

SWbemObjectSet

集合,即便是隻有一個目标 WMI 托管資源執行個體,如

Win32_WMISetting

清單 4 :用 WMI VBScript 設定腳本的預設命名空間
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colWMISettings = objWMIService.InstancesOf("Win32_WMISetting")

For Each objWMISetting in colWMISettings
        objWMISetting.ASPScriptDefaultNamespace = "root/cimv2"
        objWMISetting.Put_
Next
      

不要太專注于 WMI 腳本庫的結構,因為我們将在本系列的第三部分中詳細說明 WMI 腳本庫。現在,讓我們把注意力轉回到 CIM。

列出命名空間

到目前為止,我們已經用相同的 WMI 腳本技術來檢索動态的 WMI 托管資源的執行個體。例如,在第一部分中,我們使用相同的腳本模闆來檢索實體記憶體、服務、事件日志記錄和程序。在第二部分中,我們檢索服務、作業系統資訊和腳本的預設命名空間。這表明,您可以使用相同的 WMI 腳本技術來從 CIM 中檢索命名空間資訊。象在托管資源腳本中的情況一樣,您需要對腳本做的唯一更改就是目标類名。

命名空間資訊作為

__NAMESPACE

類的一個靜态執行個體存儲在 CIM 中。

__NAMESPACE

類是我們前面簡要定義的靜态類類型的示例。不同于從提供程式按需檢索的動态 WMI 托管資源,靜态類執行個體存儲在 CIM 中,且無需使用WMI 提供程式而直接從 CIM 中檢索。清單 5 使用

__NAMESPACE

類來檢索并回顯所有直接在根命名空間下的命名空間。

清單 5 :使用 WMI VBScript 檢索 CIM 命名空間
strComputer = "."

Set objServices = GetObject("winmgmts://" & strComputer & "/root")
Set colNameSpaces = objServices.InstancesOf("__NAMESPACE")

For Each objNameSpace In colNameSpaces
    WScript.Echo objNameSpace.Name
Next
      
3

顯示在一台 Windows Server 2003 計算機上運作清單 5 的結果。命名空間清單會根據安裝在目标計算機上不同版本的 Windows 和 WMI 而變化。

WMI 腳本入門WMI 腳本入門
3 GetNamespaces.vbs 輸出

如您可能已經注意到的,清單 5 不提供目标計算機上所有可用的命名空間的完整描述。它隻檢索并顯示在單一的、指定命名空間下的命名空間。為了在本地或遠端的啟用 WMI 的計算機上回顯所有命名空間,您需要修改清單 5 來遞歸地連接配接到并枚舉每個命名空間。幸運的是,這不想您想象中的那麼難 — 尤其像清單 6 中展示的那樣,有我們為您做這件事的時候。

将清單 5 更改到清單 6 中所示的遞歸命名空間腳本,主要包括實作子例程内的原始腳本正文,以及提供一個機制來調用從 CIM 檢索的每個命名空間執行個體的子例程。清單 6 通過執行下列步驟完成了這個任務:

1. 清單 6 從用目标計算機的名稱初始化 strComputer 開始。WMI 中的單點 (“.”) 表示本地計算機。您可以将配置設定給 strComputer 的值更改為在您有管理控制權的域中的任何啟用 WMI 的計算機。
2. 腳本調用遞歸子例程 (EnumNameSpaces),然後傳遞給子例程一個辨別初始化命名空間連接配接到“根”的字元串。
3. EnumNameSpaces 子例程的正文除了一個重要的改變外,與清單 5 是一樣的。讓我們逐漸研究子例程。
1. EnumNameSpaces 從回顯子例程單一參數 strNameSpace 的值開始。strNameSpace 辨別了每次子例程被調用時在連接配接字元串中使用的命名空間。
2. 在 VBScript 中使用 GetObject 函數,子例程連接配接到由子例程的 strNameSpace 參數辨別的命名空間。
3. 在建立到目标計算機的 WMI 服務和命名空間的連接配接後,子例程立即在由 strNameSpace 引用的命名空間下檢索所有命名空間執行個體
4. 使用 For Each 循環,子例程立即枚舉在目前連接配接的命名空間下的命名空間執行個體。但是,并不是簡單地回顯子命名空間的名字,每個子命名空間的名稱與傳遞到 EnumNameSpaces 子例程的新調用中的目前命名空間連接配接。重複這些子例程步驟,直至枚舉了所有的命名空間執行個體。
清單 6 :使用 WMI VBScript 檢索所有 CIM 命名空間
strComputer = "."

Call EnumNameSpaces("root")

Sub EnumNameSpaces(strNameSpace)

  WScript.Echo strNameSpace

  Set objWMIService = GetObject("winmgmts://" & strComputer & "/" & strNameSpace)
  Set colNameSpaces = objWMIService.InstancesOf("__NAMESPACE")

  For Each objNameSpace In colNameSpaces
    Call EnumNameSpaces(strNameSpace & "/" & objNameSpace.Name)
  Next

End Sub
      
4

展示了在同一台 Windows Server 2003 計算機上運作清單 6 的結果。

WMI 腳本入門WMI 腳本入門
4 GetAllNamespaces.vbs 輸出

定義類的分類

如前面

1

中所示,有 3 個通用的類的分類用于構造 CIM:系統、核心與公共,以及擴充。

系統類

系統類是支援内部 WMI 配置和操作(例如,命名空間配置、命名空間安全性、提供程式注冊以及事件訂閱和通知)的類。浏覽 CIM 時,您可以通過字首在每個系統類名前的兩條下劃線輕易地識别出系統類。例如

,圖 1

中展示的

__SystemClass

__Provider

__Win32Provider

類都是系統類。在上一節中,我們研究的

__NAMESPACE

類是另一個系統類的示例。

系統類可以是抽象的或靜态的。抽象系統類是用于派生其他抽象或靜态系統類的模闆。靜态系統類定義實體存儲在 CIM 儲存庫中的 WMI 配置和操作資料。例如,

__Win32Provider

系統類定義存儲在 CIM 中的提供程式注冊資訊。CIMOM(WMI 服務)使用存儲在 CIM 中的提供程式注冊資訊,将動态托管資源的請求映射到相應的提供程式。

正如我們之前用

__NAMESPACE

系統類進行的示範,您可以使用相同的 WMI 腳本技術來檢索存儲在 CIM 中的系統類的靜态執行個體。例如,清單 7 檢索并顯示所有在 root/cimv2 命名空間中注冊的

__Win32Provider

執行個體。

清單 7 :使用 WMI VBScript 檢索在 root/cimv2 命名空間中注冊的 Win32 提供程式
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colWin32Providers = objWMIService.InstancesOf("__Win32Provider")

For Each objWin32Provider In colWin32Providers
    WScript.Echo objWin32Provider.Name
Next
      

除非您在寫一本關于 WMI 的書,否則您不太可能會在 WMI 腳本中用到系統類。有一個例外是 WMI 監視腳本。WMI 監視腳本是訂閱 WMI 事件的腳本。(事件是關心的事物已經變更為一個 WMI 托管資源的實時通知。)我們會在未來的專欄中讨論 WMI 事件訂閱和通知。

對于那些急不可耐的人,三個最常見的 WMI __Event 系統類是:

__InstanceCreationEvent

__InstanceModificationEvent

__InstanceDeletionEvent

。雖然我們還是不會在這裡讨論它們,但是您可以在 TechNet 腳本中心的監視一節中找到示範如何使用這些系統類的示例監視腳本。

核心和公共類

核心和公共類扮演了兩個角色。首先,也是最重要的,它們表現抽象類 — 系統和應用程式軟體開發人員(例如 Microsoft 的開發人員)從這些抽象類派生和建立特定技術的擴充類。其次,它們定義了特殊管理區域所共有的,但是不受限于特殊的技術或實作的資源。Distributed Management Task Force (DMTF) 定義并維護這組可以通過 CIM_ 字首來識别的核心和公共類。圖 1 中四個以 CIM_ 開頭的類是核心和公共類。

root/cimv2

命名空間中定義的大約 275 個核心和公共類中,除了幾個例外其餘全部都是抽象類。這對您來說意味着什麼呢?這意味着您将極少在 WMI 腳本中使用核心和公共類(以 CIM_ 為字首的類)。為什麼?因為您不能檢索抽象類的執行個體,抽象類隻能用作新類的基礎。因為核心和公共類中的 271 個都是抽象的,是以它們主要被軟體開發人員用來建立特定技術擴充類。

那麼,例外是什麼呢?275 個核心和公共類中的 4 個不是抽象類。它們是使用 Win32 提供程式 (cimwin32.dll) 來檢索托管資源執行個體的動态類。請記錄下來,這 4 個動态類是

CIM_DataFile

CIM_DirectoryContainsFile

CIM_ProcessExecutable

CIM_VideoControllerResolution

擴充類

擴充類是由系統和應用程式軟體開發人員建立的特定技術類。圖 1 中展示的

Win32_BaseService

Win32_Service

Win32_SystemServices

Win32_ComputerSystem

類是 Microsoft 擴充類。在

root/cimv2

命名空間中的 Microsoft 擴充類可以通過 Win32_ 字首來識别。雖然這麼說,您不應該推斷所有的 Microsoft 擴充類名都以 Win32_ 開始,因為并非如此。例如,在

root/DEFAULT

命名空間中定義的

StdRegProv

類不是以 Win32_ 為字首的,盡管事實上

StdRegProv

類是用于系統資料庫管理任務的 Microsoft 擴充類。在您問之前,我們要先說:不,我們不知道為什麼

StdRegProv

類在

root/DEFAULT

命名空間而非

root/cimv2

定義。

當我們編寫這篇文章時,在

root/cimv2

命名空間中定義了大約 463 個 Win32 擴充類。在 463 個 Win32 類中,68 個是抽象類而其餘 395 個是動态類。這對您來說意味着什麼呢?這意味着擴充類是您将要在 WMI 腳本中使用的主要的類類别。

我們提供的類統計資料是基于測試版的 Windows Server 2003,且隻想說明一般的 CIM 概念。基于個别因素,如:Windows 版本、WMI 版本以及安裝的軟體,您的數字會有所不同。

列出類

此時,我們将要告訴您的事情不應該是一個大的意外。您可以編寫一個腳本來檢索在一個命名空間中定義的所有類。例如,清單 8 列出了所有在

root/cimv2

命名空間中定義的類。但是,與前面所有使用

SWbemServices InstancesOf

方法的腳本不同,清單 8 使用一個不同的方法,即

SubclassesOf

,它也是由 WMI 腳本庫的

SWbemServices

對象提供的。

正如該方法的名稱所暗示的,

SubclassesOf

傳回一個指定父類或命名空間(當沒有提供父類的時候)的所有子類。如

InstancesOf

SubclassesOf

傳回

SWbemObjectSet

集合中的所有子類,這裡該集合中的每個項目都是一個表示單一類的

SWbemObject

清單 8 中另一個重要的不同是回顯在 For Each 循環正文中的 objClass.

Path_.Path

屬性。讓我們檢視一下 For Each 循環來了解這究竟是什麼。For Each 循環正在枚舉由

SWbemServices SubclassesOf

方法傳回的

SWbemObjectSet

(colClasses) 集合中的每個

SWbemObject

(objClass)。每個

SWbemObject

表示

root/cimv2

命名空間中的一個離散類。

這是有可能産生混淆的部分。與我們前面所有顯示由托管資源藍圖(類定義)定義的屬性的腳本不同,

Path_

是由 WMI 腳本庫的

SWbemObject

提供的屬性。要了解這一點,您要考慮使用

SWbemObject

的上下文。您在使用

SWbemObject

來通路托管資源的執行個體嗎?或者您是否在使用

SWbemObject

通路托管資源的類定義?

當您使用

SWbemObject

通路托管資源的執行個體時,您更有可能使用

SWbemObject

來通路由托管資源藍圖(類定義)定義的屬性和方法。當您使用

SWbemObject

來獲得詳細的類資訊 — 如支援的屬性、方法和限定符 — 時,您使用由

SWbemObject

自己提供的屬性和方法。

Path_

就是一個這樣的屬性。

Path_

實際上引用了另一個名為

SWbemObjectPath

的,提供

Path

屬性的 WMI 腳本庫對象。

SWbemObjectPath Path

屬性包含了到被

SWbemObject

(清單 8 中的

objClass

)引用的類的完全限定路徑。再一次提醒您,現在不要太專注于腳本對象,因為我們将在第三部分做詳細讨論。

清單 8 :使用 WMI VBScript 檢索所有在 root/cimv2 命名空間中定義的類
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colClasses = objWMIService.SubclassesOf()

For Each objClass In colClasses
    WScript.Echo objClass.Path_.Path
Next
      

在我們的 Windows Server 2003 計算機上運作清單 8 顯示出一個有 914 個類的長清單,

5

展示了它的一部分。

WMI 腳本入門WMI 腳本入門
5 GetClasses.vbs 輸出

當然,您可以通過僅僅改變一下腳本的目标命名空間而輕松地修改清單 8 來列出其他命名空間中的類。您也可以将清單 8 與 findstr.exe 指令結合使用以搜尋類。對于不熟悉 findstr.exe 指令的使用者:findstr.exe 是一個在檔案中搜尋字元串的指令行工具。

例如,假設您需要知道您正在運作的 Windows 版本是否支援新的 Windows XP 和 Windows Server 2003的

Win32_TSSessionSetting

類。可以使用下列指令行來确定

Win32_TSSessionSetting

類是否存在于

root/cimv2

命名空間中。

C:/Scripts> cscript GetClasses.vbs |findstr /I "Win32_TSSessionSetting"
      

這裡來嘗試幾個另外的方案。

列出 root/cimv2 命名空間中的所有系統類:
C:/Scripts> cscript GetClasses.vbs |findstr /I "__"
      
列出 root/cimv2 命名空間中的所有核心和公共類:
C:/Scripts> cscript GetClasses.vbs |findstr /I "CIM_"
      
列出 root/cimv2 命名空間中所有的 Win32 擴充類:
C:/Scripts> cscript GetClasses.vbs |findstr /I "Win32_"
      
列出 root/cimv2 命名空間中所有包含字元串“process”的類:
C:/Scripts> cscript GetClasses.vbs |findstr /I "process"
      

CIM 類類型定義

此時應該明顯的看出:類是 CIM 儲存庫的基本構造塊。WMI 配置資訊和 WMI 托管資源由一個或更多類進行定義。與 Active Directory 架構相似,CIM 類是按等級組織起來的,在這種組織結構中子類從父類繼承屬性、方法和限定符(目前不必過多考慮屬性、方法和限定符,我們将在下一節進行讨論)。例如,

Win32_Service

動态類是從

Win32_BaseService

抽象類繼承的;而後者是從

CIM_Service

抽象類繼承而來的;

CIM_Service

抽象類則是從

CIM_LogicalElement

抽象類繼承的;而

CIM_LogicalElement

抽象類又是從

CIM_ManagedSystemElement

抽象類繼承而來的(如

1

所示)。是托管資源的類層級中的類的總和最終定義了托管資源。

如前面提到的,有 3 個主要的類類型:抽象、靜态和動态。

抽象類

抽象類是用于定義新類的模版。如 Active Directory 架構中的抽象類,CIM 抽象類是作為其他抽象、靜态和動态類的基類。每個,嗯,差不多是每個 WMI 托管資源類的定義是從一個或更多抽象類建構(或派生)的。

您可以通過檢查類的

Abstract

限定符來識别抽象類。抽象類必須定義

Abstract

限定符并将該

Abstract

限定符的值設定為 true。本文結尾的補充清單 A 示範如何使用 WMI 腳本庫來列出所有在

root/cimv2

命名空間中定義的抽象類。

抽象類類型最常用于核心和公共類的定義。抽象類極少在 WMI 腳本中使用,這是因為您不能檢索抽象類的執行個體。

靜态類

靜态類定義實體存儲在 CIM 儲存庫中的資料。靜态類擁有與動态類一樣的執行個體,但是靜态類的執行個體存儲在 CIM 儲存庫中。同樣,靜态類執行個體是直接從 CIM 中檢索的。它們不使用提供程式。

您可以通過檢查類的限定符來識别靜态類。但是,不同于通過含有指定的限定符來識别的抽象和動态類類型,靜态類是通過不含有

Abstract

Dynamic

限定符進行識别的。

靜态類類型最常用于系統類的定義。靜态類極少在 WMI 腳本中使用。

動态類

動态類是為從提供程式動态檢索的 WMI 托管資源模組化的類。

您可以通過檢查類的

Dynamic

限定符來識别動态類。動态類必須定義

Dynamic

限定符并将

Dynamic

限定符的值設定為 true。本文結尾的補充清單 B 示範如何使用 WMI 腳本庫來列出在

root/cimv2

命名空間中定義的所有動态類。

動态類類型最常用于擴充類的定義。動态類是在 WMI 腳本中使用的最常見的類類型。

關聯類

第四種類類型稱作關聯類,也是受支援的。關聯類是描述兩個類或托管資源之間關系的抽象、靜态或動态類。

1

所示的

Win32_SystemServices

類是一個動态關聯類的示例,它描述了計算機與運作在其上的服務之間的關系。

您可以通過檢查類的

Association

限定符來識别關聯類。抽象、靜态或動态關聯類必須定義

Association

限定符并将

Association

限定符的值設定為 true。

WMI 腳本入門WMI 腳本入門

傳回頁首

剖析類

冒着聽起來像破了紀錄的風險,每個通過 WMI 可托管的硬體和軟體資源均由一個類進行定義。一個類就是一個離散的 WMI 托管資源的藍圖(或模闆),且資源的所有執行個體都使用這個藍圖。類表示計算機所擁有的東西。因為計算機擁有諸如磁盤、事件日志、檔案、檔案夾、記憶體、列印機、程序、處理器、服務等東西,WMI 就有針對磁盤、事件日志、檔案、檔案夾、記憶體、列印機、程序、處理器、服務等的類。盡管也有例外(如 __Event 抽象系統類),但腳本中使用的大多數類都能夠直接聯系到實際的、活動的物質。

這些所謂的藍圖是由屬性、方法 和限制符 組成的。在研究屬性、方法和限制符之前,讓我們簡要地讨論一下托管資源類定義的起源。

假設 Microsoft 決定要建立一個新的、系統管理者可以用來管理和監視 Microsoft DNS 伺服器的 WMI 提供程式。DNS 提供程式開發小組至少需要建立兩個檔案:一個提供程式和一個托管對象格式 (MOF) 檔案。

提供程式是擔當 WMI 基礎結構與基礎托管資源(在本例中,即 Microsoft DNS 伺服器)之間的中間方的動态連結庫。提供程式通過調用托管資源的本地 API 來響應 WMI 請求。

MOF 檔案包含描述由 DNS 提供程式提供的功能的類定義。MOF 檔案利用為通常與 DNS 伺服器關聯的資源模組化的類描述 DNS 提供程式的功能。在 DNS MOF 檔案中定義的每個類都定義資料(屬性) — 這些資料和屬性與指定的 DNS 相關資源、以及在此資源上您可以執行的操作(方法)相關聯。

安裝 DNS 提供程式之後,DNS 提供程式動态連結庫就注冊到作業系統和 WMI,而 DNS MOF 檔案則經曆了一個編譯過程,該過程将 DNS 提供程式的類定義加載到 CIM 儲存庫。此時,DNS 提供程式可以供任何啟用 WMI 的使用者(包括腳本)使用。

雖然我們的故事是真實的 — Microsoft 為 Windows Server 2003 開發了一個新的 DNS 提供程式,但所能得到的重要的東西就是托管資源類定義來自 MOF 檔案。MOF 檔案對 WMI 來說及如同 MIB 檔案之于 SNMP.

MOF 檔案是基于由 Distributed Management Task Force (DMTF) 建立和維護的 MOF 語言的文本檔案。如圖 6 所示,每個托管資源的類定義都遵守定義完善的結構和文法。

WMI 腳本入門WMI 腳本入門
6 :托管資源類定義的結構

6

所示,每個托管資源類定義都是由屬性、方法 和限定符 組成的。

屬性

屬性是描述托管資源的名詞。類使用屬性來描述諸如辨別、配置和托管資源狀态等。例如,服務有名稱、顯示名稱、描述、啟動類型和狀态。

Win32_Service

類也有相同的東西。

每個屬性都有名稱、類型和可選的屬性限定符。與前面清單 1 中示範的方法一樣,将屬性名與 WMI 腳本庫的

SWbemObject

一起使用來通路托管資源的屬性。

方法

方法是在托管資源上執行一個操作的動詞。您可以對服務做些什麼呢?好,您可以啟動它們、停止它們、暫停它們或繼續它們。結果是有允許您啟動、停止、暫停和繼續服務的方法。沒有什麼不可思議的。

每個方法都有名稱、傳回類型、可選參數和可選的方法限定符。與屬性一樣,将方法的名稱與 WMI 腳本庫的

SWbemObject

結合使用來調用方法。

不是所有的類都定義方法。

限定符

限定符是提供關于類、屬性或方法的附加資訊到其所應用的事物的形容詞。例如,問題“

Win32_Service

類的類型是什麼?”是由該類的

Dynamic

限定符來回答的。當您開始編寫不隻是簡單地檢索資訊的 WMI 腳本(例如,修改屬性或調用方法)時,限定符變得愈加重要,因為它們定義了您正在更新的屬性或正在調用的方法的操作特性。那麼限定符提供哪種資訊呢?

類限定符

類限定符提供了關于類的操作資訊。例如:

如您之前了解的, Abstract Dynamic Association 限定符會告訴您類類型。
Provider 限定符告訴您服務這個類的提供程式。例如, Win32_Service 類的 Provider 限定符告訴您這個類使用 CIMWin32 提供程式 (cimwin32.dll)。另一方面,如由 Win32_NTLogEvent 類的 Provider 限定符表明的那樣, Win32_NTLogEvent 類使用 MS_NT_EVENTLOG_PROVIDER 提供程式 (ntevt.dll)。
Privileges 限定符告訴您要使用這個類所需要的專用特權。例如, Win32_NTLogEvent 類的 Privileges 限定符告訴您在 Win32_NTLogEvent 類可以用來管理安全日志前,SeSecurityPrivilege 必須被啟用。

屬性限定符

屬性限定符提供關于每個屬性的資訊。例如:

CIMType 限定符告訴您屬性的資料類型。
Read 限定符指出這個屬性是可讀的。
Write 限定符指出您是否可以修改屬性的值。例如,我們在清單 4 中修改的 Win32_WMISetting 類的 ASPScriptDefaultNamespace 屬性被标記為可寫。另一方面,清單 1 中回顯的所有 Win32_Service 屬性都被定義為隻讀 — 就是說,它們不定義 Write 限定符。
Key 限定符指出該屬性是類的密鑰,并且用于識别在相同資源集合中的托管資源的唯一執行個體。

方法限定符

方法限定符提供關于每個方法的資訊。例如:

Implemented 限定符表明這個方法有一個由提供程式提供的實作。
ValueMap 限定符為方法參數或傳回類型定義了一組允許的值。
Privileges 限定符告訴您調用這個方法所需的專用特權。

有比這裡所提到的更多的限定符。有關完整的清單,參閱 WMI SDK 中的 WMI Qualifiers 主題。

7

所示,您可以使用 WMI 測試器 (wbemtest.exe) 工具來檢查類的屬性、方法和限定符。當然,您也可以用 WMI 腳本庫來檢索相同的資訊,不久您就會看到。

WMI 腳本入門WMI 腳本入門
7 :使用 WMI 測試器 (wbemtest.exe) 檢視 Win32_Service

比較類與托管資源

大部分 WMI 屬性和方法是合理命名的。例如,如

8

所示,如果您将由

Win32_Service

類定義的屬性和方法與服務的屬性對話框相比,就不難推斷出

Win32_Service.Name

Win32_Service.DisplayName

Win32_Service.Descritpion

可能會包含什麼。

WMI 腳本入門WMI 腳本入門
8 :服務屬性對話框與 Win32_Service 類屬性及方法

那麼我們為什麼要關心所有這些内容?因為類決定了您能夠(或不能)用 WMI做什麼。如果有一個服務的類,您就可以管理服務;如果沒有,您就不能這樣做。屬性和方法是很重要的,這是因為 WMI 的版本在作業系統間是有差別的。Windows XP 中的

Win32_ComputerSystem

類有很多新的屬性和方法,而它們在 Windows 2000 中的

Win32_ComputerSystem

類中是沒有的。您必須知道 WMI 的詳細資訊,因為不同于 ADSI,為了讓工作順利進行,WMI 屬性和方法必須可用于目标計算機。

如何确定一台遠端 Windows 計算機是否支援某個屬性或方法?請檢查類定義。

檢索類定義

與 WMI 中所有東西一樣,有無數方法可以檢索托管資源的類定義。好吧,也許我們有點誇張了,但是也足以說,有許多為每個使用者界面首選項提供解決方案的方法。如果您想要檢索文本檔案,隻需分割 MOF 檔案。如果您更喜歡指令行,就使用 WMI 指令行工具 wmic.exe(僅限 Windows XP)。如果您樂于将時間花在圖形化工具上,就使用 WMI 測試器 (wbemtest.exe) 或 CIM Studio。或者如果您喜歡我們,就使用 WMI 腳本庫。

使用 WMI 腳本庫,您可以通過三種不同的方法檢索托管資源類定義。

1. 您可以使用 SWbemObject Qualifiers_ Properties_ Methods_ 屬性檢索類資訊。
2. 您可以使用 SWbemObject GetObjectText_ 方法來檢索以 MOF 文法格式化的類定義。
3. 您可以使用 SWbemObjectEx GetText_ 方法來檢索以 XML 格式化的類定義(僅限 Windows XP 和 Windows Server 2003)。

讓我們簡要地看看每個腳本方案,就此結束今天的内容。

使用 SWbemObject Properties_、Methods_ 和 Qualifiers_

清單

9、10 和 11 示範了如何使用 WMI 腳本庫的

SWbemObject

Properties_

Methods_

Qualifiers_

屬性來檢索關于

Win32_Service

類的資訊。我們将研究清單 9,然後指出清單 10 和清單 11 中的不同之處,因為三個腳本使用了相同的基本方法。

清單 9 從初始化三個變量開始,它們是:strComputer、strNameSpace 和 strClass 配置設定給 strComputer 的值是啟用了 WMI 的目标計算機。配置設定給 strNameSpace 的值是要連接配接到的命名空間。配置設定給 strClass 的值是在目标命名空間中的類的名稱,此命名空間的屬性将被檢索和顯示。将這三個值分開到多個變量中會使其他計算機、命名空間和類對腳本的重新使用變得簡單。事實上,您可以用 Windows 腳本宿主 (WSH) 參數集合輕松地将清單 9 轉換到指令行腳本。

接下來,這個腳本使用 VBScript 的

GetObject

函數連接配接到目标計算機上的 WMI 服務。注意傳遞到

GetObject

的連接配接字元串有什麼不同?除了指定目标命名空間之外,類名也要進行指定,這對

GetObject

和 WMI 腳本庫傳回的内容有深遠影響。如在我們前面的所有腳本,

GetObject

傳回一個對表示目标類的

SWbemObject

的引用,而不是傳回對

SWbemServices

對象的引用。為什麼?答案在于對象路徑。雖然我們在第三部分中會詳細讨論對象路徑,但是這裡我們還是給您一個概要的解釋來幫助您了解清單 9 到清單 11(以及補充清單 C)中到底在進行些什麼。

每個 WMI 類和每個 WMI 托管資源執行個體都有一個對象路徑。将對象路徑了解為一個檔案的完全限定路徑的 WMI 版本。每個檔案都有一個完全限定路徑,它由裝置名稱,後跟 0 或更多目錄名稱,再加上檔案名組成。同樣,每個類和托管資源也都有一個對象路徑,它由啟用了 WMI 的計算機名稱,後跟 CIM 命名空間,後跟托管資源類名,後跟類的 key 屬性以及 key 屬性的值組成,如下所示。(注意,方括号隻為了厘清一個對象路徑的四個許可部分,它們并不是對象路徑的一部分。)

[//ComputerName][/Namespace][:ClassName][.KeyProperty='Value']
      

當您在傳遞到

GetObject

的連接配接字元串中使用全部或部分的對象路徑時(順便說一下,這就是我們一直在做的),您使用的對象路徑确定了由

GetObject

和 WMI 腳本庫傳回的引用類型。例如,如果隻包含了對象路徑的計算機名稱部分,您就會獲得一個連接配接到預設命名空間的

SWbemServices

對象引用。如果包含了計算機名稱和/或命名空間,您也會獲得對

SWbemServices

對象的引用。如果包含了計算機名稱、命名空間和類名,您将會獲得對表示這個類的

SWbemObject

的引用。如果包含了所有四個部分,您将會獲得表示由類、密鑰和值識别的托管資源執行個體的

SWbemObject

。再次提醒,我們會在本系列的第三部分更詳細地讨論對象路徑。現在,了解清單 9 中的 objClass 是對表示

Win32_Service

類的

SWbemObject

的引用。

腳本的剩餘部分相當簡明易懂。在回顯一個簡單的、辨別其屬性将被顯示的類名的标題後,腳本使用從

GetObject

傳回的

SWbemObject

引用 (objClass) 來通路

SWbemObject Properties_

屬性 (

objClass.Properties_

)。

SWbemObject Properties_

屬性引用了一個

SWbemPropertySet

,它是對這個類的屬性的集合。

SWbemPropertySet

集合中的每個屬性都是一個

SWbemProperty

(objClassProperty) 對象,我們用其讀取并回顯每個屬性的名稱。

概括地說,For Each 循環枚舉了類的

SWbemPropertySet

集合(通過

SWbemObject Properties_

屬性)并回顯

SWbemPropertySet

集合中每個

SWbemProperty

Name

屬性。

清單 9 :使用 SWbemObject Properties_ 檢索 Win32_Service 屬性
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Set objClass = GetObject("winmgmts://" & strComputer & _
                         "/" & strNameSpace & ":" & strClass)

WScript.Echo strClass & " Class Properties"
WScript.Echo "------------------------------"

For Each objClassProperty In objClass.Properties_
    WScript.Echo objClassProperty.Name
Next
      
9

顯示由

Win32_Service

類定義(或繼承)的 25 個屬性的名稱。

WMI 腳本入門WMI 腳本入門
9 GetProperties.vbs 輸出

除了一個顯著的例外,清單 10 與清單 9 是相同的。For Each 循環枚舉類的

SWbemMethodSet

集合(通過

SWbemObject Methods_

屬性),并回顯

SWbemMethodSet

集合中每個

SWbemMethod

(objClassMethod) 的

Name

屬性。

清單 10 :使用 SWbemObject Methods_ 檢索 Win32_Service 方法
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Set objClass = GetObject("winmgmts://" & strComputer & _
                         "/" & strNameSpace & ":" & strClass)

WScript.Echo strClass & " Class Methods"
WScript.Echo "---------------------------"

For Each objClassMethod In objClass.Methods_
    WScript.Echo objClassMethod.Name
Next
      
10

顯示由

Win32_Service

類定義(或繼承)的 10 個方法的名稱。

WMI 腳本入門WMI 腳本入門
10 GetMethods.vbs 輸出

除了三點例外,清單 11 與清單 9 和 清單10 相同。

1. For Each 循環枚舉類的 SWbemQualifierSet 集合(通過 SWbemObject Qualifiers_ 屬性),并回顯 SWbemQualifierSet 集合中每個 SWbemQualifier (objClassQualifier) 的 Name 屬性。
2. 因為類限定符是類定義的一部分而且限定符有值,清單 11 也檢索并回顯 SWbemQualifierSet 集合中每個 SWbemQualifier (objClassQualifier) 的 Value 屬性。
3. 因為一個限定符可以有多個存儲在數組中的值,清單 11 必須在讀取限定符的值前說明此點。如果不這麼做,如果腳本試圖将一個基于數組的限定符作為标量變量來讀取,将會導緻運作時錯誤。 Win32_NTLogEvent 類的 Privileges 限定符是一個基于數組的限定符執行個體。
清單 11 :使用 SWbemObject Qualifiers_ 檢索 Win32_Service 類限定符
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Set objClass = GetObject("winmgmts://" & strComputer & _
                         "/" & strNameSpace & ":" & strClass)

WScript.Echo strClass & " Class Qualifiers"
WScript.Echo "------------------------------"

For Each objClassQualifier In objClass.Qualifiers_
    If VarType(objClassQualifier.Value) = (vbVariant + vbArray) Then
        strQualifier = objClassQualifier.Name & " = " & _
                       Join(objClassQualifier.Value, ",")
    Else
        strQualifier = objClassQualifier.Name & " = " & _
                       objClassQualifier.Value
    End If
    WScript.Echo strQualifier
    strQualifier = ""
Next
      
11

顯示由

Win32_Service

類定義(或繼承)的 5 個類限定符的名稱和值。

WMI 腳本入門WMI 腳本入門
11 GetClassQualifiers.vbs 輸出

如您可能已經注意到的,清單 9 和清單 10 無法顯示屬性和方法限定符。說實話,這是故意讓腳本保持在一個容易了解的大小。好消息是,在本專欄的結尾我們已經加入了完整的類限定符、屬性、屬性限定符、方法和方法限定符腳本(見補充清單 C)。歡迎參閱。

萬一這不是很明顯,您可以把清單 9、10、11 與清單 6(GetAllNamespaces.vbs 腳本)和清單 8(GetClasses.vbs 腳本)組合在一起來檢索在 CIM 中定義的每個類的屬性、方法和限定符。在使用所産生的帶有 findstr.exe 指令的腳本,您會得到一個解決方案來搜尋在 CIM 中定義的任何類、屬性、方法或限定符。

使用 SWbemObject GetObjectText_

在前面我們說過,您可以直接從 MOF 檔案(包含類的定義)中檢索管理資源類定義。例如,如果您想要查找

Win32_Service

類,可以檢視 %SystemRoot%/system32/wbem/cimwin32.mof 檔案。但是,直接使用 MOF 檔案是有代價的。您必須檢查托管資源的類層次結構中的每個類,以獲得完整的托管資源藍圖。

比如說,您想要查找

Win32_Service

。您就不得不檢查

Win32_Service

類層次結構中所有的 5 個類,以獲得完整的藍圖,如圖 1 所示,。如果您使用 WMI 測試器 (wbemtest.exe) 的 Show MOF 按鈕(見圖 7),也是同樣。獲得類的 MOF 表示形式的較簡單方法是使用 WMI 腳本庫的

SWbemObject GetObjectText_

方法,如清單 12 中示範的。

與清單 9 到 11 不同,清單 12 使用

SWbemServices Get

方法來檢索類,而不使用

GetObject

。必須使用

SWbemServices Get

方法,這樣才能啟用

wbemFlagUseAmendedQuailifiers

标志。啟用

wbemFlagUseAmendedQuailifiers

标志,告訴 WMI 傳回整個托管資源藍圖(類定義)而不僅僅是本地的定義。

使用

wbemFlagUseAmendedQualifiers

标記還有第二個好處。您也取回了類描述,以及對每個類的屬性、方法和限定符的描述。類、屬性、方法和限定符描述通常在一個本地化目的、單獨的 MOF 檔案中定義。例如,

Win32_Service

類的中性語言部分是在 cimwin32.mof 中定義的。

Win32_Service

類的特定語言部分,包括描述資訊,是在 cimwin32.mfl 中定義的。特定語言的(或本地化的) MOF 檔案通常帶有一個 .mfl(而非 .mof)擴充名。

SWbemServices Get

方法傳回對表示目标類的

SWbemObject

(objClass) 的引用,它用于調用

SWbemObject GetObjectText_

方法。

GetObjectText_

方法傳回該類的 MOF 表示形式。如果我們使用了

GetObjectText_

而沒有啟用

wbemFlagUseAmendedQuailifiers

标記,這個方法将隻傳回那些由 Win32_Service 定義的屬性、方法和限定符,繼承的屬性和方法會被省略。

12 :使用 SWbemObject GetObjectText_ 來檢索 Win32_Service 類的 MOF 表現形式
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Const wbemFlagUseAmendedQualifiers = &h20000


Set objWMIService = GetObject("winmgmts://" & strComputer & "/" & strNameSpace)
Set objClass = objWMIService.Get(strClass, wbemFlagUseAmendedQualifiers)
strMOF = objClass.GetObjectText_

WScript.Echo strMOF
      

不過,對于使用

GetObjectText_

有一個限定:沒有關于在包含在由該方法傳回的 MOF 文法中的繼承限定符的資訊。當

Key

限定符在一個父類的屬性中定義時,如果您想要使用

GetObjectText_

來确定一個類的

Key

屬性,這可能會帶來問題。

使用 SWbemObjectEx GetText_

Windows XP 和 Windows Server 2003 都包含一個名為

GetText_

的新方法,它可以用于檢索托管資源類定義的 XML 表現形式。

除了一個明顯的例外,使用

GetText_

與使用

GetObjectText_

類似:傳遞到

GetText_

方法的三個參數。

第一個參數是必需的,它辨別所産生的 XML 格式。它目前可以是作為由 WMI

WbemObjectTextFormatEnum

定義的兩個值中的一個:

wbemObjectTextFormatCIMDTD20

(值:1)或

wbemObjectTextFormatWMIDTD20

(值:2)。值 2 (

wbemObjectTextFormatWMIDTD20

) 告訴

GetText_

根據 Distributed Management Task Force CIM 文檔類型定義 (DTD) 2.0 版本的擴充 WMI 版本格式化所産生的 XML。

第二個參數是可選的,并且目前是為操作标記保留的。它必須被設定為 0(零)。

第三個參數 colNamedValueSet(也是可選的),是一個為

GetText_

提供特殊說明的

SWbemNamedValueSet

集合。這裡,我們讓

GetText_

進行:

檢索并編碼所有屬性和方法,不僅僅是本地定義的屬性和方法。
包含所産生的 XML 中的類限定符、屬性限定符和方法限定符。
包含所産生的 XML 中的系統屬性。
包含對所有屬性和方法的類起源。
清單 13 :使用 SWbemObjectEx GetText_ 來檢索 Win32_Service 類的 XML 表現形式(僅限 Windows XP Windows .NET
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Const wbemFlagUseAmendedQualifiers = &h20000

Const wbemObjectTextFormatWMIDTD20 = 2

Set objWMIService = GetObject("winmgmts://" & strComputer & "/" & strNameSpace)
Set objClass = objWMIService.Get(strClass, wbemFlagUseAmendedQualifiers)

Set colNamedValueSet = CreateObject("Wbemscripting.SWbemNamedValueSet")
colNamedValueSet.Add "LocalOnly", False
colNamedValueSet.Add "IncludeQualifiers", True
colNamedValueSet.Add "ExcludeSystemProperties", False
colNamedValueSet.Add "IncludeClassOrigin", True

strXML = objClass.GetText_(wbemObjectTextFormatWMIDTD20, 0, colNamedValueSet)

WScript.Echo strXML
      

為了成功運作清單 13,将腳本複制并粘貼到您最常用的文本編輯器中,儲存腳本(擴充名為 .vbs,例如:GetXML.vbs),然後使用下面列出的指令行運作腳本。

C:/Scripts> cscript //nologo GetXML.vbs >Win32_Service.xml
      
12

顯示所生成的 XML 檔案,Win32_Service.xml,使用 Microsoft Internet Explorer。

WMI 腳本入門WMI 腳本入門
12 GetXML.vbs 輸出
WMI 腳本入門WMI 腳本入門

傳回頁首

就到這裡吧

如果對 WMI 有任何疑惑、困難或不知所措,那可能是在處理由 WMI 公布的大量資料。我們願意認為,我們已經為您裝備了有效地尋找并解釋 WMI 托管資源類定義所必需的知識和工具。當然,對于這一點您是最好的裁判,是以請盡量讓我們知道我們是否以及有哪些不足。枯燥的内容結束了,準備在我們投入到 WMI 腳本庫的詳細資訊時在第三部分玩得開心點吧。哦,不管怎麼樣,随意打發剩下的時間吧。

等一下!在您打包走人之前,還有最後一個要注意的地方:WMI 開發小組讓我們告訴您,以前隻能随 WMI SDK 使用的 WMI 工具,現在已經進行了更新。更新的工具(包括 WMI CIM Studio、WMI 事件注冊、WMI 事件檢視器 和 WMI 對象浏覽器),現在都與 Windows XP 和 Windows Server 2003 以及 Windows 2000 相容。此外,更新的工具不包含 WMI SDK,這意味着現在您可以安裝這些工具而不必安裝整個 WMI SDK。這難道不是非常酷麼?

WMI 腳本入門WMI 腳本入門

傳回頁首

補充腳本

清單 A :列出在 root/cimv2 命名空間中定義的抽象類類型
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colClasses = objWMIService.SubclassesOf()

For Each objClass in colClasses
    For Each objClassQualifier In objClass.Qualifiers_
        If LCase(objClassQualifier.Name) = "abstract" Then
            WScript.Echo objClass.Path_.Class   & ": " & _
                         objClassQualifier.Name & "="  & _
                         objClassQualifier.Value
        End If
    Next
Next
清單 B:列出在 root/cimv2 命名空間中定義的動态類類型
strComputer = "."

Set objWMIService = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colClasses = objWMIService.SubclassesOf()

For Each objClass in colClasses
    For Each objClassQualifier In objClass.Qualifiers_
        If LCase(objClassQualifier.Name) = "dynamic" Then
            WScript.Echo objClass.Path_.Class   & ": " & _
                         objClassQualifier.Name & "="  & _
                         objClassQualifier.Value
        End If
    Next
Next
      
清單 C :使用 SWbemObject Qualifiers_ Properties_ Methods_ 檢索類限定符、屬性、屬性限定符、方法和方法限定符
strComputer = "."
strNameSpace = "root/cimv2"
strClass = "Win32_Service"

Set objClass = GetObject("winmgmts://" & strComputer & _
                         "/" & strNameSpace & ":" & strClass)

WScript.Echo strClass & " Class Qualifiers"
WScript.Echo "------------------------------"
i = 1
For Each objClassQualifier In objClass.Qualifiers_
    If VarType(objClassQualifier.Value) = (vbVariant + vbArray) Then
        strQualifier = i & ". " & objClassQualifier.Name & " = " & _
                                  Join(objClassQualifier.Value, ",")
    Else
        strQualifier = i & ". " & objClassQualifier.Name & " = " & _
                                  objClassQualifier.Value
    End If
    WScript.Echo strQualifier
    strQualifier = ""
    i = i + 1
Next

WScript.Echo
WScript.Echo strClass & " Class Properties and Property Qualifiers"
WScript.Echo "------------------------------------------------------"
i = 1 : j = 1
For Each objClassProperty In objClass.Properties_
    WScript.Echo i & ". " & objClassProperty.Name
    For Each objPropertyQualifier In objClassProperty.Qualifiers_
        If VarType(objPropertyQualifier.Value) = (vbVariant + vbArray) Then
            strQualifier = i & "." & j & ". " & _
                           objPropertyQualifier.Name & " = " & _
                           Join(objPropertyQualifier.Value, ",")
        Else
            strQualifier = i & "." & j & ". " & _
                           objPropertyQualifier.Name & " = " & _
                           objPropertyQualifier.Value
        End If
        WScript.Echo strQualifier
        strQualifier = ""
        j = j + 1
    Next
    WScript.Echo
    i = i + 1 : j = 1
Next

WScript.Echo
WScript.Echo strClass & " Class Methods and Method Qualifiers"
WScript.Echo "-------------------------------------------------"
i = 1 : j = 1
For Each objClassMethod In objClass.Methods_
    WScript.Echo i & ". " & objClassMethod.Name
    For Each objMethodQualifier In objClassMethod.Qualifiers_
        If VarType(objMethodQualifier.Value) = (vbVariant + vbArray) Then
            strQualifier = i & "." & j & ". " & _
                           objMethodQualifier.Name & " = " & _
                           Join(objMethodQualifier.Value, ",")
        Else
            strQualifier = i & "." & j & ". " & _
                           objMethodQualifier.Name & " = " & _
                           objMethodQualifier.Value
        End If
        WScript.Echo strQualifier
        strQualifier = ""
        j = j + 1
    Next
    WScript.Echo
    i = i + 1 : j = 1
Next
      
Scripting Clinic Greg Stemp

長期以來被公認為美國國内的腳本編寫權威之一,并且被大家廣泛譽為世界級……哈哈!嗯,他們 的履曆表中怎麼都當過足球教練?真的嗎?他被解雇 了?哦,好吧。Greg Stemp 工作在……哦,好了,難道我連這都不能說嗎?好吧!Greg Stemp 從 Microsoft 領薪水,在那兒他擁有并不顯赫的首席作家(System Administration Scripting Guide)的頭銜。

Dean Tsaltas

是一個生活在 Redmond 的 Nova Scotian 人。他已經開始說一口流利的美語了,甚至會笑他的濱海省的朋友和家人們的發音。他的計算機生涯開始于他很小的時候,那時他的祖母和父母資助他,為他買了他心愛的 C-64,并為他訂閱了 Compute! 的學報。現在,他已經在 Microsoft 工作了若幹年,他有句話要告訴在家鄉和溫哥華的朋友和家人:“沒有,我還沒見過比爾!”

Bob Wells

漫無目的地四處遊走,向每個聽他說話的人大贊腳本編寫的好處。有傳言說,Bob 的兩隻達克思獵犬對腳本編寫比大多數人類知道的都多。業餘時間裡,Bob 向 System Administration Scripting Guide 投稿。

Ethan Wilansky

把他的很多的工作時間花在了寫作和咨詢方面。他狂熱于腳本編寫、瑜伽、園藝和他的家庭(不一定按此順序)。他目前正緻力于一種建立能倒垃圾和洗餐盤的腳本的方法。

繼續閱讀