How To Search the Windows Event Log with PowerShell

Windows logs a lot of information to the Event Log which means that the event log contains a wealth of useful for troubleshooting. Assisting Windows users and system administrators alike, the event log offers the ability to understand when something goes wrong and why. Of course, with all that information, it can be difficult to search and understand. For many system administrators, this issue is compounded by often having to search multiple systems, and if done manually through the user interface, this could take a long time.

PowerShell offers native cmdlets that allow you to quickly search for just what you want to find in the Windows Event Log. The ability to filter results and return just what is needed helps to focus your troubleshooting efforts in just the right place.

Searching the Event Log Using Get-WinEvent

The PowerShell cmdlet that enables searching of the event log is the aptly named Get-WinEvent. This will retrieve the event log entries based on the parameters that you pass. Let’s demonstrate the basic searching of the Application event log – by default, the Get-WinEvent cmdlet will return the newest entry, this can be reversed by passing the -Oldest parameter. As you can also see, by default, the events are grouped by the provider.

Get-WinEvent -LogName 'Application' -MaxEvents 10
Untitled 29
Returning grouped results from the Application event log.

To list all available logs for you to search, you can use the -ListLog * parameter as shown below. Keep in mind that there will be a lot of logs. You may also see logs that have an error, this is typically because those logs are only accessible by the administrator account. If you run PowerShell elevated, you should not see this error.

$Results = Get-WinEvent -ListLog *
$Results | Select-Object -First 15
Untitled 30
Showing the first 15 results from the available event logs.

By saving the logs to a variable it decreases the time needed to search for the correct log, later on, which also weeds out logs that may be inaccessible due to access.

Filtering by Hashtable

What if we want to only return log entries between a certain date? Unlike the old Get-EventLog cmdlet, which is deprecated, there is no date specific parameters. There are two ways to filter the results through the cmdlet using XPath code or via a hashtable. The easiest method is using the hashtable approach as shown below.

$StartDate = (Get-Date).AddDays(-3)
$Logs = Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$StartDate; }
$Logs.Count
Untitled 31
Demonstrating the ability to filter by date and time using the Get-WinEvent cmdlet.

Even three days of logs can result in a lot of logs to examine. This is why filtering is very important to try and narrow down the results to just what is needed. Shifting the days returned to just one day prior shortens the results to just 940.

This is helpful, but still too much, so it would be helpful to limit the results by provider as well. Perhaps we want to find Windows Error Reporting entries? We can limit to just that provider in the time window provider by using additional key values.

$StartDate = (Get-Date).AddDays(-3)
$ProviderName = 'Windows Error Reporting'
$Logs = Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$StartDate; ProviderName=$ProviderName; }
$Logs.Count
Untitled 32
Additional filtering by the provider name using the Get-WinEvent cmdlet.

As you can see by using filters to narrow down just what we want we can quickly discover the results that we need.

Filtering by XPath

By far the more difficult way to filter events in Get-WinEvent is using the -FilterXPath parameter which utilizes the XPath language. To demonstrate the same example as above, let’s show what this looks like using this XML language.

Get-WinEvent -FilterXPath "*[System[Provider[@Name='Windows Error Reporting'] and TimeCreated[timediff(@SystemTime) <= 86400000]]]" -LogName 'Application'
Untitled 33
Demonstrating using XPath to filter the results.

One other parameter to touch on is the -FilterXML parameter. Functionally, this is very similar to the -FilterXPath parameter but it is a bit more verbose. This includes the additional XML structure that is used by the Event Log if you really need to customize the query. An example is shown below. You may note that the XPath section is in the Select node, which we use to pass to the -FilterXPath parameter.

<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[Provider[@Name='Windows Error Reporting'] and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]</Select>
  </Query>
</QueryList>

A very useful trick is to easily generate either the XPath or the full XML query, you can use the Filter section in the Windows Event Log GUI. After you click on Filter and setup your query, you can click on the XML tab and use that result with the Get-WinEvent cmdlet.

Untitled 34
                      The Event Log viewer XML view of the filter.

Conclusion

Using Get-WinEvent is a powerful tool to query the Windows Event Log. Using this built-in cmdlet in Windows PowerShell and PowerShell 7 allows you to locate just the entries you are looking for in the event log. This makes the job of a system administrator, that much easier to troubleshoot a system and find the potential issues!

Related content