Using Where-Object in PowerShell

You do a lot of Filtering output in PowerShell, primarily using the Where-Object cmdlet. This blog post will show you a few ways to do that. And that you shouldn’t use the “old” method when filtering only one property 😉

What does Where-Object do?

“The Where-Object cmdlet selects objects that have particular property values from the collection of objects that are passed to it. For example, you can use the Where-Object cmdlet to select files that were created after a certain date, events with a particular ID, or computers that use a particular version of Windows.”

Source: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.4#description

The #1 reason you shouldn’t use it for

I wrote it in a blog post a while back here, but you should always try to filter as much data as possible before letting Where-Object filter the returned data. It’s just faster!

The old and new methods with one filter

I often see Where-Object used in the old “method” when filtering just one property. This is a method that was valid until PowerShell v3.0.

The syntax was:

C:\Users\HarmVeenstra> Get-ChildItem | Where-Object {$_.Name -match "Update"}

        Directory: C:\Users\HarmVeenstra


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         5-11-2023     19:37            101 update.ps1

The new syntax from PowerShell v3.0 and higher is:

C:\Users\HarmVeenstra> Get-ChildItem | Where-Object Name -match "Update"

        Directory: C:\Users\HarmVeenstra


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         5-11-2023     19:37            101 update.ps1

It saves a few characters and seems less complicated for the starting PowerShell user 😉

Using Where-Object with multiple filters

In the example above, only one property was filtered for something specific (In the example, I searched for any file in the current directory that has an update in its filename). But what if you want to filter on multiple properties?

Filtering for all files with “update” in its name and with the “.ps1” file extension:

C:\Users\HarmVeenstra> Get-ChildItem | Where-Object {$_.Name -match "Update" -and $_.Name -match "ps1"}

        Directory: C:\Users\HarmVeenstra


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         5-11-2023     19:37            101 update.ps1

Filtering for all files with “update” in their name or with the “.ps1” file extension will also show files with update in their name.

C:\Users\HarmVeenstra> Get-ChildItem | Where-Object {$_.Name -match "Update" -or $_.Name -match "ps1"}

        Directory: C:\Users\HarmVeenstra


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         12-1-2024     16:56              0 test.ps1
-a---         12-1-2024     16:53              0 testupdate.txt
-a---         5-11-2023     19:37            101 update.ps1

Using Where-Object with multiple conditions

You can also use multiple conditions when filtering in a ScriptBlock format. In the example below, I search for files matching the name “Untitled” and have the “png” extension, but with an extra filter only showing files older than 120 days using the LastWriteTime property.

C:\Temp> Get-ChildItem | Where-Object {($_.Name -match "Untitled" -and $_.Name -match "png") -and $_.LastWriteTime -lt (Get-Date).AddDays(-120)}

        Directory: C:\Temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         23-9-2021     23:06       16008812 Untitled.4png.png
-a---         5-10-2021     23:33          45190 Untitled1.png
-a---         16-6-2022     21:28        1582520 Untitled23123.png
-a---          9-6-2022     20:23          19832 Untitled4.png

It retrieved four files in total. Without the extra filter on the LastWriteTime property, it would show these six files in total:

C:\Temp> Get-ChildItem | Where-Object {$_.Name -match "Untitled" -and $_.Name -match "png"}

        Directory: C:\Temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---         23-9-2021     23:06       16008812 Untitled.4png.png
-a---        10-12-2023     21:25           9936 Untitled.png
-a---         5-10-2021     23:33          45190 Untitled1.png
-a---         5-10-2023     11:13         360114 Untitled2.png
-a---         16-6-2022     21:28        1582520 Untitled23123.png
-a---          9-6-2022     20:23          19832 Untitled4.png

Wrapping up

In the examples above, I showed you how the filter properties retrieve only the things you want using Where-Object. If needed, you can filter for one or more properties with multiple conditions. You can find more information about the parameters with some extra examples.

2 thoughts on “Using Where-Object in PowerShell

  1. I always get confused when doing multiple operators and when to wrap it within the script block.

    C:\Users\HarmVeenstra> Get-ChildItem | Where-Object {$.Name -match “Update” -or $.Name -match “ps1”}

    Directory: C:\Users\HarmVeenstra

    Mode LastWriteTime Length Name
    —- ————- —— —-
    -a— 12-1-2024 16:56 0 test.ps1
    -a— 12-1-2024 16:53 0 testupdate.txt
    -a— 5-11-2023 19:37 101 update.ps1

    Is that example looks like you did 3 operators, but didn’t wrap it.

Leave a Reply to Harm VeenstraCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.