2016-06-09 51 views
1

我的公司正試圖找出哪些機器沒有加載我們的圖像。我們在WMI中添加了一個名爲Revision_Detail的類,但由於不一致,它沒有在我們圖像的所有版本上填充。VBScript WMI類和屬性存在

我放在一起檢查Revision_Detail是否存在,然後檢查它是否爲空。如果它爲空,它會恢復到ImageRevision類,我們的每個圖像都有。

我的問題是我碰到(並正在使用)的函數,遍歷所有CIMV2類,並且有點慢。

有沒有辦法只是執行查詢並捕獲修訂細節不存在的錯誤?

Function WMIClassExists(strComputer, WMIClassName) 
    WMIClassExists = vbFalse 
    Dim objWMIService: Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
    Dim colClasses: Set colClasses = objWMIService.SubclassesOf() 
    Dim objClass 
    For Each objClass In colClasses 
     if instr(objClass.Path_.Path,WMIClassName) Then 
      WMIClassExists = vbTrue 
     End if 
    Next 
    Set objWMIService = Nothing 
    Set colClasses = Nothing 
End Function 

Set wshNetwork = WScript.CreateObject("WScript.Network") 

strComputer = wshNetwork.ComputerName 

If WMIClassExists(strComputer,"Revision_Detail") Then 
    'Found Revision_Detail 
    WSCript.Echo strWMIClass & " WMI class does exists on " & strComputer 
    Set Wmi = GetObject("winmgmts:\\" & strComputer & "\ROOT\CIMV2") 
    SET colItems = Wmi.ExecQuery("SELECT * FROM Revision_Detail") 

    For Each objItem in colItems 
     if IsNull(objItem.CurrentBuild) Then 
      'If CurrentBuild doesnt exist, check ImageRevision 
      SET colItems2 = Wmi.ExecQuery("SELECT * FROM ImageRevision") 

      For Each objItem2 in colItems2 
       wscript.echo "ImageRevision: " & objItem2.ImageRevision 
      Next    
     else 
      'Revision_Detail exists and is not blank 
      wscript.echo "CurrentBuild: " & objItem.CurrentBuild 
      wscript.echo "StartBuild: " & objItem.StartBuild 
     end if 
    Next 

Else 
    'Must not be an our image 
    WSCript.Echo strWMIClass & " WMI class does not exists on " & strComputer 
End if 

回答

1

有沒有辦法,只是執行查詢,趕上錯誤修訂細節不存在?

當然可以。在VBScript中捕獲錯誤使用On Error Resume Nextdocs)完成。

由於WMI對象集合是一個有點尷尬着,我創建了執行WMI查詢,返回一個數組,而不是一個集合的輔助函數的工作:

Function GetWmiObjects(wmi, wql) 
    Dim items, item, i, result 
    Set items = wmi.ExecQuery(wql) 

    ' count items 
    On Error Resume Next 
    i = 0 
    For Each item In items 
     If Err.Number = 0 Then i = i + 1 
    Next 
    On Error GoTo 0 

    ' allocate array of the proper size 
    ReDim result(i - 1) 

    ' transfer items to array 
    If i > 0 Then 
     i = 0 
     For Each item In items 
      Set result(i) = item 
      i = i + 1 
     Next 
    End If 

    GetWmiObjects = result 
End Function 

現在很容易做到:

Set wmi = GetObject("winmgmts:\\.\ROOT\CIMV2") 

Revision_Detail = GetWmiObjects(wmi, "SELECT * FROM Revision_Detail") 

If Count(Revision_Detail) = 0 Then 
    Wscript.Echo "Revision_Detail not found" 
Else 
    Wscript.Echo Revision_Detail(0).CurrentBuild 
End If 

其中Count是返回的數組的大小的便利功能:

Function Count(array) 
    Count = UBound(array) + 1 
End Function 
+0

我收到所需的對象: 'Revision_Detail(...)' 在此行 「Revision_Detail = GetWmiObjects(WMI, 」SELECT * FROM Revision_Detail「)」 –

+0

哎呀,這是固定的。再試一次。 – Tomalak

0

我確信它可以完成,但是您必須等待objWMIService在每次Ping設備關閉時都會超時。 反過來說,你可以在你準備好的時候給我打電話。 創建一個腳本,檢查本地計算機上的映像,並將其結果保存到服務器上的文件中。然後,您可以讓組策略在所有機器上安排一項任務,以在本地運行新腳本。

更新: 爲了降低總體複雜度,我收緊了一些代碼。

上的錯誤繼續下一步

而且

對錯誤轉到0

需要進行內部的舉動每個循環。由於On Error GoTo 0在循環之外,Err對象無法重置爲0,直到退出每個循環。

Function GetWmiObjects(wmi, wql) 
    Dim items, item, i, result 
    Set items = wmi.ExecQuery(wql) 

    For Each item In items 
     On Error Resume Next 
     If Err.Number = 0 Then 
      i = UBound(result) + 1 
      ReDim Preserve result(i) 
      Set result(i) = item 
     End If 
     On Error GoTo 0 
    Next 

    GetWmiObjects = result 
End Function 
+0

正是我在做什麼。只是想要一個腳本跑得更快,以防止用戶退化。 –