来自参数的PowerShell自定义错误

Dar*_*te1 13 parameters powershell

一个简单的问题,是否有可能ValidateScript在测试失败时生成自定义错误消息,比如说Test-Path

而不是这个:

测试文件夹:无法验证参数"文件夹"的参数.值为"blabla"的参数的"Test-Path $ _ -Path Type Container"验证脚本未返回True结果.确定验证脚本失败的原因,然后再次尝试使用逗号.

让它在$Error变量中报告它会很高兴:

找不到"文件夹",可能存在网络问题?

码:

Function Test-Folder {
    Param (
        [parameter(Mandatory=$true)]
        [ValidateScript({Test-Path $_ -PathType Container})]
        [String]$Folder
    )
    Write-Host "The folder is: $Folder"
}
Run Code Online (Sandbox Code Playgroud)

解决方法1:

我可以删除Mandatory=$true并更改如下.但这并没有给我正确的Get-Help语法,也没有进行Test-Path验证,因为它只检查参数是否存在.

Function Test-Folder {
    Param (
        [parameter()]
        [String]$Folder = $(throw "The $_ is not found, maybe there are network issues?")
    )
    Write-Host "The folder is: $Folder"
}
Run Code Online (Sandbox Code Playgroud)

解决方法2:

我在博客上找到了这个解决方法,但问题是它产生了2个错误而不是1个错误.

Function Test-Folder {
    Param (
        [parameter(Mandatory=$true)]
        [ValidateScript({
            if (Test-Path $_ -PathType Container) {$true}
            else {Throw "The $_ is not found, maybe there are network issues?"}})]
        [String]$Folder
    )
    Write-Host "The folder is: $Folder"
}
Run Code Online (Sandbox Code Playgroud)

解决方法3:

我还可以尝试通过添加评论部分来更清楚.但是,这仍然不是理想的结果,因为错误需要对最终用户可读.

Function Test-Folder {
    Param (
        [parameter(Mandatory=$true)]
        [ValidateScript({
        # The folder is not found, maybe there are network issues?
        Test-Path $_ -PathType Container})]
        [String]$Folder
    )
    Write-Host "The folder is: $Folder"
}
Run Code Online (Sandbox Code Playgroud)

Ver*_*Ray 10

ValidateScript应该看起来像这样:

[ValidateScript({
    try {
        $Folder = Get-Item $_ -ErrorAction Stop
    } catch [System.Management.Automation.ItemNotFoundException] {
        Throw [System.Management.Automation.ItemNotFoundException] "${_} Maybe there are network issues?"
    }
    if ($Folder.PSIsContainer) {
        $True
    } else {
        Throw [System.Management.Automation.ValidationMetadataException] "The path '${_}' is not a container."
    }
})]
Run Code Online (Sandbox Code Playgroud)

这将给你一个这样的消息:

测试文件夹:无法验证参数"文件夹"的参数.无法找到路径'\\ server\Temp\asdf',因为它不存在.也许有网络问题?

要么:

测试文件夹:无法验证参数"文件夹"的参数.路径'\\ server\Temp\asdf'不是容器.

如果旧版本的POSH抛出双重错误,您可能需要在函数内部进行测试:

Function Test-Folder {
    Param (
        [parameter(Mandatory=$true)]
        [String]$Folder
    )

    try {
        $Folder = Get-Item $_ -ErrorAction Stop
    } catch [System.Management.Automation.ItemNotFoundException] {
        Throw [System.Management.Automation.ItemNotFoundException] "The '${Folder}' is not found, maybe there are network issues?"
    }

    if (-not $Folder.PSIsContainer) {
        Throw [System.Management.Automation.ApplicationFailedException] "The path '${_}' is not a container."
    }

    Write-Host "The folder is: ${Folder}"
}
Run Code Online (Sandbox Code Playgroud)

我一直讨厌POSH的部分是试图找出要捕捉的错误; 没有抓住所有.自从我最终弄明白,以下是:

PS > Resolve-Path 'asdf'
Resolve-Path : Cannot find path '.\asdf' because it does not exist.
At line:1 char:1
+ Resolve-Path 'asdf'
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (asdf:String) [Resolve-Path], ItemNotFoundE
   xception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand

PS > $Error[0].Exception.GetType().FullName
System.Management.Automation.ItemNotFoundException
Run Code Online (Sandbox Code Playgroud)


AMo*_*nin 5

你可以这样做

ValidateScript({Test-Path $_ -PathType Container}, ErrorMessage="Must exist")]
Run Code Online (Sandbox Code Playgroud)

这会给你这样的错误消息:

Cannot validate argument on parameter 'Folder'. Must exist
Run Code Online (Sandbox Code Playgroud)

至少在当前的 powershell 版本中(撰写本文时为 7.x)。

一般来说,对于仅使用 powershell 的开发人员来说,当您使用属性(例如[ValidateScript)时,有时还可以使用上述语法设置其他属性。要查看哪些属性,您只需搜索带有“Attribute”后缀的属性名称,例如“ValidateScriptAttribute”,然后查看“Properties”部分以查找所有可写属性。