天天看點

WMI的基礎介紹在vbs中的使用方式

◎WMI輕松入門之一

一、基本概念

其實我給文章起這樣的名字,絕對沒有輕視WMI的意思,事實上就連微軟也有“WMI非常難于學習而且更難于使用”的說法,在近日的學習過程中更感覺到了WMI檢索功能的強大,之是以起個“輕松入門”的名字,我隻是有感于外國人寫教程在思路上和國人不太一緻,西方式的幽默看起來困難無比,再加上一上手就在類的基本結構上展開讨論,吓跑了無數Vbs的愛好者,想從國人常見的角度出發來說說怎麼學習WMI而已。百度空間的長度限制太讨厭了,一次發不完,隻好分割成三部分,題目隻能大緻起了,見諒。

一、什麼是WMI?微軟有很多說法,大家可以到腳本中心查閱,我這樣了解,WMI是一個用于管理Windows系統資源的對象,其内部應是一個樹狀的資料庫,資料庫中包含了很多個分支,每個分支被稱作命名空間,每個命名空間包含了很多個對托管資源的抽象定義,這種定義叫做類。在很多計算機教材中喜歡把類比作建築藍圖,依據藍圖建造的樓宇叫做類的執行個體,我更喜歡将類和其執行個體的關系比作表格,類就是表格的字段定義,而表中的資料就是一個個的類的執行個體,也許我這樣說會讓很多朋友更加糊塗,

但是依此類推,WMI中最終存在的是各種軟硬體資源的抽象定義,我們利用WMI,就是要按圖索骥,通過類定義,獲得類執行個體,檢索出符合要求的屬性,調用其内置的方法,實作我們的目标。相信很多朋友已經發現,我将WMI等同于CIM庫了,我清楚他們不是一回事,但我相信這樣更容易了解。如圖:

二、WMI的基本結構

嚴格說來,WMI由四部分組成:

1、 公共資訊模型對象管理器——CIMOM

2、 公共資訊模型——CIM

3、 WMI提供程式

4、 WMI腳本對象庫

其中其第1、2、3三個部分,在使用中很少加以差別,我們一般統稱為CIM庫。

是以我們可以認為WMI實際是由兩部分組成:CIM庫和WMI腳本對象庫。在具體使用過程中,我們是通過WMI腳本對象庫去通路CIM庫,管理托管的資源。也就是說,在我們編寫腳本的過程大緻可以分為這麼幾步:

1、 建立WMI對象腳本庫的指針執行個體;

2、 調用其執行個體的方法,連接配接到CIM庫,并指明需要通路的資源的邏輯位置;

3、 獲得托管資源也就是類的執行個體的集合;

4、 枚舉執行個體,完成工作。

這幾個步驟在我們将來編寫的代碼中可以明确的反映出來。

三、常用的命名空間

命名空間是個很複雜的概念,相信在微軟的網站上一定有很多的篇幅介紹這個概念,據我個人了解,命名空間是對類所處邏輯位置的一個約定。打個比方說:張家也有個孩子叫小強,李家也有個孩子小強。大家站在一起,你大聲叫"小強",你說這到底是叫哪一個小強呢?張家,李家都是一個姓,一個人的姓實際上就是現實中的一種名字空間。好了,現在你大聲叫“張小強”,我們就明确的知道你到底是叫哪一個小強了。這就好比在變量名前加上名字空間字首。是以可以通俗的說,名字空間就是一個變量的姓氏。問題是這樣我們還會碰到一個問題,世界上有很多姓張的,也有可能有很多的張小強,這怎麼辦呢?這時候我們可以這樣說"張老三家的小強",張是一個名字空間,張老三又是張下面的二級名字空間.

張.老三的家.小強 = 110

張.三豐的家.小強= 119

也許說的更糊塗,但大緻就這樣吧,我本來也就不是說明這個的。

據微軟稱,WMI的命名空間共有16個,不過不用擔心,我們常用的隻有兩個:

1、 root\cimv2 在這個命名空間裡包括了絕大多數與計算機、作業系統相關聯的類。

2、 root\default 管理系統資料庫的類

在使用中,我們用一個字元串表示命名空間,就像檔案路徑一樣。

