Search code examples
powershellget-winevent

How to return filtered event log entries for TaskDisplayName = 'Boot Performance Monitoring' using Get-WinEvent in PowerShell


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?


Solution

  • 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