Comparison Operators and Arrays

All,

Need an assist with a comparison operation related to using arrays. Am pretty sure that it’s something simple that i’m missing.

Specifically, I am trying to compare against an array of values to determine if a property string from an AD users lookup contains one of the values in that array. Code example below:

[pre]$ADProperty1 = “my training list”
$ADProperty2 = “Backup Schedule”

$ADProperty1 -contains @(“training”,“backup”,“security”)
$ADProperty2 -contains @(“training”,“backup”,“security”)[/pre]

Have used the -contains, -match and -like (with wildcards) operators without success to try to get some semblance of understanding as to how these operators work, but I am scratching my head.

What the heck am I doing wrong?

It’s because you are passing a string that will never match the array.

You also need to know on what side the compare needs to happen an which to use to get a given results. This is all documented in the help files, so don’t guess at it.

$ADProperty1 = 'training'
$ADProperty2 = 'Backup'

@('training','backup','security') -match "$($ADProperty1)|$($ADProperty2)"
training
backup

$ADProperty1 = 'my training list'
$ADProperty2 = 'Backup Schedule'

@('my training list','training','backup','security') -match "$($ADProperty1)|$($ADProperty2)"
my training list

But what you are really trying to do, is see if any part of $ADProperty* matching anything in the array, but you are not down that, as you are asking for exact matches.

So, to do that, you have to loop. Let’s say you are lookin got see is any one is true.

[bool](@('training','backup','security') |
ForEach {$PSItem -match $ADProperty1})
True

[bool](@('training','backup','security') |
ForEach {$PSItem -match $ADProperty2})
True

[bool](@('training','backup','security') |
ForEach {$PSItem -match "$($ADProperty1)|$($ADProperty2)"})
True

# Or 

$ADProperty1, $ADProperty2 | 
ForEach { $PSItem -match 'training|backup|security'}

True
True

# Or

$ADProperty1, $ADProperty2 | 
ForEach { $PSItem | Select-String 'training|backup|security'}

my training list
Backup Schedule

# Or, because of case sensitivity

$ADProperty1, $ADProperty2 | 
ForEach {
    [regex]::Matches($PSItem,
    'training|backup|security|Training|Backup|Security').Value
}

training
Backup

-contains doesn’t work with strings. It will tell you if the item that follows it is contained in the collection that precedes it. For example:

@(1, 2, 3, 4) -contains 3 # will be True

There is a similarly-named method that does something like this for looking for a substring within a larger string, but it can only query one item at a time:

"this is a string".Contains("string") # will be True

If you want to check that one string contains any one of a collection of values within that string, it becomes a bit tricky. You can use the $string.Contains() method to do so, but I think you’ll find it rather unwieldy, requiring loops and a bit of boilerplate code to make it work the way you want.

Instead, I’d recommend using PS’s -match operator to work with regex, which is much simpler to use in this kind of scenario. Unlike -like, -match is full regex, and regex has an “or” token:

$ADProperty2 -match "training|backup|security"