VBScript WMI类和属性存在
我的公司正试图找出哪些机器没有加载我们的图像。我们在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
有没有办法,只是执行查询,赶上错误修订细节不存在?
当然可以。在VBScript中捕获错误使用On Error Resume Next
(docs)完成。
由于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
我确信它可以完成,但是您必须等待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
正是我在做什么。只是想要一个脚本跑得更快,以防止用户退化。 –
我收到所需的对象: 'Revision_Detail(...)' 在此行 “Revision_Detail = GetWmiObjects(WMI, ”SELECT * FROM Revision_Detail“)” –
哎呀,这是固定的。再试一次。 – Tomalak