Here's a snippet of my code (based on this previous question):
$rgdNames = (Get-AzureRmResourceGroupDeployment -ResourceGroupName "$azureResGrpName").DeploymentName
$siblings = $rgdNames | Where-Object{$_ -match "^($hostname)(\d+)$" }
if ($siblings) {
# Make a list of all numbers in the list of hostnames
$serials = @()
foreach ($sibling in $siblings) {
# $sibling -split ($sibling -split '\d+$') < split all digits from end, then strip off everything at the front
# Then convert it to a number and add that to $serials
$hostnumber = [convert]::ToInt32([string]$($sibling -split ($sibling -split '\d+$'))[1], 10)
$serials += $hostnumber
}
(1..$siblingsMax) | foreach { # Iterate over all valid serial numbers
if (!$serials.Contains($_)) { # Stop when we find a serial number that isn't in the list of existing hosts
$serial = $_
# break # FIXME: For some reason, this break statement breaks "too far"
}
}
} else {
$serial = 1
}
write-output("serial = $serial") # does not print
# ...more statements here, but they're never called :(
I have been looking at it for a while, but can't figure out why the break
statement (if un-commented) stops my program instead of just breaking out of its foreach
loop. Is there something about foreach
that I'm not aware of, or does break
just work differently than it would in Java?
For the time being, I'm working around this using an extra if
test, and it doesn't mean (too) much that the loop runs its entire length. But it's ugly!
This construct:
is NOT a
foreach
loop - it's a pipeline with a call to theForEach-Object
cmdlet (aliased asforeach
) - and keywords designed to interrupt the control flow of a loop (likebreak
orcontinue
) will NOT act in the same way in these two different cases.Use a proper
foreach
loop and break will behave as you expect:Alternatively, you can abuse the fact that
continue
behaves like you would expectbreak
in aForEach-Object
process block:although I would strongly discourage this approach (it'll only lead to more confusion)