'check if an string exists in a list of strings, using powershell

I have Powershell version 3,4 and 5 in my environment. When I write below code it continously gave me false, though $CompatiableOS contains output of $OSverions.

   [string] $CompatiableOS = '2016','2012','2008'
   $OSVersion=[regex]::Matches(((Get-WmiObject -class Win32_OperatingSystem).caption), "([0-9]{4})")

   if ( $CompatiableOS -contains  $OSVersion)
   {
      return $TRUE
   }
   else
   {
      return $FALSE
   }

but when I changed above code to below, it worked. What could be the issue?

 [string] $CompatiableOS = '2016','2012','2008'
 $OSVersion=[regex]::Matches(((Get-WmiObject -class Win32_OperatingSystem).caption), "([0-9]{4})")

 if ( $CompatiableOS.contains($OSVersion))
 {
    return $TRUE
 }
 else
 {
      return $FALSE
 }


Solution 1:[1]

From the MS documentation

-Contains Description: Containment operator. Tells whether a collection of reference values includes a single test value. Always returns a Boolean value. Returns TRUE only when the test value exactly matches at least one of the reference values.

The important part is here is "only when the test value exactly matches". In your case you try to compare the string "2016 2012 2008" with as an example 2016, this doese't match exactly. In this case you should use the -like operator. Or you define your compatibleOS variable as an string array like that [String[]], then you can use the -contains.

Additonal, check whats inside the OSVersion variable. It is a machtcollection not a string. If you define your compatibleOS variable as a string array and you use $OSVersion.Value both of your examples will work.

Solution 2:[2]

This comes up a lot. -contains vs .contains(). They're very different. -contains has to match exactly. But the left side can be an array of strings. You actually joined everything into one string on the left with the [string] cast.

$compatibleos
'2016 2012 2008'

'2016 2012 2008' -contains '2016'
False

'2016 2012 2008'.contains('2016')
True

'2016','2012','2008' -contains '2016'
True

('2016','2012','2008').contains('2016')
True

Solution 3:[3]

Although the $CompatiableOS contains output of $OSverions, however the -contains is only used against a single test value, and return true when the test value exactly matches at least one of the reference values. However When the test value is a collection, the Contains operator uses reference equality. It returns TRUE only when one of the reference values is the same instance of the test value object. What is of importance is that they have to be of the same instance in this case. For eg:

PS> "abc", "def", "ghi" -contains "abc", "def"

->False

PS> $a = "abc", "def"

PS> "abc", "def", "ghi" -contains $a

->False

PS> $a, "ghi" -contains $a

->True

Note, how the last one returns true due to the same instance, and the rest were false. Thus while using -contains, you received False. However when you use the contains(..) format, it does not check for the same instance and thus returned True, in your case.

Solution 4:[4]

for me below syntax worked

ForEach ($content in $logFileContent) {
  
     if( $content.contains("MainClass")){
       echo  "MainClass: $content" >> $log
           }
         }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 guiwhatsthat
Solution 2 js2010
Solution 3 Pang
Solution 4 Rama Sharma