One topic that came up during my talk at Deep Dive was the speed of running a WQL vs using –Filter in Get-WmiObject. I’d never tested it so its time to find out.
PowerShell v2 has a handy cmdlet called Measure-Command that times how long a command runs
We’ll start with using a filter
Get-WmiObject -Class Win32_Process -Filter "Name='Notepad.exe'"
if we wrap it in Measure-Command we get this
Measure-Command -Expression {Get-WmiObject -Class Win32_Process -Filter "Name='Notepad.exe'"}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 81
Ticks : 817436
TotalDays : 9.46106481481481E-07
TotalHours : 2.27065555555556E-05
TotalMinutes : 0.00136239333333333
TotalSeconds : 0.0817436
TotalMilliseconds : 81.7436
We want the TotalMilliseconds property and we need to do it more than once
1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process -Filter "Name='Notepad.exe'"}} |
Measure-Object -Property TotalMilliseconds -Average
Count : 100
Average : 52.640332
Sum :
Maximum :
Minimum :
Property : TotalMilliseconds
Now lets repeat as a query
Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name='Notepad.exe'"
which becomes
Measure-Command -Expression {Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name='Notepad.exe'"}
1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Query "SELECT * FROM Win32_Process WHERE Name='Notepad.exe'"}} |
Measure-Object -Property TotalMilliseconds -Average
Count : 100
Average : 52.345972
Sum :
Maximum :
Minimum :
Property : TotalMilliseconds
Just for fun lets try this
1..100 | foreach {Measure-Command -Expression {Get-WmiObject -Class Win32_Process | Where {$_.Name -eq 'Notepad.exe'} }} |
Measure-Object -Property TotalMilliseconds -Average
Count : 100
Average : 92.96794
Sum :
Maximum :
Minimum :
Property : TotalMilliseconds
So the results so far
Filter: 52.640332
Query: 52.345972
Where: 92.96794
The filter and the query are almost the same – I’m not going to argue over 0.03 milliseconds. Using Where-Object takes nearly twice as long. This is understandable because the query and filter pick out a single process but using Where-Object we return all processes and then filter.
I stated in my talk that it was better to use the filter because it was less typing. On these results I’ll stand by that statement for local machines as it takes me more than a few milliseconds to type the extra characters using a query.
Further research is needed:
- What happens if running against remote machines?
- is it faster to select properties in the query or using select-object
We’ll return to these points later