Help with filtering

Welcome Forums General PowerShell Q&A Help with filtering

This topic contains 6 replies, has 4 voices, and was last updated by

 
Participant
3 months, 3 weeks ago.

  • Author
    Posts
  • #109925
    Bal

    Participant
    Points: 0
    Rank: Member

    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

  • #109936
    js

    Participant
    Points: 327
    Helping Hand
    Rank: Contributor

    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
  • #109946

    Participant
    Points: 332
    Helping Hand
    Rank: Contributor

    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'

  • #109967
    js

    Participant
    Points: 327
    Helping Hand
    Rank: Contributor

    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
    
  • #109972

    Participant
    Points: 351
    Helping Hand
    Rank: Contributor

    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'}
    
  • #109975
    js

    Participant
    Points: 327
    Helping Hand
    Rank: Contributor

    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'
    
  • #109985

    Participant
    Points: 351
    Helping Hand
    Rank: Contributor

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

The topic ‘Help with filtering’ is closed to new replies.