I've been working with Powershell for way too long to have just figured this out. However, here we are...
To query event log information from a remote server, you can use Get-WinEvent. However, I've always found it really slow and not very flexible.
Recently I needed to get events from the Security log related to NTLM v1 authentication and there were about 200,000 events in the security log. The event ID that I needed to evaluate was about half of that. So, I needed to query 100,000 events.
When I used the -FilterHashTable parameter, it took about 10 minutes. That's not a good time. And processing the results also took about 10 minutes.
Many events were not relevant, because I only needed events that referred to NTLM v1 authentication. This reference was in the message and I was doing text processing on the message attribute to find the relevant events.
If you use -FilterXPath, you can refer to items in the message as an attribute and filter based on them. This got my query from 10 minutes down to less than a minute. You can view the attributes available for filtering in the properties of an event in the XML view. What appears as text in the message shows up as specific data names in EventData that you can filter on.
Here is an example of the code:
#Query only events with NTLM V1 (1 min or less per DC) $comp = "XXXXXXX" $xpath = "*[System[EventID=4624] and EventData[Data[@Name='LMPackageName']='NTLM V1']]" $LogonEvents = Get-WinEvent -ComputerName $comp -Credential $cred -FilterXPath $xpath -LogName Security
The filter I used looked for EventID=4624 in the System section of the event. In the EventData portion of the event, it looked for LMPackageName='NTLM v1'. Normally LMPackageName appears in the message portion of the event and it's not filterable. Shown below as Package Name (NTLM only) with a value of -.
So, -FilterXPath is more flexible for filtering which significantly reduces the number of events transferred by Get-WinEvent and provides a huge increase in speed.