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.

PowerShell's get-eventlog default display. (Image Credit: Jeff Hicks)
PowerShell’s get-eventlog default display. (Image Credit: Jeff Hicks)


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.
Formatting the get-eventlog display as a list. (Image Credit: Jeff Hicks)
Formatting the get-eventlog display as a list. (Image Credit: Jeff Hicks)

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.
Grabbing an object and piping it to get-member in Windows PowerShell. (Image Credit: Jeff Hicks)
Grabbing an object and piping it to get-member in Windows PowerShell. (Image Credit: Jeff Hicks)

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.
Viewing the XML file in the PowerShell ISE. (Image Credit: Jeff Hicks)
Viewing the XML file in the PowerShell ISE. (Image Credit: Jeff Hicks)

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.

​
As you can see there are a few FormatViewDefinition settings.
FormatViewDefinition settings. (Image Credit: Jeff Hicks)
FormatViewDefinition settings. (Image Credit: Jeff Hicks)
You can drill down to see the details.
FormatViewDefinition settings. (Image Credit: Jeff Hicks)
FormatViewDefinition settings. (Image Credit: Jeff Hicks)
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.
​
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.

​
I can easily navigate the document.
Navigating to the document in Windows PowerShell. (Image Credit: Jeff Hicks)
Navigating to the document in Windows PowerShell. (Image Credit: Jeff Hicks)
What I need to do is move the view nodes around, so let's get them using an XPath filter.
Selecting nodes with the xPath filter. (Image Credit: Jeff Hicks)
Selecting nodes with the xPath filter. (Image Credit: Jeff Hicks)
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.
​
Now I can insert this copy before the table control view, which I can do from the parent node.
$tmp.Configuration.ViewDefinitions.InsertBefore($clone,$views[0])

Now there are three entries.

Our three entries. (Image Credit: Jeff Hicks)
Our three entries. (Image Credit: Jeff Hicks)

The last one can now be deleted.

$tmp.Configuration.ViewDefinitions.RemoveChild($views[1])

Now I have what I want.

We now have two entries. (Image Credit: Jeff Hicks)
We now have two entries. (Image Credit: Jeff Hicks)

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:
The default output for get-eventlog. (Image Credit: Jeff Hicks)
The default output for get-eventlog. (Image Credit: Jeff Hicks)
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.
​
Now look at the result:
PowerShell automatically formatted the result as a list. (Image Credit: Jeff Hicks)
PowerShell automatically formatted the result as a list. (Image Credit: Jeff Hicks)
PowerShell automatically formatted the result as a list. If I want a table, I can still ask for it.
​
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.
​
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.