在使用参数集名称的同时使用 $args

Consume $args while also using parameter set names

考虑以下玩具示例脚本 test.ps1:

Param(
    [Parameter(ParameterSetName='readfile',Position=0,Mandatory=$True)]
    [string] $FileName,

    [Parameter(ParameterSetName='arg_pass',Mandatory=$True)]
    [switch] $Ping
)

if ($Ping.isPresent) {
    &$env:ComSpec /c ping $args
} else {
    Get-Content $FileName 
}

想要的效果是

.\test.ps1 FILE.TXT

显示FILE.TXT

的内容
.\test.ps1 -Ping -n 5 127.0.0.1

ping 本地主机 5 次。

不幸的是,后者因错误而失败

A parameter cannot be found that matches parameter name 'n'.
At line:1 char:18
+ .\test.ps1 -Ping -n 5 127.0.0.1
+                  ~~
    + CategoryInfo          : InvalidArgument: (:) [test.ps1], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,test.ps1

当然,这只是一个最小的例子。

一般来说,我正在寻找一种方法来向我的脚本引入一个 [switch] 参数,该参数存在于它自己的参数集中,并且当存在该开关时,我想使用命令行中的所有剩余参数并将它们传递给另一个命令行应用程序。在 PowerShell 中执行此操作的方法是什么?

您可以使用 ValueFromRemainingArguments 参数属性。我还建议在 CmdletBinding 中指定默认参数集名称。示例:

[CmdletBinding(DefaultParameterSetName="readfile")]
param(
  [parameter(ParameterSetName="readfile",Position=0,Mandatory=$true)]
    [String] $FileName,
  [parameter(ParameterSetName="arg_pass",Mandatory=$true)]
    [Switch] $Ping,
  [parameter(ParameterSetName="arg_pass",ValueFromRemainingArguments=$true)]
    $RemainingArgs
)
if ( $Ping ) {
  ping $RemainingArgs
}
else {
  Get-Content $FileName 
}

(另外:我认为不需要 & $env:ComSpec /c。您可以在 PowerShell 中 运行 命令而无需生成 cmd.exe 的副本。)