0

以下代码用于返回 ID = 100 的 Windows 日志事件。

$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

此代码返回 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 : 未找到符合指定选择条件的事件。在 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], 异常 + FullyQualifiedErrorId : NoMatchingEventsFound,Microsoft.PowerShell.Commands.GetWinEventCommand

如何让 Get-WinEvent 接受 TaskDisplayName 过滤器?

4

2 回答 2

3

不幸的是,您不能用于-FilterHashTable过滤 TaskDisplayName 有两个原因:

在 Microsoft docs Get-WinEvent中,有效的 FilterHashTable 值为:

  • LogName=<String[]>
  • ProviderName=<String[]>
  • Path=<String[]>
  • Keywords=<Long[]>
  • ID=<Int32[]>
  • Level=<Int32[]>
  • StartTime=<DateTime>
  • EndTime=<DataTime>
  • UserID=<SID>
  • Data=<String[]>

TaskDisplayName 不是-FilterHashTable选项之一....好的。所以下一个选项是使用-FilterXPathor-FilterXML让我们可以访问一些更低级别的过滤。为简单起见,我将使用-FilterXPath. 为了找到正确的过滤键,您必须转到事件的详细信息选项卡。这是一个示例事件:

<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>

当您将其展开时,您会注意到没有TaskDisplayName. 这是因为TaskDisplayName == Task Category. 好吧...让我们寻找Task Category...好吧,也没有Task Category。这是因为类别实际上以数字形式存储在事件中,然后使用事件类别字符串映射到适当的描述中。这就是为什么您不能基于 a 进行过滤的原因TaskDisplayNameor Task Category。相反,您必须过滤Task数字,在这种情况下您是4002. 如果你使用StartDate,也就是TimeCreated,你可以计算出 30 天是 2592000000 毫秒,那么你的代码就变成了:

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
于 2018-08-01T19:39:08.957 回答
1

文档中所述,-FilterHashTable仅允许过滤器子集:

  • 日志名称=
  • 提供者名称=
  • 路径=
  • 关键字=
  • 编号=
  • 等级=
  • 开始时间=
  • 结束时间=
  • 用户 ID=
  • 数据=
  • *=

相反,您可以做的是使用-FilterXML参数创建一个 FilterXML。eventvwr.msc您可以使用(查找和示例事件、从详细信息视图中获取任务编号、配置协议过滤器、切换到“XML”选项卡并复制内容)创建适当的 XML 。

结果将是这样的:

$Filter = @'
<QueryList>
<Query Id="0" Path="Microsoft-Windows-Diagnostics-Performance/Operational">
    <Select Path="Microsoft-Windows-Diagnostics-Performance/Operational">*[System[(EventID=100) and (Task=4002)]]</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXml $Filter

TaskDisplayName 然而不是一个有效的属性,你必须弄清楚Task“引导性能监控”有多少。请注意,该任务4002不是您要查找的任务。这只是我的事件日志中唯一可用的数字。;)

或者,但性能不佳且不推荐(一般规则:向左过滤),您可以使用示例命令并添加Where-Object过滤器。

$FitlerHashTable =  @{ 
    LogName = "Microsoft-Windows-Diagnostics-Performance/Operational"
    StartTime = $Date
    ID = 100
}
Get-WinEvent -FilterHashTable $FitlerHashTable -MaxEvents 1 | 
Where-Object { $_.Task -eq 4002 } | 
Select-Object -Property TimeCreated, Id, Task, TaskDisplayName, LevelDisplayName, Message
于 2018-08-01T19:31:39.513 回答