Where-Object inconsistent behaviour between -InputObject parameter and pipe

Viewed 56

Issue

Calling the Where-Object cmdlet returns different outputs if the same PSObject is passed using the pipe or the -InputObject parameter:

  1. When using the pipe, the condition is applied.
  2. When using the -InputObject parameter, the condition is ignored.

Question

Why does the condition not apply when the -InputObject parameter is used?

MWE

Consider the following directory:

PS C:\> Get-ChildItem -Path "C:\tmp\mwe"


    Directory: C:\tmp\mwe


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        07/07/2021     15:51              0 a.txt
-a----        07/07/2021     15:54              0 b.csv
-a----        07/07/2021     15:53              0 c.log

Using pipe

When piping Get-ChildItem to Where-Object, the condition is properly applied and the text file is excluded from the output.

PS C:\> Get-ChildItem -Path "C:\tmp\mwe" | Where-Object -Property "Name" -NotMatch -Value "\.txt"


    Directory: C:\tmp\mwe


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        07/07/2021     15:54              0 b.csv
-a----        07/07/2021     15:53              0 c.log

Using -InputObject parameter

When using the -InputObject parameter, the condition is not applied and the text file is not excluded from the output.

PS C:\> Where-Object -InputObject (Get-ChildItem -Path "C:\tmp\mwe") -Property "Name" -NotMatch -Value "\.txt"


    Directory: C:\tmp\mwe


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        07/07/2021     15:51              0 a.txt
-a----        07/07/2021     15:54              0 b.csv
-a----        07/07/2021     15:53              0 c.log
1 Answers

After careful reading of the pipeline documentation, this distinct behaviour is indeed intended.

Piping objects to a command is much like using a parameter of the command to submit the objects.

[...]

However, there's an important difference. When you pipe multiple objects to a command, PowerShell sends the objects to the command one at a time. When you use a command parameter, the objects are sent as a single array object. This minor difference has significant consequences.

Thank you Mathias R. Jessen and iRon for pointing that out in the comments.

Related