Skip to main content

Querying Event Logs

I noticed that there is a huge speed difference between using an XML Query and PowerShell Get-EventLog piped through Where-Object to filter event logs. Thanks to this article, I learned how to use the XML Query via PowerShell, so you get the best of both worlds.

General concepts

Get-EventLog

# Show available event logs and stats
Get-EventLog -List



# get the most recent 10 log entries
Get-EventLog -LogName Application -Newest 10
Get-EventLog -LogName Security -Newest 10
Get-EventLog -LogName System -Newest 10



# get all system logs from the last 24 hours
Get-EventLog -LogName system -after (Get-Date).AddDays(-1)

# get WLAN-AutoConfig system logs from the last 24 hours
Get-EventLog -LogName system -after (Get-Date).AddDays(-1) -Source Microsoft-Windows-WLAN-AutoConfig



# Get list of Event Log Sources from the System log
Get-EventLog -LogName System | Group-Object -Property Source -NoElement | Select-Object -Property Count, Name | Sort-Object -Descending Count

# Get list of Event Log Sources from the last 24 hours
Get-EventLog -LogName System -after (Get-Date).AddDays(-1) | Group-Object -Property Source -NoElement | Select-Object -Property Count, Name | Sort-Object -Descending Count

Get-WinEvent

Get-WinEvent -FilterHashtable @{
   LogName='Application'
   ProviderName='.NET Runtime'
   Keywords=36028797018963968
   ID=1023
   Level=2
}

Viewing a specific event

Get-EventLog -LogName Application -Index [Event_Index_Number] | Format-List

Querying for specific logs

System uptime related logs

Kernel-General "The operating system started at system time..."

<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">
      *[System[(EventID='12')]] 
    </Select>
  </Query>
</QueryList>

Actual log message

Log Name:      System
Source:        Microsoft-Windows-Kernel-General
Date:          5/30/2023 7:48:33 PM
Event ID:      12
Task Category: (1)
Level:         Information
Keywords:      (128)
User:          SYSTEM
Computer:      [REDACTED]
Description:
The operating system started at system time ‎2023‎-‎05‎-‎31T02:48:32.500000000Z.
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Microsoft-Windows-Kernel-General" Guid="{a68ca8b7-004f-d7b6-a698-07e2de0f1f5d}" />
    <EventID>12</EventID>
    <Version>0</Version>
    <Level>4</Level>
    <Task>1</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8000000000000080</Keywords>
    <TimeCreated SystemTime="2023-05-31T02:48:33.1346923Z" />
    <EventRecordID>74715</EventRecordID>
    <Correlation />
    <Execution ProcessID="4" ThreadID="8" />
    <Channel>System</Channel>
    <Computer>[REDACTED]</Computer>
    <Security UserID="S-1-5-18" />
  </System>
  <EventData>
    <Data Name="MajorVersion">10</Data>
    <Data Name="MinorVersion">0</Data>
    <Data Name="BuildVersion">19041</Data>
    <Data Name="QfeVersion">2075</Data>
    <Data Name="ServiceVersion">0</Data>
    <Data Name="BootMode">0</Data>
    <Data Name="StartTime">2023-05-31T02:48:32.5000000Z</Data>
  </EventData>
</Event>

Finding account lockouts.

XML Query

Use this query in the Windows Event Viewer

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[
        System[(EventID='4740')]
      ] 
    </Select>
  </Query>
</QueryList>

PowerShell Script - Slow method

Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4740} |
   Select-Object -Property TimeGenerated, Source, EventID, InstanceId, Message

PowerShell Script - Fast method

$query = @"
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[
        System[(EventID='4740')]
      ] 
    </Select>
  </Query>
</QueryList>
"@

Get-WinEvent -FilterXml $query | Format-List

Finding account lockouts for a particular user.

XML Query

<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[
        EventData[Data[@Name='TargetUserName']='administrator']
        and
        System[(EventID='4740')]
      ] 
    </Select>
  </Query>
</QueryList>

PowerShell Script - Fast method

$query = @"
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[
        EventData[Data[@Name='TargetUserName']='administrator']
        and
        System[(EventID='4740')]
      ] 
    </Select>
  </Query>
</QueryList>
"@

Get-WinEvent -FilterXml $query | Format-List

NPS + Azure MFA Logs - XML Query

Suppresses accounting event logs.

