Reputation: 1388
I'm writing a PowerShell script that needs to be able to get the query the System
Event Log and find events with the Event ID 1074 which indicates a shutdown.
To do this, I was using the following code, however, I've taken notice that when running the code on servers with larger System
Event Logs, the command takes many seconds to complete.
Get-WinEvent -LogName 'System' | Where-Object { $_.Id -eq 1074 }
Is there a way to improve the performance of this code?
Upvotes: 4
Views: 7802
Reputation: 1388
The first performance boost you can get is using Get-WinEvent
over Get-EventLog
. That is because Get-WinEvent
is replacing Get-EventLog
and is supposed to perform better.
I found a fantastic article by Ed Wilson which goes into great detail how you can improve the performance of a query such as the one I've posted above. I will highlight the performance tweaks I made to greatly improve the performance of my script.
-LogName
parameter, but rather, use the appropriate -ProviderName
of the provider that generates the event you're looking for (Ed's blog post goes into detail of how to find this). In my case, I needed to use the User32
provider since that's the provider that generates the 1074
event I'm interested in.Where-Object
clause. This clause would iterate over ever event piped into it looking for only the ones that have the 1074
Id. To avoid this, Get-WinEvent has a -FilterHashtable
parameter which can be used to filter your query results within the Get-WinEvent
cmdlet, improving efficiency. As quoted in the Microsoft documentation: "When you work with large event logs, it's not efficient to send objects down the pipeline to a Where-Object command."I've implemented the aforementioned concepts and timed the improvements for each to show the difference in performance using the Measure-Command
cmdlet with the -Expression
parameter. Note that the machine that I'm testing on has 23,581 events in the System
log.
Measure-Command -Expression {
Get-WinEvent -LogName 'System' | Where-Object { $_.Id -eq 1074 }
}
# TotalSeconds : 7.600536
ProviderName
vs LogName
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
Upvotes: 9