Help with filtering


I am trying to get into powershell and have been doing some reading and watching tutorials on it.

One thing I am having difficulty with is understanding when to use what type of filtering.

For example, the 3 following commands all return the same data:
Get-Process -Name explorer
Get-Process | Where-Object -Property Name -EQ “explorer”
Get-Process | Where-Object {$_.Name -EQ “explorer”}
Why and when should one be used over the other?

Is there rule as to which one should be used over the other?

Thanks in advance for any guidance on this.


It probably doesn’t matter. Powershell syntax is highly elastic. The first one might be a little faster. You can also do:

get-process explorer
get-process | where name -eq explorer

Yep, it matters which one you’d use.

Slow Code: Top 5 Ways to Make Your PowerShell Scripts Run Faster
Slow Code: Top 5 Ways to Make Your PowerShell Scripts Run Faster | Microsoft Docs

Filter Using Parameters Instead of Where-Object When Possible
Filter Using Parameters Instead of Where-Object When Possible | Learn Powershell | Achieve More

Filtering early is definitely faster, even if it’s only about 100 milliseconds in this case.

PS /Users/js> measure-command { ps trustd }                                                                      

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 18
Ticks             : 184870
TotalDays         : 2.13969907407407E-07
TotalHours        : 5.13527777777778E-06
TotalMinutes      : 0.000308116666666667
TotalSeconds      : 0.018487
TotalMilliseconds : 18.487

PS /Users/js> measure-command { ps | where name -eq trustd }                                                     

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 120
Ticks             : 1206590
TotalDays         : 1.3965162037037E-06
TotalHours        : 3.35163888888889E-05
TotalMinutes      : 0.00201098333333333
TotalSeconds      : 0.120659
TotalMilliseconds : 120.659

This is applying a filter when processes are retrieved, so you are getting only the process(es) that meet the search criteria:

Get-Process -Name Explorer

This is returning ALL processes and then you are piping it to another command to filter the process(es) that meet the search criteria. The example is using standard or what I would consider a more strongly-typed code. This example will work in Powershell 1.0 going forward.

Get-Process | Where-Object -FilterScript {$_.Name -eq "Explorer"}

This example is using more of a short-hand approach where administrators didn’t want to include the {} and wanted a simple way to where. It was introduced in Powershell 3.0, so if you wrote a script and tried this on 2.0 it would error. If I was going to release a tool or code for others to use, I always use strongly-typed code to ensure it works the same.

Get-Process | Where-Object -Property Name -eq "explorer"

The biggest difference between the first and second examples, as others have posted is performance. If you have 150 processes and only want one, why would you return all of them and then try to get only those versus just getting the 3 you need. Processes is one thing, but this comes into play very quickly in systems like AD. If you have 30k users and do:

Get-ADUser -Filter * | Where {$_.SamAccountName -eq 'rob'}

Your returning EVERY user in AD and then getting one user, which isn’t efficient, so you should filter left to only return what you are looking for:

Get-ADUser -Filter {SamAccountName -eq 'rob'}

This is getting a little off topic, but does anyone know why the system user on a domain-joined machine will return EVERY DOMAIN USER with this command (Windows 10):

get-wmiobject win32_useraccount

Much faster this way, but I don’t think of the system user is being a member of a domain:

get-wmiobject win32_useraccount -filter 'localaccount = true'

Yes, but you should start your own thread for your issue.