-contains vs .contains()

This topic contains 2 replies, has 3 voices, and was last updated by Profile photo of Daniel Krebs Daniel Krebs 2 years ago.

  • Author
    Posts
  • #20901
    Profile photo of stephenmbell
    stephenmbell
    Participant

    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:

    $env:COMPUTERNAME.ToLower().Contains("_a_")
    

    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,
    sb

  • #20903
    Profile photo of tommymaynard
    tommymaynard
    Member

    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_*') {}

  • #20904
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    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"
    True
    
    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.

    Example:

    $env:COMPUTERNAME
    POS_A_205
    
    $env:COMPUTERNAME -match '_a_'
    True
    
    $env:COMPUTERNAME -like '*_a_*'
    True
    

    I hope that helps.

    Regards,
    Daniel

You must be logged in to reply to this topic.