The Contains operator in PowerShell is a bit of a strange one. You probably want to check if a string contains a particular word or character. The -contains
operator sounds the most logical one to use, but is it?
In PowerShell, the contains operator, doesn’t do substring comparison. But instead, it’s a collection operator. This means that it will test if a collection contains the matching value. It can’t be used to find a character or substring inside a string. A better solution for this is to use the -like
operator or the .contains()
function
In this article, I will explain how you can check if a string contains a character and explain the differences between the different operators.
PowerShell String Contains
When you want to test if a string contains a word you probably tried to use the -contains
operator like this:
$string = "how to find a word" if ($string -contains "find") { # Do something } # Result False
But this won’t work as you may have noticed. This is because -contains
will check if the $string object matches the test element. If you would test it on the complete string, contains will return true:
$string -contains "how to find a word" # True
So when you want to search for a substring or word inside a string with PowerShell it’s better to use the -like
operator. With -like you will need to use wildcards around your search string:
if ($string -like "*find*") { Write-host "String contains find" } # Result String contains find
There is however a way to use contains in PowerShell to find a word or character inside a string. Instead of the operator, we can use the built-in .NET function .Contains()
for strings. This string function can actually check if the string contains a word:
if ($string.Contains("find")) { Write-host "String contains find" } # Result String contains find
Keep in mind that the Contains function is case sensitive, so to do a case insensitive comparison you will first need to convert the string to lower case:
if ($string.ToLower().Contains("find")) { Write-host "String contains find" }
Using -Contains and -Notcontains on Objects and Arrays
The contains operator is meant to test if an object or array contains the given value. So for example, if we have an array with fruits, we can check if the array contains a pear:
# Array with fruits $fruits = "apple","banana","pear" # Check if the array contains pear $fruits -contains "pear" # Return True
We can only search on the whole values, this means that we can’t use wildcards as with the Like operator. If we try to search on only the first few letters of apple you will see that it returns false:
$fruits -contains "*app*" # Result False
If you want to check if a set doesn’t contain an element you can use the -notcontains
operator. So for example, if you want to make sure that the fruits array doesn’t contain raspberry we can do the following:
$fruits -notcontains "raspberry" # Returns True
-in and -notin operators
The -in
and -notin
operators in PowerShell are basically the same as the -contains
and -notcontains
operators. The difference is that they just work the other way around. With -contains the test object is on the right-hand side of the operator. With -in
, it’s on the left-hand side:
$fruits = "apple","banana","pear" "apple" -in $fruits # True "raspberry -notin $fruits # True # Similar to $fruits -contains "apple" # True $fruits -notcontains "raspberry # True
Using the in operator instead of contains can improve the readability of your code. But besides that, there is no advantage in using it compared to contain.
Wrapping Up
If you want to know in PowerShell if a string contains a particular string or word then you will need to use the -like
operator or the .contains()
function. The contains operator can only be used on objects or arrays just like its syntactic counterpart -in
and -notin
.
I hope this article helped with understanding the differences between the different operators and functions. Learn more about PowerShell scripting in this complete guide. If you have any questions or tips, just drop a comment below.
I finally got it working using the -contains operator and tolower()
if($f.Name.ToLower() -match $DSplit[0].ToLower() -eq “True” -and $F.Name.ToLower() -match $DSplit[1].ToLower() -eq “True”)
Thanks for your help.
Where it’s failing is when “apple” is compared to “Apple”, or “pear” to “Pear”.
I don’t want case sensitivity?
ah yes, I overlooked that part in your example. As you have figured out it indeed is case sensative.
Hmm, thanks for checking.
Hey Rudy, I’m struggling to do what you have above, but with a variable.
I’m searching filenames for a match. $Dsplit[0] = “Apple” and $Dsplit[1] = “Pear. Here is a line of my code that works great on “Apple Pear.jpg” but not on “ApplePear.jpg”. I haven’t been able to make wildcards work with this line of code.
if($F.Name.Contains($DSplit[0]) -and $F.Name.Contains($DSplit[1]))
I just did a quick test in PowerShell, but it seems to work fine:
$Dsplit = @(“Apple”,“Pear")
$string1 = “Apple Pear.jpg”
$string2 = “ApplePear.jpg”
$string3 = “AppleKiwi.jpg”
$string4 = “Apple Kiwi.jpg”
if( $string1.Contains($DSplit[0]) -and $string1.Contains($DSplit[1])){ 'found in 1 '}
if( $string2.Contains($DSplit[0]) -and $string2.Contains($DSplit[1])){ 'found in 2' }
if( $string3.Contains($DSplit[0]) -and $string3.Contains($DSplit[1])){ 'found in 3' }
if( $string3.Contains($DSplit[0]) -and $string4.Contains($DSplit[1])){ 'found in 4' }