PowerShell参数集需要命名参数



我有一个函数的参数和它们的集合的代码片段

function Test {
[CmdletBinding(DefaultParameterSetName='StringConsole')]
param (
[Parameter(Mandatory,
ValueFromPipelineByPropertyName,
ParameterSetName = 'ObjectFile')]
[Parameter(Mandatory,
ValueFromPipelineByPropertyName,
ParameterSetName = 'StringFile')]
[Alias("PSPath")]
[ValidateNotNullOrEmpty()]
[string]
$Path,
[Parameter(Mandatory,
ValueFromPipeline,
ParameterSetName='StringFile',
Position = 0)]
[Parameter(Mandatory,
ValueFromPipeline,
ParameterSetName='StringConsole',
Position = 0)]
[ValidateNotNullOrEmpty()]
[string]
$Message,
[Parameter(Mandatory,
ValueFromPipeline,
ParameterSetName='ObjectFile',
Position = 0)]
[Parameter(Mandatory,
ValueFromPipeline,
ParameterSetName='ObjectConsole',
Position = 0)]
[ValidateNotNullOrEmpty()]
[object]
$Object,

[Parameter(ParameterSetName='StringFile')]
[Parameter(ParameterSetName='StringConsole')]
[ValidateSet('Information', 'Verbose', 'Warning', 'Error', 'Object')]
[string]
$Severity = 'Information',
[Parameter(ParameterSetName='StringFile')]
[Parameter(ParameterSetName='StringConsole')]
[switch]
$NoPreamble,
[Parameter(ParameterSetName = 'StringConsole')]
[Parameter(ParameterSetName = 'ObjectConsole')]
[switch]
$Console
)
}

如果我使用

调用函数
Test 'Hello, World'

它正确地使用CmdletBinding

设置的StringConsole

默认参数如果我使用

调用函数
Test -Message 'Hello, World' -Path C:SomeFile.txt

正确使用StringFile参数集

但是如果我用

调用函数
Test 'Hello, World' -Path C:SomeFile.txt

我得到这个错误,函数没有执行:

参数集无法使用指定的命名参数解析

该错误明确指出无法使用NAMED参数解析参数集。如果一个参数被位置绑定,它是否也满足了"命名"条件?参数?还是必须使用名称专门绑定参数?

无论如何,我可以设计参数集,使我的最后一个例子工作,而不是抛出一个错误?

用于参数集的逻辑看起来非常好,但问题是您有Position = 0(-Message-Object)的2个参数,通常这不会是问题,但其中一个是System.Object类型,因为所有对象都继承自该类,无论您在位置0传递什么作为参数,它都会匹配此参数。由于Position = 0上的另一个参数是System.String类型,那么'Hello, World'(一个字符串,但也是一个对象)匹配两个参数集,绑定器不知道您想使用哪个参数集。

一个非常简单的方法来看到这一点,不改变你的当前代码,只是添加$PSCmdlet.ParameterSetName到函数的主体,将传递一个整数作为位置参数,一切工作如预期:
function Test {
[CmdletBinding(DefaultParameterSetName='StringConsole')]
param(
# same param block here
)
'Using: ' + $PSCmdlet.ParameterSetName
}
Test 0 -Path C:SomeFile.txt # => Using: ObjectFile

最新更新