Polling for the latest event log entry in PowerShell

14 December 2012

Today I had a situation where I had to check one Windows event log all the time so see whether a new entry had arrived.

Normally you could open Event Viewer and click 'Refresh' all the time, but this was a remote Server Core machine with no Event Viewer available.

So I wrote a short PowerShell script to display the latest event log entry on a dedicated command prompt:

    [int]$interval = 10,
    [string]$log = "Application",
    [string]$filter = "*[System[(Level=1 or Level=2 or Level=3)]]"
    $lastEvent = Get-WinEvent -LogName $log -FilterXPath $filter -MaxEvents 1
    if ($lastEvent.RecordId -ne $lastId)
        wevtutil qe $log /c:1 /rd /f:text /q:$filter 
        $lastId = $lastEvent.RecordId

    $curPos = $Host.UI.RawUI.CursorPosition
    $ou = (Get-Date).ToString("HH:mm:ss")
    $ou = "  " +  $ou + " - Press CRTL+C to terminate"

    Start-Sleep -Seconds $interval

 } until ($false)

The defaults are to check for new warning or error entries in the application log every 10 seconds.

Save the code and run it, to test create a new warning in the application log:

eventcreate /t warning /l application /d "Test powershell script" /id 501

The output will look something like this:

  Log Name: Application
  Source: EventCreate
  Date: 2012-12-14T18:50:45.000
  Event ID: 501
  Task: N/A
  Level: Warning
  Opcode: Info
  Keyword: Classic
  User: S-1-5-21-*******-*******-*******-1056
  User Name: foo\bar
  Computer: foo
Test powershell script

  18:50:48 - Press CRTL+C to terminate

I'm using an endless loop that the user has to break out of by pressing ctrl+C. I'm getting the latest event matching my filter using the PowerShell Get-WinEvent commandlet. If it's record number is not the previously remembered one, I display the event. Because it is a bit tricky to extract the event data, I just use the built-in Windows tool: wevtutil to get the latest event using the same filter.

The next five lines are there to display a message on the screen and while updating the time, keeping the message always at the same position. The trick is to remember and set the cursor position.

Finally I wait the specified interval before checking the event again.

This is not super robust, but it was good enough for my needs. If you want to change the filter and don't know the exact xPath syntax, you can use Event Viewer to filter a log and then look at the 'Select' node in the XML view of the 'Filter Current Log' dialog.

Another example:

Get-LastEvent.ps1 -log "Microsoft-Windows-TaskScheduler/operational" -filter "*[System[(Level=2) and (EventID=151)]]"
This checks the task scheduler log for the last error with eventId 151

Pages in this section


ASP.Net | Community | Development | IIS | IT Pro | Security | SQL (Server) | Tools | Web | Work on the road | Windows