PowerShell脚本参数:在使用不正确时显示帮助信息?

3
在Powershell V2中,我试图使用Param()声明来解析传递到脚本中的开关。我的问题可以用这个脚本(example.ps1)来说明:
Param(
    [switch] $A,
    [switch] $B,
    [switch] $C
)
echo "$A, $B, $C"

我的问题是,这个脚本会默默地忽略任何不正确的开关。例如,“example.ps1 -asdf”只会打印“False,False,False”,而不是向用户报告不正确的用法。
我注意到,如果我添加一个位置参数,行为会发生变化:
Param(
    [switch] $A,
    [switch] $B,
    [switch] $C,
    [parameter(position=0)] $PositionalParameter
)
echo "A:$A, B:$B, C:$C"

现在,如果我运行“example2.ps1 -asdf”,将会引发ParameterBindingException异常。但是,“example2.ps1 asdf”(注意没有前导破折号的参数)仍然会被默默接受。

我有两个问题:

  1. 是否有一种方法可以让Powershell始终将我的脚本中多余的参数报告为错误?在我的脚本中,我只想允许固定的开关(-A、-B、-C),任何其他参数都应该是错误的。

  2. 当检测到参数错误时,我能否让Powershell打印用法(即“get-help example.ps1”)而不是引发ParameterBindingException异常?


你必须要有 Param ( [switch] $x ) 吗?还是 switch ($a) { A B C default } 也可以? - AvkashChauhan
我认为那样做行不通,因为我需要支持所有开关的组合。这是一个有多个阶段的脚本,我想能够禁用单个阶段:run.ps1 -SkipPhase1 -SkipPhase5 - Igor ostrovsky
@AvkashChauhan:我可能也误解了你的观点。如果你建议我自己循环遍历参数,我肯定可以做到。我一直在尝试弄清楚Param()声明是否更方便,但也许循环遍历参数才是正确的做法。 - Igor ostrovsky
以下是几种可能的情况讨论:http://technet.microsoft.com/zh-cn/library/ff730937.aspx - AvkashChauhan
@AvkashChauhan:谢谢,但那是“switch”关键字完全不同的用法。我的问题涉及到[switch]的用法,就像这里讨论的一样:http://technet.microsoft.com/en-us/library/hh847743 - Igor ostrovsky
2个回答

5

你可以尝试使用CmdletBinding,如about_Functions_CmdletBindingAttribute所述,对于具有CmdletBinding属性的函数,未知参数和没有匹配位置参数的位置参数会导致参数绑定失败。

[CmdletBinding()]
Param(
      [switch] $A,
      [switch] $B,
      [switch] $C)

echo "A:$A, B:$B, C:$C"

1
好的,谢谢...那个解决方案似乎会在传入无效参数时抛出异常。你知道如何打印帮助信息吗?谢谢。 - Igor ostrovsky
抱歉,对于我来说这是CmdLet的正常行为,因此脚本用户必须捕获异常或处理异常,但对于交互式用户来说并不是问题。 - JPBlanc
谢谢,但不幸的是我没有理解你的评论。你是在建议我创建一个 cmdlet 来抛出异常,然后再创建一个包装“脚本”来捕获异常并向用户显示消息吗? - Igor ostrovsky
1
一点也不,我的考虑是CmdletBinding让你的脚本具备了Cmdlet的行为。所以对于交互式用户来说这是正常的行为,而如果你从另一个脚本中调用这个脚本,你可以使用'Trap'或者'try/catch'来捕获异常。 - JPBlanc
1
好的,谢谢。你是对的 - 显然在Powershell中抛出ParameterBindingException异常是适当的行为。例如,即使是“dir -asdf”也会做同样的事情。 - Igor ostrovsky

2
您可以尝试通过检查$args来实现。
Function myfunction
{
  param(
        [switch] $A,
        [switch] $B,
        [switch] $C
)

foreach ( $key in $PSBoundParameters.keys )
{    
  if ( $args -gt 0) 
        {$script:test = $false ; break}
    else
        {$script:test = $true}
}    

if ($test)     
{ 
 "Parameters are ok" # ... your code script here
}    
else
{
  "Parameters error. Check Command" # or get-help myfuction
}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接