Solution: move Name
parameter to the first position to be sure string passed will be bound to this parameter rather than to Login
parameter, one that you want to pass values to using pipeline anyways.
Reason: in-line parameter binding is a process that happens before pipeline processing starts. For example simple function, that is somewhat similar to your cmdlet:
function Test-FooBar {
param (
[Parameter(ValueFromPipeline)]
$Foo,
$Bar
)
process {
"Foo: $Foo Bar: $Bar"
}
}
Depending on positional binding (with one that takes value from pipeline in the first position):
Trace-Command -Name ParameterBinding -Expression { 1 | Test-FooBar 2} -PSHost
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Foo-Bar]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Foo-Bar]
DEBUG: ParameterBinding Information: 0 : BIND arg [2] to parameter [Foo]
DEBUG: ParameterBinding Information: 0 : BIND arg [2] to param [Foo] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Foo-Bar]
DEBUG: ParameterBinding Information: 0 : BIND arg [] to parameter [Bar]
DEBUG: ParameterBinding Information: 0 : BIND arg [] to param [Bar] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
(...)
'2' is already bound to first positional, so you will get error that pipeline input can not be bound (eventually).
Same, but this time we make sure that '2' will be bound to second parameter:
Trace-Command -Name ParameterBinding -Expression { 1 | Test-FooBar -Bar 2} -PSHost
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Test-FooBar]
DEBUG: ParameterBinding Information: 0 : BIND arg [2] to parameter [Bar]
DEBUG: ParameterBinding Information: 0 : COERCE arg to [System.Object]
DEBUG: ParameterBinding Information: 0 : Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 : BIND arg [2] to param [Bar] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Test-FooBar]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Test-FooBar]
DEBUG: ParameterBinding Information: 0 : BIND arg [] to parameter [Foo]
DEBUG: ParameterBinding Information: 0 : BIND arg [] to param [Foo] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Test-FooBar]
DEBUG: ParameterBinding Information: 0 : PIPELINE object TYPE = [System.Int32]
DEBUG: ParameterBinding Information: 0 : RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 : Parameter [Foo] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 : BIND arg [1] to parameter [Foo]
DEBUG: ParameterBinding Information: 0 : BIND arg [1] to param [Foo] SUCCESSFUL
(...)
As you can see now - once BeginProcessing is called BIND PIPELINE triggers and because there are still parameters accepting pipeline input present - it works fine.