Kirk has a great summary of a difference between ForEach the PowerShell keyword and ForEach the alias for ForEach-Object cmdlet. Just a few days ago while working on the automated software testing pack I found myself confusing these two and having to debug the code which at first site looked perfectly legit:
# Locate the results entry for the currently selected test$i = 0$bNew = $true$PreviousResults | ForEach {if ( $_.Name -eq $currentTest.Name ) {$bNew = $falsebreak}$i++}
Basically, I had to find a record for the test selected to run (records stored in the $PreviousResults array) and have the $i hold the index of the record so I can update it with the record with test results. The code seemed obviou: just go through the records (ForEach), break if the test is found (the name comparison), and increment the counter if not ($i++).
The problem is that this is not a cycle - because ForEach here is actually a ForEach-Object cmdlet that simply calls the block after itself for the items it gets from the pipeline stream. There’s no cycle - so there’s nothing to break (so in my case break was breaking the whole function).
If you need to use break - use ForEach the cycle keyword or just For, like in this code which I used instead:
# Locate the results entry for the currently selected test$i = 0$bNew = $truefor ( $i=0; $i -le ($PreviousResults.length - 1); $i++) {if ( $PreviousResults[$i].Name -eq $currentTest.Name ) {$bNew = $falsebreak}}
Read Kirk’s post for other differences to keep in mind and try using full name for ForEach-Object to make your code more readable.
Dmitry
Tags: PowerShell


Subscribe by email