Custom error from parameters in PowerShell

后端 未结 4 2017
夕颜
夕颜 2020-12-17 14:25

Is it possible to have ValidateScript generate a custom error message when a test fails, like say Test-Path?

Instead of this:

相关标签:
4条回答
  • 2020-12-17 14:56

    I am not sure.

    A suggestion: maybe you want to just trap the error, and make your own message.

    trap [Error.Type] { 
      @"
      The message you want displayed.
      With maybe some additional information.
      I.e.: The full message itself: {0}' -f  $_.Error.Message;
      continue;
    }
    
    0 讨论(0)
  • 2020-12-17 14:59

    I think you've found the straightforward workarounds.

    The parameter validation logic is extensible, but requires some C#. If you implement the abstract class System.Management.Automation.ValidateArgumentsAttribute, your implementation can throw a System.Management.Automation.ValidationMetadtaException that PowerShell will use to report the error, and you can naturally use any message you like when creating that exception.

    0 讨论(0)
  • 2020-12-17 15:03

    You can just do

    ValidateScript({Test-Path $_ -PathType Container}, ErrorMessage="Must exist")]
    

    That gives you error messages like:

    Cannot validate argument on parameter 'Folder'. Must exist
    

    At least in current powershell versions (7.x at the time of writing this).

    Generally, for you powershell-only devs, when you use attributes (stuff like [ValidateScript), then you can sometimes also set additional properties with the syntax as above. To see which properties, you can just google for the name of the attribute postfixed with "Attribute", eg "ValidateScriptAttribute", and then look at the "Properties" section for all writeable properties.

    0 讨论(0)
  • 2020-12-17 15:20

    Your ValidateScript should look something like this:

    [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."
        }
    })]
    

    That will give you a message like this:

    Test-Folder : Cannot validate argument on parameter 'Folder'. Cannot find path '\\server\Temp\asdf' because it does not exist. Maybe there are network issues?

    Or:

    Test-Folder : Cannot validate argument on parameter 'Folder'. The path '\\server\Temp\asdf' is not a container.

    If the older versions of PowerShell are throwing a double error, you may need to test inside the function:

    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}"
    }
    

    The part that I always hated in PowerShell was trying to figure out what error to catch; without catching all. Since I finally figure it out, here's how:

    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
    
    0 讨论(0)
提交回复
热议问题