Breaking a nested ForEach in Powershell

Breaking a nested ForEach in Powershell

Breaking a nested ForEach in Powershell might be challanging if you don’t know that you can use labels to point the script to another location. Normally, you will require to stop a loop when you’re comparing objects from different arrays and want to terminate the loop when they match. There’s a command called “break” which is the key to breaking a nested ForEach in Powershell, however using just break will actually break all of the loops where the command is contained.

Let’s make an example. Let’s say we have two arrays, $arrayA and $arrayB. $arrayA contains the letters “a”, “d” and “f” whilst $arrayB contains “a”, “b”, “c” and “d”. We want to check each single element in $arrayA against each single element in $arrayB. This is when we will need a nested ForEach cycle.
Now, we want to compare them in order to report when an object in $arrayA is contained in $arrayB, in that case, we also need to quit the current ForEach to avoid a wrong report to show (keep reading to understand better this point).

This is how the script will look like:

$arrayA = @("a","d","f")
$arrayB = @("a","b","c","d")


ForEach ($a in $arrayA){
    
    Write-Host "Checking $($a).."

    :OutOfNestedForEach_LABEL #This is the label where break will re-direct the script to

    ForEach ($b in $arrayB){
    
        If ($b -eq $a){
            $temp_entryMatch = 1
           break :OutOfNestedForEach_LABEL
        }
        Else{
            $temp_entryMatch = 0
        }
    }

    If ($temp_entryMatch) {
        Write-Host ">> $($a) is contained in ArrayB"
    }
    Else{
        Write-Host ">> $($a) is NOT contained in ArrayB"
    }
}

o, when $a equals to $b, we must break the cycle because the object has been found and we no longer need to double check it against the other objects. If we do not use the break command, the script will continue.

Let’s try to use the script logic to explain why we need to break it, by showing what would happen when break isn’t used:

  • We’re comparing “a” (from $arrayA) with “a”. Good, it matches, so we set $temp_entryMatch to 1.
  • Now we compare “a” (from $arrayA) with “b”. Nope, they do not match, set $temp_entryMatch to 0 (zero).
  • Now we compare “a” (from $arrayA) with “c”, then “d” with the same results: setting $temp_entryMatch to 0 (zero).
  • Now that we’re done with the first nested foreach, we check if $temp_entryMatch has a different value than 0. It doesn’t, so we will write that “a” is NOT contained in ArrayB.

But hang on a minute! “a” it’s contained in $arrayB! What went wrong? Well, simply the fact that we didn’t break the loop once “a” matched “a”, so the temp variable ($temp_entryMatch) got reset to 0 (zero).
This is really important in these sort of loops where you store data to a temporary variable.

Here’s the output when I run the script as reported above:

Nested-ForEach-PowerShell_with-Break

And here’s what happens when I run it without the “break” command.

Nested-ForEach-PowerShell_WITHOUT-Break

As you can see, only “d” is reported to be contained in $arrayB just because of luck, in fact it was the last item in the loop and it happened to match. This is it on Breaking a nested ForEach in Powershell!

IT Droplets

IT Droplets