Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to query event logs for entries created during startup.

Microsoft Scripting Guy, Ed Wilson, is here. One of the things that annoys me is when something changes on my laptop, and I know that I did not do anything to directly cause the change. Obviously, I did something—but maybe not directly. For example, if I install a piece of software, and it also installs two or three startup services that go off and do this, that, or the other, without providing me the opportunity to choose, then I have changed something, but not directly.

In fact, I would say that poorly designed, and badly behaved software, is the chief cause of me reinstalling Windows on my laptop. Whereas, I used to reinstall Windows every six months, I had have gotten away from that habit in recent years. However, all of these unintended started up services and applications, are killing the performance of my laptop. It is so bad now that I boot my laptop, and then I go do stuff. I come back, log on, and then go off and do more stuff. It is either that, or wait for about 15 minutes after logon before my laptop finally settles down enough to get some work done.

Now I do not really have to wipe and reinstall (although that is always an option). I can use the tools built-in to Windows to troubleshoot and to diagnose the culprits. For me, the chief diagnostic tool is Windows PowerShell.

Query multiple event logs

One of the best ways to troubleshoot anything in the Windows environment is to examine the appropriate event log. Unfortunately, with dozens of event logs, it is often a trick to know which log to examine. This is where Windows PowerShell shines. There are two cmdlets to work with event logs:

  • Get-EventLog: Accesses classic event logs (such as Application, System, and Security)
  • Get-WinEvent: Accesses more modern logging and tracing

Today I am going to use the Get-EventLog cmdlet and look at the classic event logs. There are more than three classic event logs. In fact, I can use the Get-EventLog cmdlet to list all available classic event logs. To do this, I supply the –List switch to the Get-EventLog cmdlet as shown here:

Get-EventLog –List

The command and the output associated with the command are shown in the following image:

Image of command output

Nearly a dozen classic event logs

So on my laptop, there are nearly a dozen classic event logs. On other computers, I have even more classic event logs. Note that the Security event log does not supply any information. This is because the Windows PowerShell prompt where I took the screenshot was not elevated with Admin credentials; and Admin credentials are required to read the Security event log.

If there can be as few as three or more than a dozen class event logs, how do I know which ones to query for information related to startup events? I might think that the Media Center log does not have anything, but then again it might. What if when I installed the Media Center registration code on my laptop, thereby enabling Media Center, it created some strange startup process that enumerates media files and adds them to the catalog? I am just guessing, but stranger things have happened. So I do not want to exclude that log.

The easy way to query all classic event logs

The easy way to query all classic event logs is to obtain a list of all the logs, and then feed it to the Get-EventLog cmdlet to do the query. But first, I need to get the startup time of my system, so I know where to begin my search. To get the startup time of my system, I can easily query WMI for the information. This is shown here:

$bootTime = (Get-CimInstance win32_Operatingsystem).lastbootuptime 

Now that I have the boot-up time of my computer, I can use it in a query. I want to filter event log entries that occur beginning at boot-up time, and for events that occur up to five minutes after boot. I might need to adjust this later, but this will give me something with which to work.

Because the $boottime variable contains an actual DateTime object, I can call methods on the DateTime object. I want to use the AddMinutes method to add five minutes to control my outer limit for event log entries. Here is the Get-EventLog query for this:

Get-EventLog -LogName $log.Log -After $bootTime -Before $bootTime.AddMinutes(5) -ea 0

So where does the EventLog name come from? I get it from the Get-EventLog –List command. I put this inside a Foreach loop. Here is that part of the command:

Foreach($log in Get-Eventlog -list)

The complete script is shown here:

$bootTime = (Get-CimInstance win32_Operatingsystem).lastbootuptime

"Boot time is $($bootTime)"

Foreach($log in Get-Eventlog -list)

 {

  "Events from $($log.Log) event log"

  Get-EventLog -LogName $log.Log -After $bootTime -Before $bootTime.AddMinutes(5) -ea 0

  }

When I run the script, the following output appears in the output pane of the Windows PowerShell ISE.

Image of command output

Well, I am going to spend some time looking over this output, and I will probably play with it later. Talk to you tomorrow.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy