September 13th, 2005

How Can I Retrieve Just Audit Failures, Warnings, and Errors from My Event Logs?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I retrieve just audit failures, warnings, and errors from my event logs?

— OG

SpacerHey, Scripting Guy! AnswerScript Center

Hey, OG. You know, just for the heck of it, we decided to check the event logs on one of our computers to see whether this was a task worth doing. In the Security event log on this machine we had 42,815 events; of those, just 286 were failure events. If we assume that the failure events are the events we really care about then we have two choices here: we can either wade through 42,815 events, trying to pick out the relatively few failure events, or we can write a script that returns only failure events. Even for the Scripting Guys that wasn’t a very tough decision to make.

Here’s a script that returns just audit failures, warnings, and errors from all your event logs:

strComputer = “.”

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

Set colLoggedEvents = objWMIService.ExecQuery _ (“Select * From Win32_NTLogEvent Where EventType <> 4 AND EventType <> 8”)

For Each objEvent in colLoggedEvents Wscript.Echo “Category: ” & objEvent.Category 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.EventType Next

Having shown you the script we should point out that this one runs only on Windows XP and Windows Server 2003. But don’t panic: we’ll show you a modified version in a minute or two that will work on Windows 2000.

Hey, no need to thank us; that’s what we’re here for.

To begin with, we need to bind to the WMI service on the computer in question (in this sample script, that’s the local computer). You might notice that, when making this connection, we included the (Security) privilege in the moniker string:

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

Is that important? Well, one of the things we want to retrieve is audit failures. Audit failures are recorded in the Security event log; if you don’t include the (Security) privilege you will not be able to retrieve events from the Security event log. Yes, we know you’re an administrator on the machine. Doesn’t matter: the (Security) privilege is still required in order to retrieve items from the Security event log.

In other words, yes, it’s important.

Next we issue the following WQL query, which limits the records retrieved to audit failures, warnings, and errors:

Set colLoggedEvents = objWMIService.ExecQuery _
    (“Select * From Win32_NTLogEvent Where EventType <> 4 AND EventType <> 8”)

What do you mean it’s not obvious how the query does this? It – oh, right: it’s not very obvious, is it? Well, as it turns out, the EventType property indicates the type of record being written to the event log; furthermore, EventType will always be one of the following values:

Value

Meaning

1

Error

2

Warning

4

Information

8

Security audit success

16

Security audit failure

In our query, we asked for all the events where the EventType did not equal 4 (information events) and where the EventType does not equal 8 (security audit success). That filters out information and security audit success events; for example, an information event equals 4, which causes it to be excluded from the returned data. In turn, that leaves just three event types to be retrieved: audit failures, warnings, and errors. Coincidentally, those just happen to be the three event types you’re interested in.

The rest of the script is nothing more than a For Each loop that echoes back pertinent information for each event. As we are wont to say: problem solved.

Well, unless you’re running on Windows 2000, that is. That’s because the EventType property isn’t found on Windows 2000; instead, the Win32_NTLogEvent class uses the Type property. On Windows 2000, Type will be one of the following string values:

Value

Meaning

error

Error

warning

Warning

information

Information

audit success

Security audit success

audit failure

Security audit failure

To get our script to work on Windows 2000, we need to filter on the Type property, eliminating records of type information and type audit success. Our revised WQL query looks like this:

Set colLoggedEvents = objWMIService.ExecQuery _
    (“Select * From Win32_NTLogEvent Where Type <> ‘information’ AND Type <> ‘audit success'”)

And the revised script looks something like this:

strComputer = “.”

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

Set colLoggedEvents = objWMIService.ExecQuery _ (“Select * From Win32_NTLogEvent Where Type <> ‘information’ AND Type <> ‘audit success'”)

For Each objEvent in colLoggedEvents Wscript.Echo “Category: ” & objEvent.Category 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 Next

There you go.

Incidentally, the fact that we had 42,815 events doesn’t mean we don’t back up and clear our event logs on a regular basis. Instead, we let these records accumulate so that we’d … have a better example to use for today’s column. Now that the column is finished, we’ll probably back up and clear the event log, just like you’re supposed to.

No, not today, mind you. But soon, very soon ….

Author

0 comments

Discussion are closed.