<QueryXML>
	<QueryList>
	  <Query Id="0" Path="System">
		<Select Path="System">*[System[Provider[@Name='NPS']]]</Select>
		<Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 12552]]</Select>
		<Suppress Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 12552 and (Data='Network Policy Server discarded the accounting request for a user.')]]</Suppress>
		<Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and *[EventData[Data[@Name='LogonProcessName'] and (Data='IAS')]]</Select>
		<Select Path="AuthNOptCh">*</Select>
		<Select Path="AuthZAdminCh">*</Select>
		<Select Path="AuthZOptCh">*</Select>
	  </Query>
	</QueryList>
</QueryXML>

NPS Logs - XML Query

Suppresses accounting event logs.

<QueryXML>
	<QueryList>
	  <Query Id="0" Path="System">
		<Select Path="System">*[System[Provider[@Name='NPS']]]</Select>
		<Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 12552]]</Select>
		<Suppress Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and Task = 12552 and (Data='Network Policy Server discarded the accounting request for a user.')]]</Suppress>
		<Select Path="Security">*[System[Provider[@Name='Microsoft-Windows-Security-Auditing']]] and *[EventData[Data[@Name='LogonProcessName'] and (Data='IAS')]]</Select>
	  </Query>
	</QueryList>
</QueryXML>

Disk logs

XML Query

<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[Provider[@Name='disk']]]</Select>
  </Query>
</QueryList>

VPN Client Logs

PowerShell Query

$query = @"
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[Provider[@Name='RasAuto' or @Name='RasCfg' or @Name='RasClient' or @Name='Rasman' or @Name='Microsoft-Windows-RasServer' or @Name='Microsoft-Windows-RasSstp' or @Name='Microsoft-Windows-EapMethods-RasChap' or @Name='Microsoft-Windows-NcdAutoSetup' or @Name='Microsoft-Windows-NCSI' or @Name='Microsoft-Windows-NetworkProfile']]]</Select>
    <Select Path="System">*[System[Provider[@Name='RasAuto' or @Name='RasCfg' or @Name='RasClient' or @Name='Rasman' or @Name='Microsoft-Windows-RasServer' or @Name='Microsoft-Windows-RasSstp' or @Name='Microsoft-Windows-EapMethods-RasChap' or @Name='Microsoft-Windows-NcdAutoSetup' or @Name='Microsoft-Windows-NCSI' or @Name='Microsoft-Windows-NetworkProfile']]]</Select>
  </Query>
</QueryList>
"@

Get-WinEvent -FilterXml $query | Format-List

XML Query

<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[Provider[@Name='RasAuto' or @Name='RasCfg' or @Name='RasClient' or @Name='Rasman' or @Name='Microsoft-Windows-RasServer' or @Name='Microsoft-Windows-RasSstp' or @Name='Microsoft-Windows-EapMethods-RasChap' or @Name='Microsoft-Windows-NcdAutoSetup' or @Name='Microsoft-Windows-NCSI' or @Name='Microsoft-Windows-NetworkProfile']]]</Select>
    <Select Path="System">*[System[Provider[@Name='RasAuto' or @Name='RasCfg' or @Name='RasClient' or @Name='Rasman' or @Name='Microsoft-Windows-RasServer' or @Name='Microsoft-Windows-RasSstp' or @Name='Microsoft-Windows-EapMethods-RasChap' or @Name='Microsoft-Windows-NcdAutoSetup' or @Name='Microsoft-Windows-NCSI' or @Name='Microsoft-Windows-NetworkProfile']]]</Select>
  </Query>
</QueryList>

Searching for WLAN-AutoConfig related errors

Original source

#Powershell
$addhours = 12;

# Setup filter for error only logs
$filter = @{ LogName = "Microsoft-Windows-WLAN-AutoConfig/Operational"
StartTime = [DateTime]::Now.AddHours($addhours*-1)
EndTime = [DateTime]::Now
Level = 2
}

Write-Host ([DateTime]::Now.AddHours($addhours*-1))

Write-Host ([DateTime]::Now)

$Events = Get-Winevent -FilterHashtable $filter



# Parse out the event message data            
ForEach ($Event in $Events) {            
	# Convert the event to XML            
	$eventXML = [xml]$Event.ToXml()            
	# Iterate through each one of the XML message properties            
	For ($i=0; $i -lt $eventXML.Event.EventData.Data.Count; $i++) {            
		# Append these as object properties            
		Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name $eventXML.Event.EventData.Data[$i].name -Value $eventXML.Event.EventData.Data[$i].'#text'            
	}            
}       

$Events | Select-Object id, MachineName, ProcessId,TimeCreated, Adapter, LocalMac, SSID, Cipher, Auth, PeerMac | Format-List

Sources: 1