-contains vs .contains()

This may be a easy question, but I am a bit confused. I have a script that I am using in a point-of-sale environment. 700 PCs. Each named consistently, like this - POS_A_[NUMBER] for each location. For example, POS_A_101, POS_B_101, POS_A_102, POS_B_102, etc…all the way to 700.

In my script, I am running a different process depending on if the machine is an A machine or a B machine.

I do the following:

if($env:COMPUTERNAME.ToLower() -contains "_A_")
# do some stuff

Problem is, if I run:

$env:COMPUTERNAME.ToLower() -contains "_a_"

On a machine that is named POS_A_205, I get a return of False.

However, if I run:


On a machine that is named POS_A_205, I get a return of True

What’s the difference? Obviously, I know how to modify the script to function like I want, I just don’t get why one is different than the other?

Thanks in advance,

I’d start by reading the ‘-Contains isn’t -Like’ chapter in The Big Book of PowerShell Gotchas (https://onedrive.live.com/?cid=7F868AA697B937FE&id=7F868AA697B937FE!112). Then I’d move away from using contains to using -like, such as If ($env:COMPUTERNAME.ToLower() -like ‘A’) {}

Hi Stephen,

The PowerShell Containment operators (-Contains and -NotCOntains) are designed to work against collections like arrays not strings like $env:COMPUTERNAME. The containment operators only match exact values.

Examples from about_Comparison_Operators help:

PS C:\> "abc", "def" -Contains "def"

PS C:\> "Windows", "PowerShell" -Contains "Shell"
False  #Not an exact match

The correct PowerShell operators to use in your case are -match or -like which are case-insensitive. No need to convert to lower case.



$env:COMPUTERNAME -match '_a_'

$env:COMPUTERNAME -like '*_a_*'

I hope that helps.