0

I have an array of string values and am trying to run a loop to match (using -eq operator) and return true if another variable matches one of the string values in the array. Even though I know the values should match, the loop is returning false.

I am currently taking the PS objects and pulling out the string values of a particular property of the object for the matching. I tried other operators aside from -eq, including -like using a wildcard and -match but there is no change in behavior. I also am currently constructing a list using $XXXX.Add($XXXX), but also had no luck with just populating an array with =+.

foreach ($Server in $UpdateGroupMembers) {
    if ($Server -eq $NodeName) {
        Write-Host "$Server is a match, loop terminated"
        return $true
        #break
    } else {
        Write-Host "There is no match"
        return $false
    }
}

$NodeName in the code above is a value that I know exists in the array/list, so I am quite lost.

5
  • It should work. Can you show how $UpdateGroupMembers and $NodeName are being made? $list = 'one','two','three'; $target = 'two'; foreach ($i in $list) { $i -eq $target } Commented Apr 30, 2019 at 14:27
  • 1
    Your code returns after the first element in the list, so not other elements get checked. Thus you'll always get "false" unless the very first element of your array matches $NodeName. Commented Apr 30, 2019 at 14:31
  • Why is it returning after the first element? That is where I think I am unclear. Is it because I called return $true specifically and not just $true? Commented Apr 30, 2019 at 14:52
  • 1
    Perhaps surprisingly return does exactly what the name suggests. Commented May 1, 2019 at 0:11
  • I am not a coder by trade, so things like that fly over my head. Commented May 1, 2019 at 16:09

2 Answers 2

3

If you just need to check whether a list or array contains an item, you can use the -in operator:

if ($NodeName -in $UpdateGroupMembers) {
    "$NodeName is a match"
    $true
}
else {
    "There is no match"
    $false
}

If you truly only need a True or False return, then you can do a one-liner:

$NodeName -in $UpdateGroupMembers
Sign up to request clarification or add additional context in comments.

3 Comments

It seems the real issue with my code as is was the use of the return keyword in my loop as Ansgar pointed out above. That being said, your solution is certainly an improvement on what I presented. I do not need the Write-Host bit at all, just the return.
And a follow up Q for the one liner: This seems to be using shorthand of some kind—is that correct? Is there a full fledged version that one line can be expanded to? I try to not use shortcuts or aliases in my code (idea being I understand what is occurring better).
The oneliner is not shorthand. It is a complete expression using the -in operator. The expression returns true or false always.
1

It seems to me that you are exiting the function after hitting the first servername that doesn't match. If my understanding is correct the code should look like:

$found= $false
foreach ($Server in $UpdateGroupMembers) {
    if ($Server -eq $NodeName) {
        Write-Host "$Server is a match, loop terminated"
        $found = $true
        break
}
if ($found -eq $false) {write-host "no match found for $NodeName "}
return $found

Make sure that $NodeName is a string and $UpdateGroupMembers is a collection of names not a collection of objects so you can compare them. I use something like $UpdateGroupMembers | get-member to see exactly what I am working with.

1 Comment

Thanks for the guidance. I had already pulled the desired property out of the object as a string for the items in $UpdateGroupMembers to ensure both I was matching strings so I knew I had that correct at least.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.