Impressions of PowerShell: Taking Buck Woody’s EventLog example further.

This is not quite a PowerShell first impressions article. I’ve toyed with PowerShell a few times before previously. Most notably, I toyed with the PowerShell TFS cmdlets that come with Team Foundation Server Power Toys a little under a year ago. However, I never stuck with it long enough to retain any of the syntax. Recently, I discovered a one liner by chance in Buck Woody’s blog. This lead me to do some serious PowerShell tinkering today. I’m not quite a seasoned PowerShell novice, but I believe I am now on my way there.

So here is the script in question:

Get-EventLog System | Where-Object { $_.EntryType -eq “Error” }

It is a simple one liner to get all the errors in your event log. The main work horse is the Get-EventLog cmdlet. I spent a good chunk of time playing with it.  I came up with a few iterations:

  • Get-EventLog -Log System -EntryType ‘Error’ # Skip the step of piping through the event logs
  • Get-EventLog -Log System -EntryType ‘Error’ -After (Get-Date).Date.AddDays(-5) # Errors From the past 5 days
  • Get-EventLog -Log System | Where-Object { $_.EntryType -eq ‘Error’ -and $_.TimeGenerated -gt (Get-Date).Date.AddDays(-5) } # Alternate one liner to get errors from the past 5 days with Where-Object

I tried several other permutations, most of which did nothing. I will make note of one thing here, which I will delve into more in a followup post. That something is the pipe “|” character. It works almost exactly as any windows or unix command line guru would expect. Namely, it “pipes” the output from the program on the left into the input of the program on the right. However, PowerShell is object based, unlike unix, dos and windows shells, which are based on streams of text. Therefore, you can pipe objects as well as strings with PowerShell. When piping to and from cmdlets, you are piping objects. The examples above that use the Where-Object cmdlet makes the implications of this clear.

One thing to note here is speed of return. One would think that the event log is indexed by date, and that I could reduce my query time by only returning recent entries. Searching the whole event log should be expected when using the Where-Object cmdlet,  since all log entries are being queried and piped to another program. However, one would think that the Event Log would be indexed and the Get-EventLog command written in such a way that only a subset of the log entries would have to be traversed when you specified the -After parameter. However, when you run both examples, the command “hangs” for a bit between the last row output and the command prompt being displayed.

In my next article we will throw grep and less into the mix, and see what happens when we mix object piping with text piping.

Further Reading

Links that will be useful to play around with this stuff.