Gathering the Number of Event Log Entries Over a Given Time-frame

Today, I needed to gather some statistics on a particular error message in the event logs of my servers.  We have been experiencing some problems this week on occasion that have been a little difficult to isolate.  The developers who are working on this with me have set up a separate event log to capture events from the application platform.  Unfortunately, this log rolled over after three to four hours.  While we didn’t have visibility to see further back in history about some errors we were seeing, I could use Powershell to gather information on how many of the errors we were getting in an hour.

To gather this information, we will use the Get-WMIObject cmdlet. 

$errors = Get-WMIObject -ComputerName USSPS01,USSPS02 -Query "SELECT ComputerName,TimeGenerated FROM Win32_NTLogEvent WHERE LogFile='Application' AND EventCode='1054'"

The above code is a pretty vanilla version of a WMI query.  If you are familiar with Powershell, you know that a collection of WMI Objects that include the ComputerName and TimeGenerated property are gathered.  However, we only need the ComputerName and TimeGenerated properties and not all the other information from the WMI Objects. 

__GENUS          : 2
__CLASS          : Win32_NTLogEvent
__SUPERCLASS     :
__DYNASTY        :
__RELPATH        :
__PROPERTY_COUNT : 2
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
ComputerName     : COMPUTER01
TimeGenerated    : 20110111185758.000000-300

The above clip is a sample of what you might find from the query at the top.  The next line of code will extract the properties needed.

$errors | Select-Object ComputerName,@{Expression={$_.TimeGenerated.SubString(0,10)};Name="Hour"} | Group-Object ComputerName,Hour -NoElement

In this code snippet, the $errors objects are being piped to the Select-Object cmdlet.  The Select-Object cmdlet will strip out the unnecessary information from the WMI Objects.  The second property is a  “calculated property.”  We are taking the TimeGenerated property and taking information from it.  In the sample of information, the time information is shown in a WMI date-time format.  Since this is a string format of date/time information, it makes it very easy to gather statistics by year, month, day, even down to the second, if needed.  In the case above, we are taking the first 10 characters of the date string to get the date and hour information.  The new calculated property is called “Hour.” The new data objects that we have extracted look like this:

ComputerName : USWKS01
Hours        : 2010080701

Finally, the ComputerName and new Hour property are sent to the Group-Object cmdlet.  Since we now have all the information for the number of times the event was picked up during the hour, in this instance.  The format of the time string is now YYYYMMDDHH.  The cmdlet will produce output similar to the following:

Count Name
----- ----
  2 USWKS01, 2011020309   
    2 USWKS01, 2011020207   
    1 USWKS01, 2011020118   
    1 USWKS01, 2011020116   
    2 USWKS01, 2011020111   
    1 USWKS01, 2011020109   
    2 USWKS01, 2011020108

I do know that this information is not real pretty, but when you are trying to troubleshoot something, it does come in handy to be able to get the information without a lot of extra fuss.  I possibly could have modified the resulting date/time string with some spaces to make it a little more readable. 

I am sure there are more elegant ways of sorting and grouping the times, but this got me the information I needed in a relatively short amount of time.

This entry was posted in Event Logs, WMI and tagged , , , , , . Bookmark the permalink.

2 Responses to Gathering the Number of Event Log Entries Over a Given Time-frame

  1. Don Jones says:

    Actually, the ConvertToDateTime() method on every WMI object would help.

    @{Expression={$_.ConvertToDateTime($_.TimeGenerated).Hour};Name=”Hour”}

    A bit cleaner than using SubString since it lets you work directly with a full DateTime. Also, should the WMI date time format ever change, you’re protected since you’re not relying on a particular string sequence. The method also considers the time zone offset that’s present in a WMI date/time string.

    And of course no need to use a variable:

    Get-WMIObject -ComputerName USSPS01,USSPS02 -Query “SELECT ComputerName,TimeGenerated FROM Win32_NTLogEvent WHERE LogFile=’Application’ AND EventCode=’1054′” | Select-Object ComputerName,@{Expression={$_.ConvertToDateTime($_.TimeGenerated).Hour};Name=”Hour”} | Group-Object ComputerName,Hour -NoElement

    Long live the one-liner. And if folks are squirrely about WQL…

    Get-WMIObject -ComputerName USSPS01,USSPS02 -Class Win32_NTLogEvent -Property ComputerName,TimeGenerated -Filter “LogFile=’Application’ AND EventCode=’1054′” | Select-Object ComputerName,@{Expression={$_.ConvertToDateTime($_.TimeGenerated).Hour};Name=”Hour”} | Group-Object ComputerName,Hour -NoElement

    Less query-looking but same net result. Ten ways to do anything, of course. I do like that you spelled out all the cmdlet and parameter names – I hate blogs full of aliases; they make it a lot harder for newcomers to dig in.

    Good work!

  2. Pingback: Tweets that mention Gathering the Number of Event Log Entries Over a Given Time-frame | Powershell Reflections -- Topsy.com

Comments are closed.