PowerShell Problem Solver: Creating a Better EventLog View
If you have used the PowerShell Get-Eventlog cmdlet to display event logs, then you have probably been a little frustrated. You’ll run a command like this:
get-eventlog system -newest 10 -EntryType Error
But the default display is hardly helpful.
You’ll notice that the message property is truncated, and it’s probably the thing you want to see most when using the get-eventlog cmdlet. You can get around this by specifically telling PowerShell to format the display as a list.
Now you have to remember to always use format-list or come up with a custom command to display the properties the way you want. This is a case where PowerShell isn’t making things easier for the IT pro. In fact, a suggestion was made to Microsoft about this very situation. The default display for Get-Eventlog should be a list and not a table. Fortunately, we don’t have to wait for Microsoft to make that change.
Most common object types, like what we get from Get-Eventlog, have defined views. That is, when you run Get-Eventlog, at the end of the pipeline PowerShell looks at the objects and then determines how to best display them. It accomplishes this by looking at a set of rules stored in .ps1xml files. PowerShell is flexible enough to allow you to rewrite those rules and that’s what we are going to do.
First, we need to know what type of object we’re dealing with. I’ll get a single object as a reference and pipe it to Get-Member.
The typename tells me what I need to know. In this case, I can ignore everything after the # symbol. When you run Get-Eventlog, PowerShell looks in its files for instructions on how to display a System.Diagnostics.EventLogEntry object. In this particular case, these rules are stored in $pshome\DotNetTypes.format.ps1xml. If you want, you can carefully open the file in Notepad or the PowerShell ISE, and search for the object type.
You’ll see entries for a Table and a List. Because the Table is listed first, it becomes the default. But don’t change anything in the file. It is digitally signed by Microsoft and any changes you make could be overwritten. Instead, you can create your own set of rules via a custom .ps1xml file. Instead of having you copy and paste, let’s work on this from PowerShell. If you opened the dotnetypes file, close it without saving any changes.
We can see the same information in PowerShell with the Get-FormatData cmdlet.
$fd = Get-FormatData -TypeName System.Diagnostics.EventLogEntry
As you can see there are a few FormatViewDefinition settings.
You can drill down to see the details.
This should be the same type of information you saw in the dottypes format file. In order to change the format data for this type, I am going to have to create my own .ps1xml file. In that file, I can make sure the List control comes first. To extract the data I want, PowerShell will let me export to a new file.
$newFile = "C:\scripts\myeventlogview.ps1xml" Get-FormatData -TypeName System.Diagnostics.EventLogEntry | Export-FormatData -Path $newFile -IncludeScriptBlock –Force
The new file is an XML document, so I can manipulate it from PowerShell.
[xml]$tmp = get-content $newFile
I can easily navigate the document.
What I need to do is move the view nodes around, so let’s get them using an XPath filter.
$views = $tmp.Configuration.ViewDefinitions.SelectNodes("//View")
The second node is my list control, which I want to move before the table. However, the XML document doesn’t have a move method from what I can tell.
Because of this, I will have to work around this limitation by copying the second view.
$clone = $views.CloneNode($true)
Now I can insert this copy before the table control view, which I can do from the parent node.
Now there are three entries.
The last one can now be deleted.
Now I have what I want.
All that remains is to write the changes back to the file.
You only need to go through this process once to create your own .ps1xml file. Now , let’s use it. Right now I still have the default output:
To change this, I will use Update-FormatData and specify my new .ps1xml file.
If you look at the cmdlet help, you will see there are parameters for prepending and appending. In this case, I want my file to overwrite the Microsoft version, so I will prepend.
Update-FormatData -PrependPath $newFile
Now look at the result:
PowerShell automatically formatted the result as a list. If I want a table, I can still ask for it.
get-eventlog system -Newest 2 | format-table
This change will only last for as long as my PowerShell session is running. Don’t like a change or made a mistake? Exit and restart PowerShell to return to the default settings. However, if this is something I know I always want, then I will add this line to my PowerShell profile script.
Update-FormatData -PrependPath "C:\scripts\myeventlogview.ps1xml"
If Microsoft changes the default view in a future version of Windows, which I hope they do, all I have to do is remove the line from my profile. In the meantime, if you would prefer a list by default, you should be able to follow these steps.