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 = $false
break
}
$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 = $true
for ( $i=0; $i -le ($PreviousResults.length - 1); $i++) {
if ( $PreviousResults[$i].Name -eq $currentTest.Name ) {
$bNew = $false
break
}
}
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