To filter objects where a property contains some text, use Where-Object with the -like operator and wildcards on both sides. This returns every server whose name contains “SQL”:
$servers | Where-Object Name -like '*SQL*'
The -contains operator looks like the obvious choice, but it doesn’t check for text inside a string. That trips up almost everyone, so I’ll show you why below.
All the examples use this small list of servers. Paste it into your console first:
$servers = @(
[pscustomobject]@{ Name = 'WEB01'; Role = 'Web server'; City = 'Dallas'; Tags = @('prod', 'iis') }
[pscustomobject]@{ Name = 'WEB02'; Role = 'Web server'; City = 'Austin'; Tags = @('test', 'iis') }
[pscustomobject]@{ Name = 'SQL01'; Role = 'SQL Server'; City = 'Dallas'; Tags = @('prod', 'sql') }
[pscustomobject]@{ Name = 'APP-SQL02'; Role = 'App and SQL'; City = 'Denver'; Tags = @('prod', 'sql', 'app') }
[pscustomobject]@{ Name = 'FILE01'; Role = 'File server'; City = 'Seattle'; Tags = @('prod') }
)
Output:
Name Role City Tags
---- ---- ---- ----
WEB01 Web server Dallas prod, iis
WEB02 Web server Austin test, iis
SQL01 SQL Server Dallas prod, sql
APP-SQL02 App and SQL Denver prod, sql, app
FILE01 File server Seattle prod
I tested every example in PowerShell 7.6 and Windows PowerShell 5.1.
Where-Object contains: filter with -like
Here’s the command from the top, with its output:
$servers | Where-Object Name -like '*SQL*'
Output:
Name Role City Tags
---- ---- ---- ----
SQL01 SQL Server Dallas {prod, sql}
APP-SQL02 App and SQL Denver {prod, sql, app}

-like ignores case, so '*sql*' finds the same servers. The * means “any characters”, which is why a match anywhere in the name counts.
Why does -contains return nothing?
This is the most common mistake with Where-Object:
$servers | Where-Object Name -contains 'SQL'
'Found: ' + @($servers | Where-Object Name -contains 'SQL').Count
Output:
Found: 0

-contains is a collection operator. It asks “is this exact item in the list?”, not “does this text appear inside the string?”:
'SQL01' -contains 'SQL' # a string is not a collection
@('SQL01', 'WEB01') -contains 'SQL01' # exact match of a whole item
@('SQL01', 'WEB01') -contains 'sql01' # case-insensitive
Output:
False
True
True
Use -contains when the property is a list, like the Tags column later in this article. For text inside a string, use -like or -match.
The .NET .Contains() method does check for a substring, but it’s case-sensitive, unlike PowerShell’s operators:
'SQL01'.Contains('SQL')
'SQL01'.Contains('sql') # case-sensitive
Output:
True
False
Use a script block for more complex conditions
The short form (Where-Object Name -like '*SQL*') handles one condition. For two or more, use a script block with $_:
$servers | Where-Object { $_.Name -like '*sql*' -or $_.Role -like '*sql*' } |
Select-Object Name, Role
Output:
Name Role
---- ----
SQL01 SQL Server
APP-SQL02 App and SQL
I go deeper into this in Where-Object with multiple conditions.
Where-Object starts with
Put the wildcard only at the end to match the start of a string:
$servers | Where-Object Name -like 'WEB*' | Select-Object Name, City
Output:
Name City
---- ----
WEB01 Dallas
WEB02 Austin
Does not start with
Swap in -notlike:
$servers | Where-Object Name -notlike 'WEB*' | Select-Object -ExpandProperty Name
Output:
SQL01
APP-SQL02
FILE01
Ends with
Move the wildcard to the front:
$servers | Where-Object Name -like '*01' | Select-Object -ExpandProperty Name
Output:
WEB01
SQL01
FILE01
Exclude items with -notlike
-notlike works with any pattern, not just “starts with”. This keeps servers whose role doesn’t mention “server”:
$servers | Where-Object Role -notlike '*server*' | Select-Object Name, Role
Output:
Name Role
---- ----
APP-SQL02 App and SQL
Filter with regex using -match
When wildcards aren’t enough, -match takes a regular expression. This one keeps names that are WEB or FILE followed by exactly two digits:
$servers | Where-Object Name -match '^(WEB|FILE)\d{2}$' | Select-Object -ExpandProperty Name
Output:
WEB01
WEB02
FILE01
To match any of several words, separate them with |:
$servers | Where-Object Role -match 'SQL|File' | Select-Object Name, Role
Output:
Name Role
---- ----
SQL01 SQL Server
APP-SQL02 App and SQL
FILE01 File server
-notmatch is the opposite. This keeps every server whose name doesn’t start with WEB:
$servers | Where-Object Name -notmatch '^WEB' | Select-Object -ExpandProperty Name
Output:
SQL01
APP-SQL02
FILE01
For more patterns, see my PowerShell regex guide.
Make the match case-sensitive
-like and -match ignore case. Put a c in front (-clike, -cmatch) when case matters:
'-like : ' + @($servers | Where-Object Name -like '*sql*').Count
'-clike : ' + @($servers | Where-Object Name -clike '*sql*').Count
'-cmatch: ' + @($servers | Where-Object Name -cmatch 'SQL').Count
Output:
-like : 2
-clike : 0
-cmatch: 2
Where-Object in array: -in and -notin
To keep objects whose property equals any value in a list, use -in. It’s the same as “WHERE City IN (…)” in SQL:
$texas = 'Dallas', 'Austin', 'Houston'
$servers | Where-Object City -in $texas | Select-Object Name, City
Output:
Name City
---- ----
WEB01 Dallas
WEB02 Austin
SQL01 Dallas

