Write-Error 在 class 方法内部使用时不会产生有用的信息 |电源外壳

Write-Error doesn't result useful information when used inside class methods | Powershell

我使用了有和没有 class 的方法,Write-Error 似乎产生了不同的输出。在 class 的情况下,它不指定 函数并且行号始终为 1,1

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

oper1

上面的输出:

oper1 : The term '.\some_exe_which_does_not_exist.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At F:\debug\encryption_concat_tests\Untitled1.ps1:11 char:1 + oper1 + ~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,oper1

当我在 class 中包含相同的函数时,我得到了这个:

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()

The term '.\some_exe_which_does_not_exist.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + F:\debug\encryption_concat_tests\Untitled1.ps1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

classes 中的方法出现这种行为的原因可能是什么?

顺便说一句:Invoke-Expression (iex) should generally be avoided; definitely - 只需直接调用它,如下所示。


在 PowerShell class 方法中:

  • 不要使用 Write-Error,因为 classes 不是为了发出 非终止 错误而设计的。

    • 您看到任何输出的唯一原因是 错误 从 PowerShell Core 7.0.0-rc.3 开始,方法的 return 类型发生成为 [void] - 参见 GitHub issue #5331.
  • 相反,仅通过使用 Throw 语句 抛出 捕获错误来传达错误终止 错误(包括使用 -ErrorAction Stop 调用 .NET 方法和 cmdlet 的异常)。

    • 注意:Throw-ErrorAction Stop(或 $ErrorActionPreference = 'Stop')创建 script-terminating(线程终止)错误,而抛出异常通过 .NET 方法(未在 class 方法中捕获并重新抛出)仅创建 statement-terminating 错误;也就是说,虽然 class 方法主体立即终止,但默认情况下在调用者中继续执行;后者也适用于未找到可执行文件的调用运算符 (&)、1 / 0 等表达式中的错误以及发出语句终止错误(它们可以报告的最严重错误类型)的 cmdlet 调用没有他们被提升为脚本-终止-ErrorAction Stop;有关 PowerShell 复杂错误处理的全面概述,请参阅 this GitHub docs issue

请参阅 了解更多关于 class 方法中的错误处理和流输出行为的信息。

这是您的代码的更正版本。

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()
$operator.oper1()

我也有这个问题!但我真的很想弄清楚如何从函数中输出信息和 return 所需的信息类型! 我使用 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;
    }
}