To check if an array contains a value in PowerShell, use the -contains operator. It returns True or False, and it ignores case:
$cities = 'Dallas', 'Austin', 'Houston', 'El Paso'
$cities -contains 'Austin'
$cities -contains 'Miami'
Output:
True
False

That covers the everyday case. Below, I’ll handle the variations people actually search for: case-sensitive checks, partial matches, “does not contain”, several values at once, the index of an item, and arrays of objects.
Every example uses the same $cities array and runs the same way in PowerShell 7.6 and Windows PowerShell 5.1.
Use -contains in an if statement
Because -contains returns a Boolean, it drops straight into an if:
if ($cities -contains 'Houston') {
'Houston is in the list'
}
Output:
Houston is in the list
How do I check if an array does not contain a value?
Use -notcontains. This pattern is handy for adding an item only when it’s missing:
if ($cities -notcontains 'Miami') {
'Miami is not in the list, adding it'
$cities += 'Miami'
}
$cities -join ', '
Output:
Miami is not in the list, adding it
Dallas, Austin, Houston, El Paso, Miami
-in and -notin: the same check, flipped
-in does the same job with the value on the left. Many people find it reads more naturally:
'austin' -in $cities
'Miami' -notin $cities
Output:
True
True
Pick whichever reads better. -in shines inside Where-Object, for example Where-Object City -in $cities.
Case-sensitive and case-insensitive checks
PowerShell operators ignore case, but the .NET .Contains() method doesn’t. Mixing them up causes a lot of “it works on my machine” bugs:
'-contains austin : ' + ($cities -contains 'austin')
'-ccontains austin : ' + ($cities -ccontains 'austin')
'.Contains austin : ' + $cities.Contains('austin')
'.Contains Austin : ' + $cities.Contains('Austin')
Output:
-contains austin : True
-ccontains austin : False
.Contains austin : False
.Contains Austin : True

Use -ccontains when you need a case-sensitive operator.
Check if an array contains part of a string
-contains only matches whole items. For part of a string, use -like with wildcards. On an array, it returns every item that matches:
$cities -like '*as*'
'---'
if ($cities -like '*paso*') { 'At least one city contains "paso"' }
Output:
Dallas
El Paso
---
At least one city contains "paso"

A non-empty result counts as $true in an if, so the second check works without -contains at all.
For patterns, use -match, which also filters the array:
$cities -match '^(Dal|Hou)'
Output:
Dallas
Houston
Check if an array contains all or any of several values
All values
Find the values that are missing. If nothing is missing, the array contains all of them:
$required = 'Austin', 'Dallas'
$missing = $required | Where-Object { $_ -notin $cities }
if (-not $missing) { 'All required cities are in the list' }
else { "Missing: $($missing -join ', ')" }
Output:
All required cities are in the list
Any value
Keep the values that are in the array and count them:
$wanted = 'Miami', 'Austin', 'Denver'
$found = $wanted | Where-Object { $_ -in $cities }
"Found $(@($found).Count) of $($wanted.Count): $($found -join ', ')"
Output:
Found 1 of 3: Austin
Check if one array contains another
The “all values” check works as a subset test. Wrap it in a function if you use it often:
$texasShortList = 'Houston', 'Dallas'
$otherList = 'Houston', 'Chicago'
function Test-Subset($Small, $Big) { -not ($Small | Where-Object { $_ -notin $Big }) }
Test-Subset $texasShortList $cities
Test-Subset $otherList $cities
Output:
True
False
Find the index of an item
.IndexOf() returns the position, or -1 when the item isn’t there. It’s case-sensitive, so use [array]::FindIndex() with a condition when case shouldn’t matter:
$cities.IndexOf('Houston') # case-sensitive
$cities.IndexOf('houston') # -1 means not found
# case-insensitive index
[array]::FindIndex([string[]]$cities, [Predicate[string]] { param($c) $c -eq 'houston' })
Output:
2
-1
2
Find the first match and return it
.Where() with the 'First' mode stops at the first match, which is faster on big arrays:
$cities.Where({ $_ -like '*o*' }, 'First')
# or with the pipeline
$cities | Where-Object { $_.Length -gt 6 } | Select-Object -First 1
Output:
Houston
Houston
Search an array with two conditions
Combine conditions with -and or -or inside Where-Object:
$cities | Where-Object { $_ -like '*a*' -and $_.Length -le 6 }
Output:
Dallas
Austin
Why does -contains return False for an array of objects?
With objects, -contains compares the whole object, not a property. Pull the property out first, and PowerShell collects it from every object for you:
$servers = @(
[pscustomobject]@{ Name = 'WEB01'; City = 'Dallas' }
[pscustomobject]@{ Name = 'SQL01'; City = 'Austin' }
)
$servers -contains 'SQL01' # compares whole objects: False
$servers.Name -contains 'SQL01' # compares the Name values: True
Output:
False
True
Numbers and strings are converted
PowerShell converts the value to the type of the array items before comparing, so these both match:
@(1, 2, 3) -contains '2'
@('10', '20') -contains 20
Output:
True
True
That’s convenient, but watch for it when you compare IDs that could be text in one list and numbers in another.
Faster lookups for large lists
-contains checks items one by one. If you test thousands of values against a big list, load it into a HashSet first:
$ids = 1..100000 | ForEach-Object { "ID-$_" }
$set = [System.Collections.Generic.HashSet[string]]::new([string[]]$ids, [System.StringComparer]::OrdinalIgnoreCase)
'-contains: {0,6:N1} ms' -f (Measure-Command { 1..200 | ForEach-Object { $null = $ids -contains 'id-99999' } }).TotalMilliseconds
'HashSet : {0,6:N1} ms' -f (Measure-Command { 1..200 | ForEach-Object { $null = $set.Contains('id-99999') } }).TotalMilliseconds
Output:
-contains: 1,395.5 ms
HashSet : 10.8 ms
The OrdinalIgnoreCase comparer keeps the lookups case-insensitive, like -contains. Microsoft covers every containment operator in about_Comparison_Operators.
Frequently Asked Questions
How do I check if a PowerShell array contains a value?
Use $array -contains 'value'. It returns True or False and ignores case.
Is -contains case-sensitive in PowerShell?
No. Use -ccontains for a case-sensitive check. The .NET .Contains() method is case-sensitive.
How do I check if an array contains part of a string?
Use -like with wildcards, for example $array -like '*text*'. It returns the matching items.
What is the difference between -contains and -in?
They do the same check. -contains puts the collection on the left, and -in puts the value on the left.
How do I find the index of an item in a PowerShell array?
Use $array.IndexOf('value'). It returns -1 when the item isn’t found and it’s case-sensitive.
Want more on arrays? Start here:
- PowerShell array tutorials
- Append to an array in PowerShell
- Remove items from an array in PowerShell
- PowerShell Where-Object contains
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.