Use PowerShell to parse event log for shutdown events
Summary: Using the Windows PowerShell Get-EventLog cmdlet makes it easy to parse the system event log for shutdown events.
One of the great things about central Florida during this time of the year is that there are certain fruits, such as red grapefruit, that are in season. This is also true of a certain variety of tangelo that is super sweet.
However, as sweet as both of these are, neither is a sweet as parsing the event log with Windows PowerShell. It makes it easy to gain insights into what is going on with your computer, server, or whatever device.
Using Get-EventLog cmdlet is super easy
There are two basic Windows PowerShell cmdlets that parse the event log. One, Get-WinEvent, is super powerful, but a bit tricky to use. The other, Get-EventLog, is super easy, and it works great for ad hoc parsing. Today I will use Get-EventLog because I am only working with a classic event log, and I am only working on my local computer.
Since Windows XP and Windows 2003, Windows has had the Shutdown Event Tracker, which will track what is going on with shutdowns. It writes to the System event log and the source is User32. I can search for this information directly from the System event log by using the Get-EventLog cmdlet:
Get-EventLog -LogName system -Source user32
The command and output are shown in the following image:
I also know from working with the Microsoft Operations Management Suite that there are two event IDs associated with the Shutdown Event Tracker. One is normal, and the other is an unexpected shutdown.
Note For more information about Microsoft Operations Management Suite Search capabilities, see my series of blog posts on the MSOMS Team blog.
At this point, I do not need to know which event is normal or unexpected. All I want to do is to group them by EventID, then I can dive into them in a little bit. Here is the command that I use:
Get-EventLog -LogName system -Source user32 | group EventID
My output, which appears in the following image, tells me that I only have a single EventID: 1074.
Dive into the data
Let me look at one instance of the 1074 event. To this, I send the output to the Format-List cmdlet and select all of the properties. In the following command, fl is an alias for Format-List and * means to choose all of the properties:
Get-EventLog -LogName system -Source user32 -Newest 1 | fl *
The output includes the machine name, the time the event was generated, the user name, the message, and other properties. By looking at these details, I can decide what information I actually find useful, and that will guide my selection process. Here a screenshot of the event record details:
Sort the data
Because I know there is only one EventID on my system from the User32 source, I know that I can leave that information out. From looking at the event record details, I can see that I am only interested in two pieces of information (properties of the object). These are the TimeGenerated and the Message. So, I select that information in my revised query:
Get-EventLog -LogName system -Source user32 | Select TimeGenerated, Message
Note In my Windows PowerShell console running Windows PowerShell 5.0, I can Tab expand the property names in my Select statement.
Here is the output from the command:
It looks like my time is displayed in descending fashion. But I am more interested in the message. Because the message looks somewhat redundant, I think I might be able to sort on that property and receive meaningful data:
Get-EventLog -LogName system -Source user32 | Select TimeGenerated, Message | sort message
The command and its output are shown here:
That looks good, and I can see that the RuntimeBroker initiated a number of shutdowns, but there were also a few by the winlogon. I can easily pipe the output to the Format-Table cmdlet and tell it to wrap. By doing this, I will be able to see the content of the Message property. The following command is a one-liner that is broken at the pipeline character for readability (ft is an alias for Format-Table):
Get-EventLog -LogName system -Source user32 | Select TimeGenerated, Message |
sort message | ft -Wrap
Here is the command and its output:
If I would like a good overview of various reasons, I can select unique messages and still wrap them. When I do this, I do not need the time generated, I am only looking at the reasons:
Get-EventLog -LogName system -Source user32 | Select Message -Unique | ft -Wrap
This command and its output are shown here:
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. Also check out my Microsoft Operations Management Suite Blog. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy