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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WMI query....capture empty collections?

Status
Not open for further replies.

VulcanJedi

Technical User
Oct 2, 2002
430
US
I have the following lines of code:
the issue is when colleggedEvents is empty and in nothing is returned from the query than the for each loop crashes; is there a way to capture if the query is empty??


Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colLoggedEvents = objWMIService.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Application' and " _
& "EventCode = '1106' and Type = 'error'")

For Each objevent In colLoggedEvents

[yinyang] Tranpkp [pc2]
 
Sorry just got on machine w/ code; submitted below...not a critical task/problem...just figure its something I want to konw and assume may encounter in the future....


'Set up basic scripting objects****************************
'Option Explicit
Dim objShell, objFSO, objWSHNetwork

Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWshNetwork = WScript.CreateObject("WScript.Network")

Dim ComputerName, UserName, UserDomain, ScriptName, ScriptNameFull
ComputerName = objWshNetwork.ComputerName
'*********************************************************
dim newstring(1)

strLogFile= "C:\temp\" & GetClient(computername) & " CTXPrintDriverFailure.txt"
Wscript.Echo "Processing information from all servers in the farm. This might take several minutes." & vbcrlf & " LOG @ :" & strLogfile & vbcrlf & "Script will notify when complete."

Set objLogFile = objFso.CreateTextFile(strLogFile)

'Run qfarm from CMD to capture the total servers from the CTX farm
Dim strNextLine,objTextFile,RetVal, x,y
Dim line
RetVal = objShell.run("cmd /c qfarm > c:\scripts\servers.txt",, true)
Const ForReading = 1

'Read qfarm file to capture servernames into array
Set objTextFile = objFSO.OpenTextFile _
("c:\scripts\servers.txt", ForReading)

strNextLine = objTextFile.Readall
'msgbox strNextLine

line=split(strNextLine, vbcrlf,-1,1)

For x = 1 to ubound(line)
y=instr(1,line(x), " ", vbtextcompare)
If instr(1,line(x), "CTX", vbtextcompare) Then
If Mid(line(x), y-1,1) = "*" Then y=y-1 'capture for the current server
strComputer=Left(line(x), y-1)

'connect to wmi/query
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colLoggedEvents = objWMIService.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Application' and " _
& "EventCode = '1106' and Type = 'error'")
count =0
On Error Resume Next 'capture for when collection is empty/nonexistant/null so just skip
For Each objevent In colLoggedEvents

mystring =Null

mystring = objevent.message
' count = count +1
startpos =InStr(1, mystring, "Printer Driver:", vbtextcompare)
endpos = InStrrev(mystring, ")", len(mystring),vbtextcompare)
mystring = Mid (mystring, startpos, endpos)
If IsNull(mystring) Then
'do nothing
Else
objlogfile.Write mystring
count=count+1
End if
Next

On Error goto 0

objLogFile.WriteLine "******************************************************"
objLogFile.Write Now & " TOTAL EVENTS for " & strComputer & ": " & Count & vbCrLf


End If
Next
objlogfile.Close
WScript.Echo "DONE"
Function GetClient(DeviceName)

GetClient=Mid(DeviceName,1,(InStr(1,DeviceName,"CTX",vbtextcompare)-1))
End Function
 
> Don't make the mistake of thinking that WQL, which happens to look rather like SQL, returns ADO recordsets. It doesn't, and therefore the issues with recordset count properties does not arise.


Thanks strongm, i wouldnt make that mistake, i was just brain dumping on other 'similar' count/collection issues
 
The .count property is applicable as long as the query is synchronous. If it is semi-sync or asyn, then the .count is not supported. It is a runtime error. Hence, for semi-sync or async, never check .count. For sync query, it is fine. That is the systematic of how count behaves.
 
Amendment
Also, I just have one amendment to make on my own first post, forgotten to change type which is string to eventtype which is uint8 type. Also my correction to eventcode should stand. It is of type uint8, not a string. My second line should eventually be read like this.
[tt] Set colLoggedEvents = objWMIService.ExecQuery _
("Select * from Win32_NTLogEvent Where Logfile = 'Application' and " _
& "EventCode = 1106 and [red]Event[/red]Type = 1")[/tt]
That's all I have to say as to the query line.
 
I never had any luck with the WMI event query since it tends to do an endless loop during the query. I had to resort to the Microsoft DUMPEL.EXE utility from the link at
I have following code that I wrote for my event log query. It always works for me.

===================================================
Option Explicit

Dim strComputer, strLogFile, strDay, arrEvtData, objItem

strComputer = "MySERVER"
strLogFile = "Application"
strDay = 1

arrEvtData = getEventLogInfo(strComputer, strLogFile, strDay)

For Each objItem In arrEvtData
Wscript.Echo objItem
Next

