这种方式无法按照您的意愿工作。您的两个参数都是相同的数据类型,PowerShell会在检查是否从管道传入之前绑定参数,并尝试立即从位置0开始填充。
我甚至尝试使用参数集重新实现它:
function Build-Path {
[CmdletBinding(DefaultParameterSetName='Default',PositionalBinding=$false)]
param(
[Parameter(
ParameterSetName='Default',
Mandatory=$true,
ValueFromPipeline=$true
)]
[Parameter(
ParameterSetName='LooseyGoosey',
Mandatory=$true,
Position=0
)]
[String]
$Left,
[Parameter(
ParameterSetName='Default',
Mandatory=$true,
Position=0
)]
[Parameter(
ParameterSetName='LooseyGoosey',
Mandatory=$true,
Position=1
)]
[String]
$Right
)
Join-Path $Left $Right
}
如果想了解PowerShell是如何绑定参数的,可以使用Trace-Command
命令:
Trace-Command -Name ParameterBinding -Expression { Build-Path (Get-Location) Test } -Verbose -PSHost
无论怎么切割,你都会遇到问题。没有
DefaultParameterSet
?参数集无法解析。改变默认设置?那么哪些调用有效或无效就只是发生了变化而已。
同时,你也不能将
-Right
参数变成一个
[String[]]
数组,因为在绑定时 PowerShell 会尝试强制转换,所以一个
[String]
仍然会被接受并绑定。
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-Location]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-Location]
DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-Location]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Build-Path]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Build-Path]
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to parameter [Right]
DEBUG: ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 : result returned from DATA GENERATION: C:\Users\Briantist
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to param [Right] SKIPPED
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to parameter [Left]
DEBUG: ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 : result returned from DATA GENERATION: C:\Users\Briantist
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to param [Left] SKIPPED
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to parameter [Right]
DEBUG: ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 : result returned from DATA GENERATION: C:\Users\Briantist
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to param [Right] SKIPPED
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to parameter [Right]
DEBUG: ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 : result returned from DATA GENERATION: C:\Users\Briantist
DEBUG: ParameterBinding Information: 0 : COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 : Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 : BIND arg [C:\Users\Briantist] to param [Right] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND arg [Test] to parameter [Right]
DEBUG: ParameterBinding Information: 0 : Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 : result returned from DATA GENERATION: Test
DEBUG: ParameterBinding Information: 0 : BIND arg [Test] to param [Right] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Build-Path]
DEBUG: ParameterBinding Information: 0 : PROMPTING for missing mandatory parameters using the host
$left | Join-Path -ChildPath $right
<-- 我相当确定Join-Path已经可以完成你所要求的功能了。 - Ryan Bemrose