Complete Guide: How to Filter Data Using Where-Object in PowerShell

Complete Guide: How to Filter Data Using Where-Object in PowerShell blog image

PowerShell is a command line and scripting language for system administration and automation in Windows, and is a vital part of every Windows administrator or developer’s toolkit. Filtering the output of PowerShell commands using Where-Object allows you to quickly find relevant data for display, or perform operations on a subset of objects based on your filter criteria.

This guide explains how to use Where-Object to filter objects and data in PowerShell, and includes practical examples that you can copy and paste for use in your own code. It also explains performance considerations and best practices for using Where-Object in your PowerShell scripts.

Stop reacting—start leading. Learn how to shift to a proactive IT management strategy with our step-by-step guide. Get started.

Understanding the Where-Object PowerShell cmdlet

The Where-Object PowerShell CmdLet (a CmdLet is a PowerShell command used for automation) filters a collection of objects from a command to only those that match your search criteria.

The most commonly used syntax and parameters for Where-Object is as follows:

[ Command ] | Where-Object [ -Property ] [ -Value ] [ Operator ]

Note that:

  • [ Command ] is the command that has its output filtered by Where-Object.
  • [ -Property ] is the property of the object to compare, supplied as a string.
  • [ -Value ] is the value to compare the property against, supplied as an object or string.
  • The final parameter is the comparison [ Operator ] to use: -eq (equal to), -ne (not equal to ), -gt (greater than), -lt (less than), -ge (greater than or equal to), -le (less than or equal to).

Output is piped to Where-Object. You can see other syntax options in the PowerShell documentation. It is also possible to supply your own more complex filtering criteria as a code block, as shown in the examples later in this article.

Practical examples of using Where-Object to filter objects

The best way to see how to use Where-Object is to see it in action. Below are several simple examples showing basic usage using built-in comparison operators and advanced usage that implements custom criteria in script blocks. These examples include how to filter by multiple values, using regex, and filtering by date.

Following that are several complete PowerShell commands that use Where-Object to perform common scripting tasks like cleaning up log files, finding processes with high memory usage, filtering Active Directory users, and searching event logs.

Filtering single values

This example shows how to filter to a single value using the -eq comparison operator:

# Filter running processes to those with the name ‘powershell’

Get-Process | Where-Object Name -eq ‘powershell’

Filtering by multiple values

This example shows how to filter by multiple values. It filters the list of running processes from Get-Process to those named “winlogon” and “explorer” (both of which should be running for every logged-in user):

# Filter running processes named ‘winlogon’ or ‘explorer’

$names = @(‘winlogon’, ‘explorer’) # Define an array containing the multiple search values

Get-Process | Where-Object { $names -contains $_.Name }

The curly braces in this example denote a PowerShell script block that contains a collection of expressions. Note also the use of $_ — a shortcut that represents the object being compared. In this case, it’s used to supply the Name property of the object to the comparison.

Using regular expressions

Where-Object can also be used with arrays. Regex can be used to filter any kind of object, providing a way to add complex conditions for filtering by the contents of strings:

# Filter an array of emails to those from a specific domain

$emailAddresses = @(“[email protected]”, “[email protected]”, “[email protected]”) # Define an array of email addresses

$emailAddresses | Where-Object { $_ -match ‘@test.com$’ }

Note that you could also use the array Where() method, discussed later in this article.

Filtering by date

For commands that return objects with date properties, you can filter using DateTime objects returned by Get-Date:

# Find files in the current directory that were modified in the last 14 days

Get-ChildItem -Path . | Where-Object { $_.LastWriteTime -GT (Get-Date).AddDays(-14) }

You can also filter between dates by supplying a date range:

# Find Windows event log entries from the last week

$startDate = (Get-Date).AddDays(-7) # Note the use of a negative number to set the date to the past

$endDate = Get-Date

Get-EventLog -LogName Application | Where-Object { $_.TimeGenerated -ge $startDate -and $_.TimeGenerated -le $endDate }

Advanced examples demonstrating custom criteria in script blocks

As shown in the above examples, script blocks can be used to contain multiple comparison expressions. You can perform more complex filtering using Where-Object by supplying multiple criteria and conditions in script blocks. Here are a few examples:

# Filter processes with CPU usage greater than 75%

Get-Process | Where-Object { $_.CPU -gt 75 }

# Find running services that have a name starting with ‘Win’

Get-Service | Where-Object { $_.Status -eq ‘Running’ -and $_.Name -like ‘Win*’ }

