Where-Object is a cmdlet used for filtering objects in the pipe. Where-Object is placed in between commands and can remove objects that do not meet the criteria. Where-Object takes an object from the pipeline and filters all objects that do not meet the filter_expression.

# General data flow:
Cmdlet | Where-Object { filter_expression } | Cmdlet

Where-Object returns the objects that match the specified condition. The filter includes (filter-in) the desired objects into the output.

When should Where-Object be used?

Where-Object can be used at any point in the pipeline for removing objects out of the pipeline. However, the best practice is to filter as soon as possible earliest in the pipeline.

For example, we want all the .txt files in our directory, we can use Where-Object:

ls | Where-Object { $_.Name -like "*.txt" }

However, ideally, we filter as soon as possible earliest in the pipeline, removing the need for filtering with Where-Object:

ls -Filter '*.txt'

# or simply:
ls *.txt

This is better practice, as there is less data flowing between cmdlets and less processing that needs to be done in later stages of the pipeline, thus better performance.

In general, look for a -Filter parameter in the cmdlets earlier in the pipe to reduce the need for Where-Object.

ℹ️ Get-ChildItem (i.e., ls) has -Filter but because its a positional parameter it does not need to be explicitly named, but can be if needed.

How to use Where-Object

The general syntax of Where-Object is:

Where-Object { filter_expression }
  • Input: objects
  • Output: objects picked by filter_expression

One good use case is dealing with CSV files.

Where-Object Example: Working with CSV files

Example CSV file:

Name,Id,Job
Alice,100,CTO
Bill,101,Software Engineer II
Carol,102,Software Engineer III
David,105,Software Engineer V
Ethan,200,Software Engineer VI
Fifi,205,Software Engineer VII

The CSV file can be loaded into an object by using Import-Csv:

Import-Csv .\data.csv

Output:

Name  Id  Job
----  --  ---
Alice 100 CTO
Bill  101 Software Engineer II
Carol 102 Software Engineer III
David 105 Software Engineer V
Ethan 200 Software Engineer VI
Fifi  205 Software Engineer VII

The CSV file can be loaded into an object (done by Import-Csv) and passed further into the pipeline into Where-Object will do filtering.

For example, find the “Name” that equals David:

Import-Csv .\data.csv | Where-Object { $_.Name -eq 'David' }

Output:

Name  Id  Job
----  --  ---
David 105 Software Engineer V

Find all objects that Id is greater or equal to 200:

Import-Csv .\data.csv | Where-Object { $_.Id -ge 200 }

Output:

Name  Id  Job
----  --  ---
Ethan 200 Software Engineer VI
Fifi  205 Software Engineer VII

Where-Object filter wildcards

Wild card filtering with -Like. For example, find objects that their Job begins with “Software Engineer”:

Import-Csv .\data.csv | Where-Object { $_.Job -like 'Software Engineer*' }

Output:

Name  Id  Job
----  --  ---
Bill  101 Software Engineer II
Carol 102 Software Engineer III
David 105 Software Engineer V
Ethan 200 Software Engineer VI
Fifi  205 Software Engineer VII

Where-Object filter regex

We can do regex filtering with -match, let’s do the previous wild card example but with regex:

Import-Csv .\data.csv | Where-Object { $_.Job -match "Software Engineer.*" }

Output:

Name  Id  Job
----  --  ---
Bill  101 Software Engineer II
Carol 102 Software Engineer III
David 105 Software Engineer V
Ethan 200 Software Engineer VI
Fifi  205 Software Engineer VII

Where-Object filter not equal to

We can do the opposite of -Like and -Match using -NotLike and -NotMatch respectively. For example, we want to get all objects that don’t have the Job “Software Engineer”:

Import-Csv .\data.csv | Where-Object { $_.Job -NotMatch "Software Engineer.*" }

Output:

Name  Id  Job
----  --  ---
Alice 100 CTO

That’s all for now, peace ✌️