Thank you that was the concept I was missing. I had thought ForEach was simply an alias for ForEach-Object. When I changed ForEach-Object to ForEach I get the expected result.
Clarification: If ‘Foreach’ is at the beginning of a statement then it is the foreach loop keyword. If it is used after a pipe character it’s interpreted as ‘Foreach-Object’. It was a bit confusing for me at first too. I started a habit of never using the alias of Foreach-Object to prevent this confusion.
So if I understand using foreach in any instance should work, but foreach-object should not be used for a loop in a script. What about the @? Is it simply an alias for foreach? It is not listed by get-alias, but I do see it used often. How (literally) is it interpreted by powershell, both in the shell and in a script?
And you can use the cmdlet in a script; it just needs something piped to it, and it’s syntax is different. It has different performance characteristics.
There is no hard and fast rule that says you can’t use Foreach-Object in a script, but it’s generally considered a best practice. I have certainly used it in scripts but if you are processing a ton of data, particularly data that has already been collected and saved in a variable, then using the foreach keyword will generally yield better performance. The performance differences between the two have been hotly debated by people much smarter than me so don’t take my word for it - this is just my preference.
I am not certain what you mean by the ‘@’. Do you mean ‘%’? This is an alias for Foreach-Object and generally aliases should be avoided in scripts just for readability’s sake. They mainly exist to reduce typing in the console. With tab expansion and Intellisense in the ISE I typically use full cmdlet names for scripts and in the console.
Thank you for the clarification, trying to avoid aliases in scripts was why I had used the full foreach-object. I was mixing % for @, since I have seen both used in scripts. And now I know that foreach-object will work in a script if it has pipleline input, but to use only “foreach” for a scriptblock. Is this correct?