The following code works to return the Windows Log events with ID = 100.
$Date = (Get-Date).AddDays(-30)
Get-WinEvent -FilterHashTable @{ LogName = "Microsoft-Windows-Diagnostics-Performance/Operational"; StartTime = $Date; ID = 100 } -MaxEvents 1 | Select-Object -Property TimeCreated, Id, Task, TaskDisplayName, LevelDisplayName, Message
This code returns an error for the TaskDisplayName = 'Boot Performance Monitoring'
$Date = (Get-Date).AddDays(-30)
Get-WinEvent -FilterHashTable @{ LogName = "Microsoft-Windows-Diagnostics-Performance/Operational"; StartTime = $Date; TaskDisplayName = 'Boot Performance Monitoring' } | Select-Object -Property TimeCreated, Id, Task, TaskDisplayName, LevelDisplayName, Message
Get-WinEvent : No events were found that match the specified selection criteria. At D:\tfsws\TG-Dev-ICSG2\Support\PowerShell Scripts\Get-WinEvent-TEST.ps1:6 char:1 + Get-WinEvent -FilterHashTable @{ LogName = "Microsoft-Windows-Diagnos ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (:) [Get-WinEvent], Exception + FullyQualifiedErrorId : NoMatchingEventsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
How do I make Get-WinEvent accept the TaskDisplayName filter?
Unfortunately you can't use -FilterHashTable
to filter on TaskDisplayName for 2 reasons:
In the Microsoft docs Get-WinEvent valid FilterHashTable values are:
LogName=<String[]>
ProviderName=<String[]>
Path=<String[]>
Keywords=<Long[]>
ID=<Int32[]>
Level=<Int32[]>
StartTime=<DateTime>
EndTime=<DataTime>
UserID=<SID>
Data=<String[]>
TaskDisplayName isn't one of the -FilterHashTable
options.... ok. So next option is to use -FilterXPath
or -FilterXML
which gives us access to some more lower level filtering. For simplicity, I will use -FilterXPath
. In order to find the right keys to filter on, you have to go to the details tab on the event. Here is a sample event:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Diagnostics-Performance" Guid="{CFC18EC0-96B1-4EBA-961B-622CAEE05B0A}" />
<EventID>100</EventID>
<Version>2</Version>
<Level>2</Level>
<Task>4002</Task>
<Opcode>34</Opcode>
<Keywords>0x8000000000010000</Keywords>
<TimeCreated SystemTime="2018-05-23T21:09:42.047563100Z" />
<EventRecordID>8</EventRecordID>
<Correlation ActivityID="{F774E0CC-F2D9-0006-E0FA-74F7D9F2D301}" />
<Execution ProcessID="3876" ThreadID="4980" />
<Channel>Microsoft-Windows-Diagnostics-Performance/Operational</Channel>
<Computer>D4700.adcfcu.connectfirstcu.com</Computer>
<Security UserID="S-1-5-19" />
</System>
<EventData>
<Data Name="BootTsVersion">2</Data>
<Data Name="BootStartTime">2018-05-23T21:06:49.733345200Z</Data>
..........
<Data Name="UserLogonWaitDuration">9415</Data>
</EventData>
</Event>
When you expand it out, you notice that there is no TaskDisplayName
. This is because TaskDisplayName == Task Category
. Ok... let's look for Task Category
... Well there is no Task Category
either. That's because Categories are actually stored numerically in the event, and then mapped into a proper description using an Event Category String. That is why you can't filter based on a TaskDisplayName
or Task Category
. Instead you will have to filter on the Task
number, which you in this case is 4002
. And if you use the StartDate
, which is TimeCreated
, you can calculate that 30 days is 2592000000 miliseconds, then your code becomes:
Get-WinEvent -LogName "Microsoft-Windows-Diagnostics-Performance/Operational" -FilterXPath "*[System[Task=4002 and TimeCreated[timediff(@SystemTime) <= 2592000000]]]" | Select-Object -Property TimeCreated, Id, Task, TaskDisplayName, LevelDisplayName, Message