Write-Error не дает полезной информации при использовании внутри методов класса | Powershell

Я использовал метод с классом и без него, и похоже, что Write-Error дает разные результаты. В случае класса он не указывает функцию, а номер строки всегда 1,1

function oper1() {
    Try {
        [string] $cmd = ".\some_exe_which_does_not_exist.exe"
        iex $cmd 
    }
    Catch {
        Write-Error $_.Exception.Message
    }
}

oper1

Вывод для выше:

oper1: термин '.\some_exe_which_does_not_exist.exe' не распознается как имя командлета, функции, файла сценария или работающей программы. Проверьте написание имени или, если был включен путь, проверьте правильность пути и повторите попытку. В F:\debug\encryption_concat_tests\Untitled1.ps1:11 символов: 1 + oper1 + ~~~~~ + CategoryInfo: NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId: Microsoft.PowerShell.Commands.WriteErrorException,oper1

Когда я включил ту же функцию в класс, я получил следующее:

class Operator {
    [void] oper1() {
        Try {
            [string] $cmd = ".\some_exe_which_does_not_exist.exe"
            iex $cmd 
        }
        Catch {
            Write-Error $_.Exception.Message
        }
    }
}

[Operator] $operator = New-Object Operator
$operator.oper1()

Термин '.\ Some_exe_which_does_not_exist.exe' не распознается как имя командлета, функции, файла сценария или работающей программы. Проверьте написание имени или, если путь был включен, убедитесь, что путь правильный, и повторите попытку. В строке: 1 символ: 1 + F:\debug\encryption_concat_tests\Untitled1.ps1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId: Microsoft.PowerShell.Commands.WriteErrorException

В чем может быть причина такого поведения методов внутри классов?

2 ответа

Решение

Как в сторону: Invoke-Expression (iex) обычно следует избегать; определенно не используйте его для вызова внешней программы - просто вызывайте ее напрямую, как показано ниже.


В методах класса PowerShell:

  • Не использовать Write-Error, поскольку классы не предназначены для выдачи непрекращающихся ошибок.

    • Единственная причина, по которой вы вообще видите какой-либо вывод, - это ошибка PowerShell Core 7.0.0-rc.3 с методами, возвращаемым типом которых является[void]- см. эту проблему на GitHub.
  • Вместо этого сообщайте об ошибках, просто бросая ихThrowоператор или не обнаруживая завершающие ошибки (которые включают исключения из методов.NET и вызовов командлетов с-ErrorAction Stop).

    • Примечание: Throw а также -ErrorAction Stop (или $ErrorActionPreference = 'Stop') создавать ошибки, завершающие сценарий(завершающие пространство выполнения), в то время как исключения, создаваемые методом.NET (не перехваченные и не генерируемые повторно в методе класса), создают только ошибки, завершающие выполнение оператора; то есть, хотя тело метода класса завершается сразу, выполнение по умолчанию продолжается в вызывающей программе; последнее также относится к оператору вызова (&) не удается найти исполняемый файл, ошибки в таких выражениях, как 1 / 0, и вызовы командлетов, которые выдают ошибки завершения оператора (наиболее серьезный тип ошибки, о котором они могут сообщить) без их повышения до ошибок завершения сценария с помощью-ErrorAction Stop; см. этот выпуск документации GitHub, чтобы получить исчерпывающий обзор сложной обработки ошибок PowerShell.

См. Этот ответ для получения дополнительной информации об обработке ошибок и поведении потокового вывода, в частности, в методах класса.

Вот исправленная версия вашего кода.

class Operator {
    [void] oper1() {
        Try {
            # Try to invoke a non-existent executable.
            & ".\some_exe_which_does_not_exist.exe"
        }
        Catch {
            # Re-throw the error.
            # Alternatively, don't use try / catch, but the error
            # then only aborts the method call, not the entire script.
            Throw
        }
    }
}

[Operator] $operator = New-Object Operator
$operator.oper1()

у меня тоже такая проблема! Но очень хотелось разобраться, как выводить информацию и возвращать нужный тип информации из функции! Я решил проблему с помощью Write-Warning

      [bool] hidden AddUserToGroup([Microsoft.ActiveDirectory.Management.ADGroup]$group, [Microsoft.ActiveDirectory.Management.ADUser]$user)
{
    try
    {
        Add-ADGroupMember -Server $this.server -Identity $group -Members $user;
        return $true;
    }
    catch [System.SystemException]
    {
        Write-Warning $_.Exception.Message;
        return $false;
    }
}
Другие вопросы по тегам