四、常用的腳本對象庫

WMI腳本對象庫由24個對象組成,在腳本中心有一副腳本庫對象模型的圖,有興趣的朋友可以參考一下,作為入門,我們一般隻用到其中的四個對象,其繼承和層級關系如下:

SwbemLocator教本庫對象→SwbemServicesWMI服務對象→SwbemObjectSet類執行個體集合對象→SwbemObject類的執行個體

好了,現在讓我們來舉個例子,詳細說明一下這四個對象在腳本中的應用方法:

例一:用來檢索計算機上安裝的光驅:

strComputer = "."

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")

Set objSWbemServices = objSWbemLocator.ConnectServer

Set colItems = objSWbemServices.ExecQuery("Select * from Win32_CDROMDrive")

For Each objItem in colItems

WScript.Echo "CD光牒驅動器的類型: " & objItem.Caption

WScript.Echo "盤符是: " & objItem.Id

Next

例二:用來檢索CPU型号

Set objSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Processor")

For Each objSWbemObject In objSWbemObjectSet

Wscript.echo "CPU的型号為:" & objSWbemObject.name

請注意,這兩個腳本雖然簡單,卻代表了WMI腳本設計中最普遍的東西,可以說是很典型的腳本。讓我們來仔細觀察一下這兩個腳本,讨論讨論一下腳本通路WMI的基本方法:我們可以看到整個腳本的執行過程基本相同:

①定義了SwbemLocator的執行個體;SwbemServices、SwbemObjectSet、SwbemObject對象;建立了SwbemLocator的執行個體;②通過SwbemLocator的ConnectServer方法連接配接到WMI,獲得SwbemServices的執行個體集合;③枚舉集合中的每個執行個體;④顯示各執行個體的一些屬性。

讓我們來詳細說明一下各行代碼的詳細含義,并請仔細回想我們第二部分WMI基本結構中談到的編寫WMI腳本的基本步驟:(注意:考慮到腳本的簡易,我們編寫的腳本一般隻在本地計算機進行檢索,我們隻介紹涉及本地的這一部分,涉及到通路遠端計算機的部分我們就省略了,其實随着計算機安全技術的發展,僅憑WMI通路遠端計算機的可行性是越來越小了)

1、連接配接到指定的CIM命名空間

要用WMI對象程式設計,必須首先建立WMI對象腳本庫的執行個體,連接配接到目标計算機的CIM命名空間。

方法一:

步驟一、建立SwbemLocator對象的執行個體。代碼為:

然後用SwbemLocator對象的ConnectServer方法(SwbemLocator對象隻有1個隻讀屬性Security_和1個方法ConnectServer)建立WMI服務的連接配接,傳回一個命名空間的連接配接(SwbemServices對象),代碼為:

Set objSWbemServices = objSWbemLocator.ConnectServer()

ConnectServer方法共有8個參數,所有參數都是可選的,其參數格式如下:

ConnectServer([strComputName],[strNamespace],[strUser],[strPassword],[strLocale],[strAuthority],[iSecurityFlags],[objwbemNamedValueSet])

考慮到WMI的複雜性,在使用中我們如果隻是在本地計算機上進行檢索和查詢,那麼我們隻需要設定第1、2個參數,其它參數都可以省略;如果想連接配接到遠端計算機,一般需要對前4個參數進行設定,我們也隻對此做個簡單的介紹。

strServer——計算機名,預設為本機,本機也可以用”.”

strNamespace——需要登入的CIM命名空間,例如:"root\CIMV2",預設為"root\CIMV2"。

方法二:用moniker名字法建立WMI服務的連接配接,這也是微軟推薦的連接配接方法

moniker名字法是利用GetObject函數直接建立WMI服務的連接配接,它的要點就是通過編寫一個moniker字元串作為GetObject函數的參數,然後傳回一個SwbemServices對象。

關于moniker字元串的完整格式如下:

"winmgmts:[{SecuritySettings}!][\\ComputerName][\Namespace][:ClassName][.KeyProperty='Value']"

"winmgmts:"是字首,

