Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Speeding up WMI data collection with Async queries 1

Status
Not open for further replies.
Jul 17, 2001
6
0
0
US
I was looking for a way to speed up data collection via WMI from a large set of servers. After looking at (and rejecting) several different approaches I've decided to try Async queries to poll several hosts simultaneously. Code is below:

[sub]
Set objSink = WScript.CreateObject("wbemscripting.swbemsink","sink_") 'WBEM Event Sink
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") 'Common WBEM Locator
Set objQueue = WScript.CreateObject("Scripting.Dictionary") 'Dictionary serves as queue holder

intMaxQueue = 3 'Maximum simultaneous queues

arrComputers = Array("host1","host2","host3","host4","host5","host6") 'Array containing hosts to query

Dim arrAsyncObjects() 'Array containing Async objects
ReDim arrAsyncObjects(intMaxQueue-1, 2) 'Set to match intMaxQueue

For i=0 To intMaxQueue - 1 'Initial array values
Set arrAsyncObjects(i,0) = Nothing
Next

For Each strComputer In arrComputers
For i=0 To intMaxQueue - 1
If TypeName(arrAsyncObjects(i,0)) = "Nothing" Then 'Spot available in the queue
Exit For
End If
Next
objQueue.Add strComputer, i
Set arrAsyncObjects(i,0) = WScript.CreateObject("WbemScripting.SWbemNamedValueSet")
arrAsyncObjects(i,0).Add "AsyncId", strComputer
Set arrAsyncObjects(i,1) = objSWbemLocator.ConnectServer(strComputer, "root\CIMV2")
arrAsyncObjects(i,2) = strComputer
arrAsyncObjects(i,1).ExecQueryAsync objSink, "Select * from Win32_NTLogEvent Where Logfile = 'Application'",,,,arrAsyncObjects(i,0)

While objQueue.Count = intMaxQueue 'If queue is full - sleep until spot is available
WScript.Sleep 1000
Wend

Next

Sub sink_OnObjectReady(objInst, objContext)
WScript.Echo objContext.Item("AsyncId").Value & " - " & objInst.SourceName
End sub

Sub sink_OnCompleted(HResult, objErr, objContext)
WScript.Echo objContext.Item("AsyncId").Value & " - " & "ExecQueryAsync completed"
intIndex = objQueue.Item(objContext.Item("AsyncId").Value) 'Determine which Async objects can be closed
Set arrAsyncObjects(intIndex,0) = Nothing
Set arrAsyncObjects(intIndex,1) = Nothing
arrAsyncObjects(intIndex,2) = ""
objQueue.Remove objContext.Item("AsyncId").Value 'Free up spot in the queue
End Sub
[/sub]

intMaxQueue could be adjusted to suit your needs, arrComputers, WMI "Select .. " statement and sink_OnObjectReady sub should be changed as well. Way I'm using sink_OnObjectReady in my production is by having it fill ADOR recordset, which later on is sorted by computer name.

Overall this helped turn data collection task that was running for over 4 hours into a 20 minutes one.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top