Hey, Scripting Guy! Can I Retrieve Just Failure Events from the Security Event Log?

Hey, Scripting Guy! Question


Hey, Scripting Guy! Is there a way to retrieve just Failure Audit events from the Security event log?

— KA

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KA. Interesting, isn’t it: any time the subject is failure, people turn to the Scripting Guys. What makes you think we know anything about failure?


Ok, you’re right: silly question. As far as your question goes, it’s very easy to retrieve just Security Failure Audit events from the Security event log; in fact, we just happened to have a script lying around that does that very thing:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate,(Security)}!\\” & _
strComputer & “\root\cimv2”)
Set colLoggedEvents = objWMIService.ExecQuery _
(“Select * FROM Win32_NTLogEvent WHERE Logfile = ‘Security’ ” & _
“AND EventType = 5”)
For Each objEvent in colLoggedEvents
Wscript.Echo “===================================================”
Wscript.Echo “Category: ” & objEvent.Category
Wscript.Echo “Computer Name: ” & objEvent.ComputerName
Wscript.Echo “Event Code: ” & objEvent.EventCode
Wscript.Echo “Message: ” & objEvent.Message
Wscript.Echo “Record Number: ” & objEvent.RecordNumber
Wscript.Echo “Source Name: ” & objEvent.SourceName
Wscript.Echo “Time Written: ” & objEvent.TimeWritten
Wscript.Echo “Event Type: ” & objEvent.Type
Wscript.Echo “User: ” & objEvent.User
Wscript.Echo
Next

A pretty simple little script, but there are at least two things you should take note of. First, notice that we included the (Security) parameter when connecting to WMI:

Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate,(Security)}!\\” & _
strComputer & “\root\cimv2”)

You must include this parameter any time you’re working with the Security event log; leave it out, and the script won’t work. And, yes, we know you’re a local administrator and we know you have the right to read the Security event log. For better or worse, though, WMI doesn’t care about that: you still have to include the (Security) parameter.


Second, note the two parts of our WHERE clause:

(“Select * from Win32_NTLogEvent WHERE Logfile = ‘Security’ ” & _
“AND EventType = 5”)

For this script, we only want to retrieve events that meet two criteria: they’re recorded in the Security event log, and they have an EventType of 5. As you probably figured out, in WMI-speak an EventType of 5 means a Failure Audit. Alternatively, you could search for EventTypes of 1 (Error), 2 (Warning), 3 (Information), or 4 (Security Audit Success). Because we want Failure Audit events, we look for events in the Security Logfile with an EventType of 5. Thus:

WHERE Logfile = ‘Security’ AND EventType = 5

Cool, huh? If you’d like more information about working with event logs (including some sample queries you might find useful), check out the Logs chapter in the Microsoft Windows 2000 Scripting Guide.


And as long as we have your attention, we might want to add one more thing. The script, as it currently stands, will display the TimeWritten property (that is, the date and time that the event was recorded in the event log) using WMI’s default Universal Time Coordinate format. In other words, you’ll get back results similar to this:

20041025124000.000000-420

How … nice …. But don’t despair. Here’s a modified version of the script that includes a function (WMIDateStringTodate) that will convert this UTC value to something a bit easier to read:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate,(Security)}!\\” & _
strComputer & “\root\cimv2”)
Set colLoggedEvents = objWMIService.ExecQuery _
(“Select * FROM Win32_NTLogEvent WHERE Logfile = ‘Security’ ” & _
“AND EventType = 5”)
For Each objEvent in colLoggedEvents
Wscript.Echo “===================================================”
Wscript.Echo “Category: ” & objEvent.Category
Wscript.Echo “Computer Name: ” & objEvent.ComputerName
Wscript.Echo “Event Code: ” & objEvent.EventCode
Wscript.Echo “Message: ” & objEvent.Message
Wscript.Echo “Record Number: ” & objEvent.RecordNumber
Wscript.Echo “Source Name: ” & objEvent.SourceName
dtmEventDate = objEvent.TimeWritten
strTimeWritten = WMIDateStringToDate(dtmEventDate)
Wscript.Echo “Time Written: ” & strTimeWritten
Wscript.Echo “Event Type: ” & objEvent.Type
Wscript.Echo “User: ” & objEvent.User
Wscript.Echo
Next

Function WMIDateStringToDate(dtmEventDate)
WMIDateStringToDate = CDate(Mid(dtmEventDate, 5, 2) & “/” & _
Mid(dtmEventDate, 7, 2) & “/” & Left(dtmEventDate, 4) _
& ” ” & Mid (dtmEventDate, 9, 2) & “:” & _
Mid(dtmEventDate, 11, 2) & “:” & Mid(dtmEventDate, _
13, 2))
End Function


We won’t bother explaining how this works today, but if you have any questions about it, let us know. Maybe we’ll go into it in more detail in a future column.