-notin keeps everything else:
$servers | Where-Object City -notin 'Dallas', 'Austin' | Select-Object Name, City
Output:
Name City
---- ----
APP-SQL02 Denver
FILE01 Seattle
-in needs exact matches (case-insensitive). It won’t match part of a value, so use -match 'Dallas|Austin' for partial matches.
When the property is a list: use -contains
Here’s where -contains is the right tool. Tags holds several values, and I want every server tagged sql:
$servers | Where-Object Tags -contains 'sql' | Select-Object Name, @{ Name = 'Tags'; Expression = { $_.Tags -join ', ' } }
Output:
Name Tags
---- ----
SQL01 prod, sql
APP-SQL02 prod, sql, app
Filter a list of strings
Everything above works on plain strings too. Inside the script block, $_ is the string itself:
$lines = 'INFO Service started',
'ERROR Could not reach SQL01',
'WARN Disk at 91%',
'ERROR Login failed for svc_backup'
$lines | Where-Object { $_ -like 'ERROR*' }
Output:
ERROR Could not reach SQL01
ERROR Login failed for svc_backup
To search text inside files, use Select-String instead. I cover it in find text patterns with Select-String.
Filter files by name
The same operators filter files. Use -Filter first to narrow the list, then Where-Object for the rest:
Get-ChildItem -Path C:\psfaqs\Logs -Filter *.log |
Where-Object Name -notlike 'sql*' |
Select-Object -ExpandProperty Name
Output:
app.log
web.log
A faster option: the .Where() method
For data already in a variable, the .Where() method avoids the pipeline and is usually faster:
$servers.Where({ $_.City -eq 'Dallas' }).Name
Output:
WEB01
SQL01
Microsoft lists every operator in about_Comparison_Operators.
Frequently Asked Questions
How do I check if a string contains text in Where-Object?
Use -like with wildcards: Where-Object Name -like '*text*'. -contains won’t work, because it checks whole items in a collection.
What is the difference between -contains and -like in PowerShell?
-like matches a string against a wildcard pattern. -contains checks whether a collection includes an exact value, for example @('a','b') -contains 'a'.
How do I filter where a value is in an array?
Use -in: Where-Object City -in 'Dallas', 'Austin'. Use -notin to exclude those values.
How do I use regex with Where-Object?
Use -match with a pattern, for example Where-Object Name -match '^WEB\d+$'. Use -notmatch to exclude matches.
Is Where-Object -like case-sensitive?
No. Use -clike or -cmatch for a case-sensitive filter.
Continue with these Where-Object guides:
- PowerShell Where-Object
- Where-Object with multiple conditions
- Where-Object for null or empty values
- PowerShell -like operator
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.