Query and Export Windows Event Logs using PowerShell

Windows Event viewer/Event Log is one of the important tools for system administrators to troubleshoot system-related issues and track suspicious activities. You can simply open the Event viewer and check the logs, but sometimes we need to use PowerShell to efficiently query and filter the events.

We can use the Get-WinEvent cmdlet to get events from event logs and event trace log files on local and remote computers. Before you start, open the PowerShell with “Run as administrator” permission since some of the logs (ex: Security log) requires elevated privilege.

Summary

List all logs – Log names and configuration

Events are logged under different log categories such as Application, System, etc. The Get-WinEvent cmdlet uses the ListLog parameter to retrieve the specific log information, we can provide the asterisk (*) wildcard to this parameter to list all the available logs. The below command gets the available logs on the local computer.

Get-WinEvent -ListLog *

If you’re not running PowerShell as an Administrator, you will get the below error message for the logs which require Run as administrator privilege.

Get-WinEvent : Could not retrieve information about the Security log. Error: Attempted to perform an unauthorized operation.

Get all events from a specific event Log

The Get-WinEvent cmdlet uses the LogName parameter to specify the event logs (ex: Application, Security) that this cmdlet gets events from. We can provide a single event log name or enter the log names in a comma-separated list. Wildcards are also permitted (ex: Get-WinEvent -LogName *PowerShell*).

The below command retrieves the latest 100 events from the Application log.

Get-WinEvent -LogName 'Application' -MaxEvents 100

Run the below command to get the events from the Security log.

Get-WinEvent -LogName 'Security' -MaxEvents 100

The below command gets the events from the Windows PowerShell and Setup logs. The log names are provided as comma-separated values. The command returns the number of events that are grouped by the Level such as Error or Warning and the log name.

Get-WinEvent -LogName 'Windows PowerShell', 'Setup' |
  Group-Object -Property LevelDisplayName, LogName -NoElement | Format-Table -AutoSize

Use Basic Filter to Query and Search Event Log

The Get-WinEvent cmdlet retrieves all events from the given Event log. In some cases, this will lead to thousands of event messages, and we can’t be able to easily locate the required event. We need to apply the required filter while querying the events.

We can use the Where-Object cmdlet to filter the retrieved events. This will provide the required result, but the filters are applied after the objects are retrieved from the log. In other words, this is a client-side filter, and we may face performance degradation if the log contains a large number of events.

#Get events for last 30 days from Setup log
$StartDate = (Get-Date) - (New-TimeSpan -Day 30) 
Get-WinEvent -LogName 'Setup' | Where-Object { $_.TimeCreated -ge $StartDate }

For better performance, we can use the server-side filters supported by the Get-WinEvent cmdlet, such as FilterHashtable (Basic) and FilterXML (Advanced).

Filter events on the server-side using the FilterHashtable parameter

The FilterHashtable parameter specifies a query in hash table format to select events from one or more event logs. The below command fetches the events for the last 2 days from the Application log.

$StartDate = (Get-Date).AddDays(-2)
Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$StartDate;}

We can also filter the events by an Event ID value. Run the following command to retrieve the logon events (4624) from the Security log.

$StartDate = (Get-Date).AddDays(-2)	
Get-WinEvent -FilterHashtable @{ LogName='Security'; StartTime=$StartDate; Id='4624'}

This command uses the FilterHashtable parameter to find events generated in the last 10 days by Windows Installer (‘MsiInstaller’).

$StartDate = (Get-Date).AddDays(-10)	
Get-WinEvent -FilterHashtable @{ Logname='Application';ProviderName='MsiInstaller';StartTime=$StartDate }

For more information about the FilterHashtable parameter, see How to create Get-WinEvent queries with FilterHashtable.

Use Advanced Filter to Query and Search Event Log

You can create a basic level filter using the FilterHashtable parameter, but we need to use the FilterXml parameter for complex queries with multiple conditions. The FilterXml parameter can be used to search events on the server side by using a structured XML query.

The below command retrieves the Critical, Error, and Warning level events for the last 30 days from the Application log.

#Using the FilterXML parameter:
$xmlQuery = @'
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[(Level=1  or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 2592000000]]]</Select>
  </Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQuery

The tricky part with this method is creating the XML query for your requirement. To create a valid XML query, use the Create Custom View and Filter Current Log features in Windows Event Viewer.

Follow the below steps to generate a valid XML query using Windows Event Viewer.

  • Open the Event Viewer (open the Run window, type eventvwr.msc, and press the ENTER key).
  • On the left-hand side, right-click on Custom Views and select Create Custom View option.
  • Select time interval (Logged – Last 7 days) and select the required Event levels to filter such as Critical, Error, and Warning.
  • Choose the By Log option and select System under Windows Logs. Add more filter options if needed. 
  • Finally, click the XML tab to view the query in XML format. You can copy the XML query from the XML tab (Ctrl+A and Ctrl+C) and use the value in the FilterXml parameter.

This command gets the events for the last 7 days from the System log. The XML query filters the events with the event levels Critical, Error, and Warning.

#Using the FilterXML parameter:
$xmlQuery = @'
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[(Level=1  or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]</Select>
  </Query>
</QueryList>
'@
Get-WinEvent -FilterXML $xmlQuery 

Export event logs to a CSV file

Once we retrieved the required events, we can export the log result to a CSV file using the Export-CSV cmdlet. The following command queries the events (exclude the Level 4 events – Information) from the System log for the last 30 days and exports the result to a CSV file.

$xmlQuery = @'
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[(Level=1  or Level=2 or Level=3 or Level=5) and TimeCreated[timediff(@SystemTime) &lt;= 2592000000]]]</Select>
  </Query>
</QueryList>
'@

#Get events with FilterXML
$Events= Get-WinEvent -FilterXML $xmlQuery 

#Export the System events to the CSV file
$Events | Export-CSV "C:\Temp\SystemEvents.CSV" -NoTypeInformation -Encoding UTF8

The following command exports the Critical, Error, and Warning level events for the last 30 days from the Application log.

$xmlQuery = @'
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[(Level=1  or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 2592000000]]]</Select>
  </Query>
</QueryList>
'@

#Get events with FilterXML
$Events= Get-WinEvent -FilterXML $xmlQuery 

#Export the Application events to the CSV file
$Events | Export-CSV "C:\Temp\ApplicationEvents.CSV" -NoTypeInformation -Encoding UTF8
Advertisement