1

我的 cmdlet 尝试获取 2 个参数,1 个来自管道,1 个来自用户输入,我想知道是否可以通过位置参数来完成,就像这样:

Set-login name pw | add-view viewName

add-view 是这样的:

[parameter(position=0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, Mandatory = true)]
public loginInfo Login {}
[parameter(position=1, Mandatory = true)]
public String Name {}
...

然而,有了上述属性,

Set-login name pw | add-view viewName 

将返回错误说 cannot convert Stringto loginInfo,我必须这样做:

$a = Set-login name pw
Add-View $a viewnames

或者

$a | Add-View -Name viewnames

似乎位置参数和管道相互矛盾,这是真的吗?解决方法是什么?

谢谢!

4

1 回答 1

3

解决方案:将Name参数移动到第一个位置以确保传递的字符串将绑定到此参数而不是Login参数,您希望将值传递给使用管道的参数。

原因:内联参数绑定是在管道处理开始之前发生的一个过程。例如简单的函数,它有点类似于你的 cmdlet:

function Test-FooBar {
param (
    [Parameter(ValueFromPipeline)]
    $Foo,
    $Bar
)

process {
    "Foo: $Foo Bar: $Bar"
}
}

取决于位置绑定(在第一个位置从管道中获取值):

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' 已经绑定到第一个位置,因此您将收到无法绑定管道输入的错误(最终)。

同样,但这次我们确保 '2' 将绑定到第二个参数:

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
(...)

正如您现在所看到的 - 一旦 BeginProcessing 被称为 BIND PIPELINE 触发器,并且因为仍然存在接受管道输入的参数 - 它工作正常。

于 2013-03-06T10:16:38.153 回答