Powershell: Strange behavior of parameters with the pipeline input

Created on 23 Apr 2019  路  2Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

function PipelineArgWorks{
    param($Option)
    process{
        Write-Host "$Option $_"
    }
}

function PipelineArgError{
    param([Parameter()]$Option)
    process{
        Write-Host "$Option $_"
    }
}

"World!" | PipelineArgWorks -Option "Hello" # <- prints "Hello world!"

# raises "The input object cannot be bound to any parameters for the command
# either because the command does not take pipeline input or the input and its
# properties do not match any of the parameters that take pipeline input."
"World!" | PipelineArgError

Expected behavior

Hello World!
Hello World!

Actual behavior

Hello World!
PipelineArgError : The input object cannot be bound to any parameters for the command either because the command does no
t take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At /mnt/c/Projects/Test.ps1:20 char:12
+ "World!" | PipelineArgError
+            ~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (World!:String) [PipelineArgError], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,PipelineArgError

Environment data

Name                           Value
----                           -----
PSVersion                      6.2.0
PSEdition                      Core
GitCommitId                    6.2.0
OS                             Linux 4.4.0-17763-Microsoft #379-Microsoft Wed Mar 06 19:16:00 PST 2019
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question Resolution-Answered

Most helpful comment

the first expression behaves somewhat like an unnamed scriptblock. Pipeline input is bound to $_ during the process block and to none of the parameters.

When you apply either [CmdletBinding()] or a [Parameter()] attribute, PS switches from the loose function execution to the stricter PSScriptCmdlet mode.

This means you don't get parameters for free, you _must_ define pipeline input parameters if the function is going to use pipeline input. This is done by providing the ValueFromPipeline property value to a [Parameter()] attribute.

All 2 comments

IMO, Error is expected, but I never expect first expression to execute.

the first expression behaves somewhat like an unnamed scriptblock. Pipeline input is bound to $_ during the process block and to none of the parameters.

When you apply either [CmdletBinding()] or a [Parameter()] attribute, PS switches from the loose function execution to the stricter PSScriptCmdlet mode.

This means you don't get parameters for free, you _must_ define pipeline input parameters if the function is going to use pipeline input. This is done by providing the ValueFromPipeline property value to a [Parameter()] attribute.

Was this page helpful?
0 / 5 - 0 ratings