Hi,
I encountered a weird problem with foreach loop. My understanding is foreach is alias of foreach-object - which I can confirm by using get-alias command.
However if I run the following command, I get different results with foreach & foreach-Object, below is simple conde what I have tried, can someone explain why there is a difference in behaviour, is it a bug or expected behaviour?
$list = “A”, “B”, “C”, “D”
PS C:> ForEach ($item in $list) {$item}
A
B
C
D
PS C:> ForEach-Object ($item in $list) {$item} At line:1 char:23
ForEach-Object ($item in $list) {$item}
~~
Unexpected token ‘in’ in expression or statement.
At line:1 char:22
ForEach-Object ($item in $list) {$item}
~
Missing closing ‘)’ in expression.
At line:1 char:31
ForEach-Object ($item in $list) {$item}
~
Unexpected token ‘)’ in expression or statement.
+ CategoryInfo : ParserError: ( , ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
“Foreach” are just 7 letters that PowerShell will have to parse in two different ways, depending on the context.
1. As you correctly mentioned, they could be an alias for a Cmdlet called Foreach-Object. Other alias is %, but you’ve already found them with Get-Alias.
To be understood as such a cmdlet, you have to use it in a pipeline. In your example :
$list | Foreach-Object -Process { $_ }
This could be abbreviated with the alias and using default parameters to
$list | Foreach { $_ }
But I wouldn’t recommend it. Do not use aliases, they could have been modified to do a different thing…
2. “Foreach” can also be a keyword, a language structure used to enumerate any object which can be enumerated.
The syntax is totally different (similar to foreach in C#, for example), and is NOT translated to a cmdlet.
foreach ($element in $list) { $element }
Notice in this case you don’t use $_ but a variable you explicitly declare ($element in this example)
Unfortunately they chose “foreach” for both the keyword and the alias, which makes things slightly difficult.
Homework : Foreach-Object has also a -Begin and -End parameter…