How to properly use break in a foreach loop? [SOLVED]

by John.A.Mello at 2013-04-22 07:14:02

I’m having trouble figuring out how to use properly use break to exit a foreach loop in a script if a condition is meet. When I use break it exits the entire script. I’ve read some articles stating that this is because foreach isn’t an actual loop. But I’ve tried making an actual for loop and I’m still having issues with break exiting the entire script.
So my original example is below. Basically I’m gathering a series of groups and comparing the current members to the previous group members (saved upon the last run of the script in a file or multi-value AD attribute). If a user was removed from the group then I want to perform some work on the removed user. If both the current group membership and the previous group membership are empty, then there is no need to continue the rest of the script for this group and proceed to the next group.

#Script parameters etc
[Array]$Grouplist = Get-ADGroup -LdapFilter “(&(Description=Email Compliance - )(Name=Compliance)(ObjectClass=group))”

#foreach($GroupList in $GroupList) {
If (($CurrentGroupMembers.count -eq 0) -AND ($UsersToTest.count -eq 0)) {
Write-Verbose “Both are blank, stoping work on this group and proceeding to the next”
Break
}
Else {Write-Verbose “One of the groups has members, continuing script”}
#CONTIUNE SCRIPT WORK
}


This didn’t work so I tried an actual for statement, but the results were the same

for($Index=0; $Index -le ($GroupList.Count -1); $index++) {
If (($CurrentGroupMembers.count -eq 0) -AND ($UsersToTest.count -eq 0)) {
Write-Verbose “Both are blank, stoping work on this group and proceeding to the next”
Break
}
Else {Write-Verbose “One of the groups has members, continuing script”}
#CONTIUNE SCRIPT WORK
}


So in the meantime I’m putting the rest of the script in the else block

for($Index=0; $Index -le ($GroupList.Count -1); $index++) {
If (($CurrentGroupMembers.count -eq 0) -AND ($UsersToTest.count -eq 0)) {
Write-Verbose “Both are blank, stoping work on this group and proceeding to the next”
Break
}
Else {
#CONTIUNE SCRIPT WORK
}
}


While this works, I’d like to figure out why break doesn’t work for me in this instance. I’m sure I’m missing something, but I’m not sure what.
by mjolinor at 2013-04-22 07:26:27
You are correct that it doesn’t work properly with foreach-object. Technically, foreach-object is a cmdlet and not one of the loop constructs.
I blame making foreach an alias for foreach-object, but that ship has sailed so you’ll just have to adapt. It is what it is.

The reason it’s exiting the script in your for loop is that there’s nothing else there but the for loop. Once it breaks out of that loop, it’s finished.
by John.A.Mello at 2013-04-22 07:43:56
Thanks for the reply mjolinor, I was hoping that having break in the if block would bring me back to the beginning of the loop. Now it’s obvious to where my mistake is.
by ArtB0514 at 2013-04-22 07:46:00
Try checking these out and see if Continue might be more what you want than Break:
Get-Help about_Break
Get-Help about_Continue
by mjolinor at 2013-04-22 07:58:14
[quote]Thanks for the reply mjolinor, I was hoping that having break in the if block would bring me back to the beginning of the loop. Now it’s obvious to where my mistake is.[/quote]

Break immediatly exits the loop and does not process any more objects.

Continue bypasses any more of the instructions in the loop, and goes immediatly to the bottom. If there are more objects to process, and whatever logical continuation tests might be at the end of the loop evalutate to “True” it will continue with the next object.