# Find files in the current directory that are larger than 3MB and have been modified in the last 30 days

Get-ChildItem -Path . | Where-Object { $_.Length -gt 3MB -and $_.LastWriteTime -gt (Get-Date).AddDays(-30) }

Common real-world Where-Object examples

In addition to the examples above, here are some further PowerShell commands that are commonly required for automation and system administration:

# Find .txt files in the current directory

Get-ChildItem -Path . | Where-Object Extension -eq ‘.txt’

# Delete log files at a given path older than 90 days

Get-ChildItem -Path ‘C:PathToLogs’ -Filter ‘*.log’ | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-90) } | Remove-Item

# List processes that use more than 1000 MB of memory

Get-Process | Where-Object { $_.WorkingSet -gt 1000MB } | Select-Object Name, WorkingSet

# Search for Active Directory users who are members of a specific group (marketing) and have a specific job title (Director)

Import-Module ActiveDirectory

Get-ADUser -Filter { MemberOf -eq ‘CN=Marketing,OU=Groups,DC=example,DC=com’ -and Title -eq ‘Director’ }

# Find Windows event log entries that are errors related to a specific application (MyApplication)

Get-EventLog -LogName Application -EntryType Error | Where-Object { $_.Source -eq ‘MyApplication’ }

Note the combined use of Where-Object and Select-Object in this example to extract relevant data from results.

Difference between Where-Object and other filtering methods

There are several ways to filter data in Powershell, some dealing with objects, and some dealing with text. They do not behave the same way, so you should pick the one that best suites each scenario:

  • Where-Object: Filter collections of objects piped to the command so that only matching objects remain.
  • Select-Object: Additionally able to filter object properties, for example returning a collection of objects, but only including the ‘name’ property of each.
  • Array Where() method: Filter arrays based on supplied conditions.
  • Filter parameter: Some cmdlets will include a -Filter parameter for searching their output.

Performance considerations when filtering data

Data filtering can be a resource-intensive task. PowerShell commands, especially when interacting with databases or Active Directory, can potentially output multiple thousands of records, and using Where-Object to process and filter each one is not the most efficient way to search large sets of data.

Many PowerShell commands will include a -Filter parameter that is optimized for searching using that command. If a -Filter parameter is available, it’s recommended to use it to reduce the data as much as possible before passing it to Where-Object.

For example, if you are working with Active Directory data using the Get-ADUser, and want to retrieve a list of users from a certain department, and then perform different actions based on their job role, you should use -Filter to limit the results to the department, and you can then use Where-Object to perform actions based on Job role to the smaller list of objects.

If your Powershell script is taking too long to execute and you suspect that a command containing Where-Object is to blame, you can assess its performance using the Measure-Command cmdlet to measure the time it takes for the command to complete.

Best practices and common pitfalls when using Where-Object in PowerShell

There are a few common pitfalls that users encounter when using Where-Object that can be solved with the following best practices:

  • “Filter left”: Use cmdlet specific -Filter or other search parameters as early in your PowerShell commands as possible (that is, as far to the left of the command as possible) to maximize efficiency.
  • Use Select-Object to filter out unneeded properties: This improves performance when dealing with large amounts of data (that you can’t otherwise filter using cmdlet-specific functions).
  • Keep it simple: Avoid complex conditions in script blocks and break things down wherever possible to improve performance and make debugging easier.
  • Use comparison operators correctly: Make sure you understand what your filter parameters and script blocks are doing to avoid unexpected results.
  • Keep your scripts readable: You can use ? as an alias for Where-Object to shorten commands to make them easier to read. You should also use white space and indentation to keep your code well-formatted and easy to read, as well as add comments noting what each line in your PowerShell script is meant to do (in case you come back in months or years to tweak something and forget what the purpose of a command was).

To assist with debugging Where-Object commands, you can use the common PowerShell verbose parameter to print detailed information about the operation in progress. For example:

$VerbosePreference = “Continue”

Get-Process | Where-Object { $_.CPU -gt 75 } -Verbose

You should also use try-catch blocks to handle unexpected errors gracefully.

Data filtering using PowerShell Where-Object lets you display relevant information from cmdlets, search for files and processes, and sort through results from any PowerShell command that returns results as objects, including tools for working with Active Directory. To see how Where-Object can assist with repetitive system administration tasks, check out our tutorial on how to use PowerShell for automation.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about Ninja Endpoint Management, check out a live tour, or start your free trial of the NinjaOne platform.

You might also like

Ready to simplify the hardest parts of IT?
×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).