How Can I Find the Date of the Oldest Event in an Event Log?

How Can I Find the Date of the Oldest Event in an Event Log?

  • Comments 3
  • Likes
Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I find the date of the oldest event in an event log?

-- JL

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JL. You know, you just had to make a reference to “old” in your question, didn’t you? Just today one of the Scripting Guys received a letter from the American Association of Retired Persons (AARP). Although the letter acknowledged that this Scripting Guy wasn’t 50 years old yet (and thus wasn’t eligible for membership), it did invite him to pre-register for membership; after all, the letter implied, it won’t be that much longer, will it? Thoughtfully included in the letter was a sample membership card with the Scripting Guy’s name emblazoned on it. Trust us: if you’ve never felt old before, then you’ve never seen your name on an AARP membership card.

But enough about that; after all, you aren’t looking for old Scripting Guys but old events in an event log. (Lucky for you, seeing as how there aren’t any old Scripting Guys. Although we sometimes wonder about Jean.) At first this proved to be a bit of a problem, and for two reasons. For one, it’s difficult to translate an idea like “find the oldest item in a collection” into a WQL query; the WQL query language doesn’t support keywords like MIN or MAX. Granted, you can always just grab all the events and then determine which event is the oldest, but that introduces another problem: because you can’t specify a sort order in a WQL query, how will you know which event is the oldest? So many questions revolving around what ought to be a simple enough request!

Ah, but where there’s a will there’s a way, huh? (No, not that kind of will. We keep telling you, we’re not that old!) As it turns out, each time an event is written to the event log that event is assigned a record number: the first event written to a log is assigned the number 1, the second event is assigned the number 2, etc. This remains true even when an event log is cleared. Suppose you have 1,000 events in an event log and you clear the log. Guess what record number will be assigned to the first event to be written to the cleared log? You got it: 1.

Why does that matter to us? That matters because it means the oldest event in an event log will always have record number 1. In turn, that means we can find the oldest record in an event log simply by locating event 1. And we can do that by using a script like this one:

strComputer = "."
Set objWMIService = GetObject("winmgmts:{(Security)}\\" & strComputer & "\root\cimv2")

Set colEvents = objWMIService.ExecQuery _
    ("Select * from Win32_NTLogEvent Where Logfile = 'System' " & _
        "AND RecordNumber = 1")

For Each objEvent in colEvents
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
Next

As you can see, this is a fairly run-of-the-mill WMI script. We start off by connecting to the WMI service on the local computer, although - as we never tire of pointing out - this script can also be run against a remote machine. We then use this WQL query to return all the events from the System event log that have a RecordNumber equal to 1:

Set colEvents = objWMIService.ExecQuery _
    ("Select * from Win32_NTLogEvent Where Logfile = 'System' " & _
        "AND RecordNumber = 1")

Because record numbers must be unique we know we’ll only have one item in the collection. And because the first event written to the event log will have a record number of 1, we also know that we’ve located the oldest event. All that’s left now is to set up a For Each loop to walk through our one-item collection and echo back the value of the TimeWritten property:

For Each objEvent in colEvents
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
Next

We should add that, for better or worse, TimeWritten will be returned as a UTC (Universal Time Coordinate) value. But that’s all right: if you’re looking for an easy way to convert that UTC value to a regular (and readable) date-time value take a look at this sample script in the Script Center Script Repository.

Now, we know what you’re thinking: if it’s possible to find the oldest event in an event log does that mean it’s possible to find the newest event that’s been added to an event log? You bet. However, you’ll have to wait until tomorrow to find out how to do that. After all, at our age one column a day is the best we can do.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • yes, this post is old, but its also wrong. If enough log entries have been generated to fill up the log file, then windows will start overwriting the previous entries starting with the oldest. Its a circular buffer. Ergo, record number 1 may not exist.

    Output from a script that attempts to pull a record.

    QUERY: select * from Win32_NTLogEvent where Logfile='Application' and RecordNumber = 1

    EMPTY[1] took 2.571

    QUERY: select * from Win32_NTLogEvent where Logfile='Application' and RecordNumber = 1353

    EMPTY[1353] took 2.245

    AVERAGE[sec/rec]: 2.645

    QUERY: select * from Win32_NTLogEvent where Logfile='Application' and RecordNumber = 1354

    EMPTY[1354] took 2.388

    AVERAGE[sec/rec]: 2.5936

    QUERY: select * from Win32_NTLogEvent where Logfile='Application' and RecordNumber = 1355

  • RECORD[1355] took 2.324

    AVERAGE[sec/rec]: 2.5486666666666666

    QUERY: select * from Win32_NTLogEvent where Logfile='Application' and RecordNumber = 1356

  • This post is a little old, but comes up in a lot of similar Google searches, so I'll commet here. I think I've found a way to get PowerShell 2 to pull the last event in a log, without having to pull the whole log in first.

    As far as I can tell, the .Index property returned from Get-EventLog and .RecordNumber property returned from WQL coincide, so:

    #get the index/recordnumber of the newest event

    $newindex=(Get-EventLog -ComputerName Server1 -LogName Security -Newest 1).index

    #Get the number of events in the log

    $numevent=(Get-WmiObject win32_nteventlogfile -ComputerName Server1 -Filter "LogFileName='Security'").NumberOfRecords

    #calculate the index/recordnumber of the last event

    $lastindex=$newindex - $numevent + 1

    #query for the last record

    $query = "Select * from Win32_NTLogEvent "

    $query+= "Where Logfile = 'Security' "

    $query+= "and RecordNumber=$lastindex"

    $event = Get-WmiObject -ComputerName Server1 -Query $query

    $event | Format-List *

    On systems with huge logs, or over slow network connections, this is 1 or 2 orders of magnitude faster than pulling the whole log and then sorting for the last event.