' Function to run dumpel.exe utility to query the event log information.
Private Function getEventLogInfo(strComputer, strLogFile, strDay)
Dim objDicData, objShell, objExecObject, strDataSource, strData, strDate
Dim strTime, strType, strID, strSource, strDesc, dtmDateTime, arrData
Dim strDateSelect
PrintMsg3 "Querying event log information on " & strComputer & ". Please wait. . ."
Set objDicData = CreateObject("Scripting.Dictionary")
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objExecObject = objShell.Exec _
("%comspec% /c dumpel -s \\" & strComputer & " -l " & strLogFile & _
" " & " -d " & strDay & " -t -format dtITSs")
' Event Type (T): 1 = Error, 2 = Warning, 4 = Information
Do While Not objExecObject.StdOut.AtEndOfStream
strDataSource = objExecObject.StdOut.ReadLine
If strDataSource <> "Dump successfully completed." Then
strData = Split(strDataSource, vbTab)
strDate = strData(0) : strTime = strData(1) : strID = strData(2)
strType = strData(3) : strSource = strData(4) : strDesc = strData(5)
Select Case strType
Case 1
strType = "Error"
Case 2
strType = "Warning"
Case 4
strType = "Information"
End Select
If Len(strDesc) > 0 Then
If objDicData.Count > 75 Then Exit Do ' Limit the event log number to 75.
strDesc = Split(strDesc, ".")(0) & "."
dtmDateTime = strDate & " " & strTime
arrData = strDate & vbTab & strTime & vbTab & strID & vbTab & _
strType & vbTab & strSource & vbTab & Replace(strDesc, Chr(34), "")
' Select only the events from last 24 hours and event type is either error or warning.
strDateSelect = DateDiff("s", dtmDateTime, Now)
'If strDateSelect =< 864000 And strType <> "Information" Then ' 10 days.
'If strDateSelect =< 432000 And strType <> "Information" Then ' 5 days.
If strDateSelect =< 86400 And strType <> "Information" Then ' 1 day.
objDicData.Add objDicData.Count, arrData
End If
End If
End If
Loop
If objDicData.Count > 0 Then
getEventLogInfo = SortEventData(objDicData.Items)
Else
getEventLogInfo = Array("")
End If
' Clean up variables.
Set objDicData = Nothing: Set objShell = Nothing: Set objExecObject = Nothing
End Function

' Function to sort the event log data.
Function SortEventData(arrData)
Dim dicDataList, DataList, objItem, strData, strDateTime, strDate
Dim strID, strType, strSource, strDesc
Set dicDataList = CreateObject("Scripting.Dictionary")
Set DataList = CreateObject("ADODB.Recordset")
DataList.Fields.Append "strEventDate", 7 ' adVarDate
DataList.Fields.Append "strEventID", 200, 255 ' adVarChar
DataList.Fields.Append "strEventType", 200, 255 ' adVarChar
DataList.Fields.Append "strEventSrc", 200, 255 ' adVarChar
DataList.Fields.Append "strEventDesc", 200, 255 ' adVarChar
DataList.Open
For Each objItem In arrData
strData = Split(objItem, vbTab)
strDateTime = strData(0) & " " & strData(1)
DataList.AddNew
DataList("strEventDate") = strDateTime
DataList("strEventID") = strData(2)
DataList("strEventType") = strData(3)
DataList("strEventSrc") = strData(4)
DataList("strEventDesc") = strData(5)
DataList.Update
Next
If DataList.RecordCount > 0 Then 'Used for trapping null record.
DataList.Sort = "strEventDate DESC" ' Sort date and time by descending order.
DataList.MoveFirst
Do Until DataList.EOF
strDate = getDateTime(DataList.Fields.Item("strEventDate"))
strID = DataList.Fields.Item("strEventID")
strType = DataList.Fields.Item("strEventType")
strSource = DataList.Fields.Item("strEventSrc")
strDesc = DataList.Fields.Item("strEventDesc")
strData = strDate & vbTab & strID & vbTab & strType & vbTab & strSource & vbTab & strDesc
dicDataList.Add dicDataList.Count, strData
DataList.MoveNext
Loop
End If
SortEventData = dicDataList.Items
' Clean up variables.
Set dicDataList = Nothing: Set DataList = Nothing
End Function

' Function to split event date and time after sorting.
Private Function getDateTime(strDateTime)
Dim strDate, strTime
strDate = Split(strDateTime)(0)
strTime = Split(strDateTime)(1) & " " & Split(strDateTime)(2)
getDateTime = strDate & vbTab & strTime
End Function

' Sub routin to print message.
Private Sub PrintMsg (ByVal strMessage)
Wscript.StdOut.WriteBlankLines(1)
Wscript.StdOut.WriteLine Space(3)& strMessage
End Sub

================================================

CluM09
 
Hop! I made a mistake in the getEventLogInfo function where the PrintMsg3 should be replaced with PrintMsg.
 
FWIW, the colLoggedEvents.Count = 0 statement DOES work to show an empty collection. I had the same issue checking the application event log for the DST patch, trying to figure out whether the patch was applied. Finding a zero count for the WSH event told me that the patch had not been applied.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top