Подтвердить что ты не робот

Настраиваемая ошибка из параметров в PowerShell

Возможно ли, чтобы ValidateScript генерировал пользовательское сообщение об ошибке при неудачном Test-Path теста, как, например, Test-Path?

Вместо этого:

Test-Folder: невозможно проверить аргумент параметра "Папка". Сценарий проверки "Test -Path $ _ -Path Type Container" для аргумента со значением "blabla" не вернул результат True. Определите причину сбоя сценария проверки, а затем повторите запятую.

Было бы неплохо, чтобы он сообщал об этом вместо этого в переменной $Error:

Папка не найдена, возможно, есть проблемы с сетью?

Код:

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

Обходной путь 1:

Я мог бы удалить Mandatory=$true и изменить его, как показано ниже. Но это не дает мне правильный синтаксис Get-Help и не выполняет Test-Path, потому что он только проверяет 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"
}

Обходной путь 2:

Я нашел этот обходной путь в сообщении в блоге, но проблема в том, что он генерирует две ошибки вместо одной.

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

Обходной путь 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"
}
4b9b3361

Ответ 1

Ваш 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."
    }
})]

Это даст вам сообщение, подобное этому:

Test-Folder: невозможно проверить аргумент параметра "Папка". Не удается найти путь "\\ server\Temp\asdf", так как он не существует. Может быть, есть проблемы с сетью?

Или же:

Test-Folder: невозможно проверить аргумент параметра "Папка". Путь \\server\Temp\asdf не является контейнером.

Если в старых версиях PowerShell выдается двойная ошибка, вам может потребоваться выполнить тестирование внутри функции:

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

Часть, которую я всегда ненавидел в PowerShell, пыталась выяснить, какую ошибку поймать; не ловя все. Так как я наконец-то понял это, вот как:

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

Ответ 2

Я думаю, что вы нашли простые обходные пути.

Логика проверки параметров является расширяемой, но требует некоторого С#. Если вы реализуете абстрактный класс System.Management.Automation.ValidateArgumentsAttribute, ваша реализация может генерировать исключение System.Management.Automation.ValidationMetadtaException, которое PowerShell будет использовать для сообщения об ошибке, и вы, естественно, можете использовать любое сообщение, которое вам нравится, при создании этого исключения.

Ответ 3

Я не уверен.

Предложение: может быть, вы хотите просто перехватить ошибку и создать собственное сообщение.

trap [Error.Type] { 
  @"
  The message you want displayed.
  With maybe some additional information.
  I.e.: The full message itself: {0}' -f  $_.Error.Message;
  continue;
}