查询关闭事件1074时,使用Get-WinEvent / Get-EventLog进行事件日志查询非常慢

时间:2020-03-09 13:36:45

标签: windows powershell

我正在编写一个PowerShell脚本,该脚本需要能够获取查询System事件日志并使用Event ID 1074查找指示关闭的事件。

为此,我使用了以下代码,但是,我注意到,在具有更大System事件日志的服务器上运行代码时,该命令需要花费很长时间才能完成。

Get-WinEvent -LogName 'System' | Where-Object { $_.Id -eq 1074 }

有没有办法改善这段代码的性能?

1 个答案:

答案 0 :(得分:3)

Get-WinEvent与Get-EventLog

Get-WinEvent相比,使用Get-EventLog可获得的第一项性能提升。这是因为Get-WinEvent取代了Get-EventLogis supposed to perform better

正确过滤查询

我发现了一个fantastic article by Ed Wilson,其中非常详细地介绍了如何提高查询的性能,例如我上面发布的查询。我将重点介绍为大幅提高脚本性能而进行的性能调整。

  1. 请勿使用-LogName参数,而应使用生成您要查找的事件的提供程序的适当-ProviderName(Ed的博客文章详细介绍了如何找到此事件)。就我而言,我需要使用User32提供程序,因为那是生成我感兴趣的1074事件的提供程序。
  2. 尽可能避免完全遍历数据。您会注意到我的脚本有一个Where-Object子句。此子句将遍历传入它的所有事件,仅查找具有1074 ID的事件。为避免这种情况,Get-WinEvent具有-FilterHashtable parameter,可用于过滤Get-WinEvent cmdlet中的查询结果,从而提高效率。正如Microsoft文档中引用的那样: “使用大型事件日志时,将对象沿管道发送到Where-Object命令效率不高。”

代码

我已经实现了上述概念,并使用Measure-Command cmdlet和-Expression参数对每个概念进行了改进,以显示性能差异。请注意,我正在测试的计算机在System日志中有23,581个事件。

基线

Measure-Command -Expression {
    Get-WinEvent -LogName 'System' | Where-Object { $_.Id -eq 1074 }
}

# TotalSeconds      : 7.600536

使用ProviderNameLogName

Measure-Command -Expression {
    Get-WinEvent -ProviderName 'User32' | Where-Object { $_.Id -eq 1074 }
}

# TotalSeconds      : 0.1929325

使用FilterHashtable

Measure-Command -Expression {
    Get-WinEvent -FilterHashtable @{ProviderName = "User32"; Id = 1074} 
}

# TotalSeconds      : 0.1578928