windows - 使用 Get-WinEvent / Get-EventLog 查询事件日志在查询关机事件 1074 时非常慢
问题描述
我正在编写一个 PowerShell 脚本,该脚本需要能够获取System
事件日志的查询并找到事件 ID 为 1074的事件,该事件表示关闭。
为此,我使用了以下代码,但是,我注意到在具有较大System
事件日志的服务器上运行代码时,该命令需要几秒钟才能完成。
Get-WinEvent -LogName 'System' | Where-Object { $_.Id -eq 1074 }
有没有办法提高这段代码的性能?
解决方案
Get-WinEvent 与 Get-EventLog
您可以获得的第一个性能提升是使用Get-WinEvent
over Get-EventLog
。那是因为Get-WinEvent
正在更换Get-EventLog
并且应该表现更好。
正确过滤查询
我找到了Ed Wilson 的一篇精彩文章,其中详细介绍了如何提高查询的性能,例如我在上面发布的查询。我将重点介绍我为大大提高脚本性能所做的性能调整。
- 不要使用
-LogName
参数,而是使用-ProviderName
生成您要查找的事件的提供程序的适当参数(Ed 的博客文章详细介绍了如何找到它)。就我而言,我需要使用User32
提供程序,因为它是生成1074
我感兴趣的事件的提供程序。 - 尽可能避免完全遍历数据。你会注意到我的脚本有一个
Where-Object
子句。该子句将遍历输入它的所有事件,仅查找具有1074
Id 的事件。为避免这种情况,Get-WinEvent 有一个-FilterHashtable
参数,可用于在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
使用ProviderName
vsLogName
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
推荐阅读
- android - 如何处理 android chrome URL 栏下推网站?
- javascript - JavaScript 从另一个对象更新对象值
- apache-spark - 如何在特定位置向 PySpark Dataframe 添加多个空列
- spring-boot - Spring Boot 2 升级后授权服务器返回“必须向客户端注册至少一个 redirect_uri”。
- javascript - Angular 7.2.0:类型“字符串”不可分配给类型“RunGuardsAndResolvers”
- python - 返回 100 个特定姓氏的记录
- reactjs - React js PrivateRoute 显示隐藏基于 JSON Web 令牌和 fetch 调用的仪表板组件
- bash - 文件中多个参数的计数器
- qt - Qml 注册类型的构造函数中的发射信号不起作用
- python - Merging two dataframe by date