PowerShell:使用参数验证而不抛出异常

时间:2012-09-18 17:01:07

标签: exception powershell command-line-arguments

我想以这种方式调用PowerShell脚本:
script.ps1 -path mypath\to\files\ -days 6 -hours 0

要验证命令行参数,我可以手动执行,也可以依赖param语法:

Param (
    [Parameter(Mandatory=$true )] [string] $path,
    [Parameter(Mandatory=$false)] [int]    $days,
    [Parameter(Mandatory=$false)] [int]    $hours
)

如果我使用param语法:

  • param定义必须是脚本中的第一行(不包括注释)。好的,对我来说不是问题

  • 如果参数不正确,我无法捕获错误(例如显示自定义错误消息)

当使用错误的参数调用脚本时,我想显示自定义错误消息 是否有可能以及如何在参数错误的情况下捕获异常?

5 个答案:

答案 0 :(得分:3)

没关系,不可能使用param AND来捕获相关的异常。

答案 1 :(得分:0)

示例适用于函数(简单和高级),但同样的想法也适用于param的脚本:

# Simple function.
# Everything not declared in `param` goes to $args.
# If $args is not empty then there are "invalid" parameters or "unexpected" arguments
function test {
    param (
        [string]$path,
        [int]$days,
        [int]$hours
    )
    # check $args and throw an error (in here we just write a warning)
    if ($args) { Write-Warning "Unknown arguments: $args" }
}

或者

# Advanced function.
# For an advanced function we can use an extra argument $args
# with an attribute `[Parameter(ValueFromRemainingArguments=$true)]`
function test {
    param (
        [Parameter(Mandatory=$true )] [string] $path,
        [Parameter(Mandatory=$false)] [int]    $days,
        [Parameter(Mandatory=$false)] [int]    $hours,
        [Parameter(ValueFromRemainingArguments=$true)] $args
    )
    # check $args and throw an error (in this test we just write a warning)
    if ($args) { Write-Warning "Unknown arguments: $args" }
}

以下测试:

# invalid parameter
test -path p -invalid -days 5

# too many arguments
test -path p 5 5 extra
两种情况下的

都会产生相同的输出:

WARNING: Unknown arguments: -invalid
WARNING: Unknown arguments: extra

答案 2 :(得分:0)

可能的解决方法是将您的实际功能包装在另一个中。类似于私人/公共关系的东西。例如:

function Example-Private
{
    [CmdletBinding()]
    Param
    (
        [ValidateNotNullOrEmpty()]
        [string]$Arg1,
        [ValidateNotNullOrEmpty()]
        [string]$Arg2   
   )

   # Do what you need
}

function Example-Public
{
    [CmdletBinding()]
    Param
    (
        [string]$Arg1,
        [string]$Arg2   
    )

    try
    {
       Example-Private $Arg1 $Arg2
    }
    catch
    {
       # Display a user-friendly message, save exception into a log file, etc.
    }
}

如果您正在处理模块,可以在此处查看如何导出公共函数并隐藏私有函数:Export Powershell Functions

答案 3 :(得分:-1)

Begin块中,您始终可以对参数进行进一步验证,但如果参数错误,我认为您不希望继续执行。也就是说,你想要抛出一个终止错误。这是一个例子:

param (
    [Parameter(Mandatory=$true )] [string] $path,
    [Parameter(Mandatory=$false)] [int]    $days,
    [Parameter(Mandatory=$false)] [int]    $hours
)

Begin {
    if ($hours -lt 0 -or $hours -gt 23) {
        throw "Hours parameter must be between 0 and 23"
    }
}

那就是说,我不确定这比使用PowerShell的内置参数验证功能更好,例如:

param (
    [Parameter(Mandatory=$true )] [string] $path,
    [Parameter(Mandatory=$false)] [int]    $days,
    [Parameter(Mandatory=$false)]
    [ValidateRange(0,23)]
    [int]
    $hours
)

答案 4 :(得分:-1)

如果使用属性“ValueFromRemainingArguments”添加字符串类型的dummy-parameter,则可以使用param语法执行此操作。 然后,您可以在脚本中检查此伪参数并采取适当的操作,例如:

Param(
    [Parameter(Mandatory=$false)]
    [SWITCH]$myparam1,

    [Parameter(Mandatory=$false)]
    [SWITCH]$myparam2,

    [parameter(Mandatory=$false,ValueFromRemainingArguments=$true)]
    [STRING]$dummy     
    )

if ($dummy -eq anythingYouDontLike) throwAMessageOrSomething.