Author Posts

August 24, 2018 at 8:04 pm

Hi

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.

Bal

August 24, 2018 at 9:05 pm

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

August 24, 2018 at 10:45 pm

Yep, it matters which one you'd use.

PowerShell Performance: Filtering Collections

Slow Code: Top 5 Ways to Make Your PowerShell Scripts Run Faster
'blogs.technet.microsoft.com/ashleymcglone/2017/07/12/slow-code-top-5-ways-to-make-your-powershell-scripts-run-faster'

Filter Using Parameters Instead of Where-Object When Possible
'learn-powershell.net/2012/06/26/filter-using-parameters-instead-of-where-object-when-possible'

August 25, 2018 at 1:16 pm

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

August 25, 2018 at 2:41 pm

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'}

August 25, 2018 at 2:47 pm

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'

August 25, 2018 at 3:09 pm

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