Foreach vs Foreach-object

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}
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: (:slight_smile: [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken

You are partially right and partially wrong :slight_smile:

“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…

Many thanks Ruiz, that explains the change in behaviour… Using alias as foreach for foreach-object confused me a bit