表示為WMI服務,必須使用;第二部分用來驗證權限和假冒級别的,省略。第三部分為計算機名字:"\\.\"是計算機名字,預設可省略,其餘同上;第四部分CIM命名空間:預設的命名空間為"root\CIMV2",預設可省略。

第五部分為類名。第六部分為屬性值。注意:當該moniker字元串不包括最後2項時(即為:"winmgmts:[\\ComputerName][\Namespace]"),則GetObject(moniker字元串)傳回的是一個命名空間的已驗證的連接配接(SwbemServices對象);當不包括最後1項時,傳回的是一個CIM類(SWbemObject對象);當包括最後2項時,傳回的是一個類的單獨執行個體(SWbemObject對象)。

2.獲得類的執行個體

我們有4種方法獲得類的執行個體,其中方法1和方法2是通過SwbemServices對象的InstancesOf方法和ExecQuery方法來獲得某個類的多個執行個體組成的集合對象。方法3和方法4則是傳回單獨的類的執行個體,即傳回的是一個SWbemObject對象。

1)InstancesOf方法獲得類的執行個體集合

InstancesOf方法的文法參數格式如下:

SwbemServices.InstancesOf(strClass)

strClass為類名,例如"Win32_Service"

回顧例二,就是用語句:Set objSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Processor

") 來獲得"Win32 Processor "類的所有執行個體集合,然後我們可以用

……

語句獲得每一個類的執行個體SWbemObject對象,然後就可以根據我們的需要,進行相應的操作。

2)ExecQuery方法獲得類的執行個體集合

與InstancesOf方法不一樣的是,ExecQuery方法可以通過查詢語句,隻傳回比對部分執行個體和屬性。ExecQuery方法的文法參數格式如下:

SwbemServices.ExecQuery(strQuery)

strQuery為WMI查詢語言(WQL)構造的一個查詢語句字元串。

例如:

Set objSWbemObjectSet = objSWbemServices.ExecQuery("select ProcessorId from

Win32_Processor where DeviceID='cpu0'")

3)Get方法獲得一個類的執行個體(SWbemObject對象)

此方法也就不必再用 For Each objSWbemObject In objSWbemObjectSet :……:Next

語句從SWbemObjectSet對象中獲得每一個類的執行個體SWbemObject對象,Get方法的文法參數格式如下:

SwbemServices.Get([strObjectPath][.KeyProperty='Value'])

strObjectPath是類的名字

KeyProperty是主鍵屬性名

Value是指定的主鍵屬性值

這裡要注意的是如果要獲得一個類的執行個體,則strObjectPath.KeyProperty='Value'中的任何一項都不能省略,例如:

Set objSWbemServices = GetObject("winmgmts:")

Set objSWbemObject = objSWbemServices.Get("Win32_Processor.DeviceID='cpu0'")

Wscript.echo “CPU的型号為”:" & objSWbemObject.ProcessorId

看,結果一樣,腳本卻簡化了不少。

4)直接用moniker名字法獲得一個類的執行個體

在說明Moniker名字法的時候我們說過,當包括最後2項時,傳回的是一個類的單獨執行個體,如:Set objSWbemObject =

GetObject("winmgmts:Win32_Processor.DeviceID='cpu0'")

Wscript.echo "首枚CPU序列号:" & objSWbemObject.ProcessorId

是不是更加簡單?僅僅2條語句就獲得了CPU的序列号。

3.讀取類的執行個體屬性,調用類的方法

實在是太多了,你可以參照C:/WINDOWS/system32/wbem/cimwin32.mfl檔案中,對所有類的屬性和方法的描述。也可以用下列代碼查詢,雖然看起來有點困難,不過看的多了也就明白了。strClass=inputbox("請輸入你要查詢的類")

strNameSpace = "root\cimv2"

Const wbemFlagUseAmendedQualifiers = &h20000

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\" & strNameSpace)

Set objClass = objWMIService.Get(strClass, wbemFlagUseAmendedQualifiers)

strMOF = objClass.GetObjectText_

WScript.Echo strMOF

本文轉自hcy's workbench部落格園部落格,原文連結:http://www.cnblogs.com/alterhu/archive/2012/04/07/2435927.html,如需轉載請自行聯系原作者。