简体   繁体   English

在 class 方法内部使用时,Write-Error 不会产生有用的信息 | Powershell

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

I used a method with and without a class and the Write-Error seems to produce different outputs.我使用了有和没有 class 的方法,Write-Error 似乎产生了不同的输出。 In case of class, it doesn't specify the function and the line number is always 1,1对于 class,它不指定function,行号始终为 1,1

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

oper1

Output for above: Output 以上:

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. oper1 :术语“.\some_exe_which_does_not_exist.exe”未被识别为 cmdlet、function、脚本文件或可运行程序的名称。 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在 F:\debug\encryption_concat_tests\Untitled1.ps1: 11 char:1 + oper1 + ~~~~~ + CategoryInfo: NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId: Microsoft.PowerShell.Commands.WriteErrorException,操作员1

When I enclosed the same function in a class, I got this:当我将相同的 function 包含在 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.术语“.\some_exe_which_does_not_exist.exe”未被识别为 cmdlet、function、脚本文件或可运行程序的名称。 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在第 1 行 char:1 + F:\debug\encryption_concat_tests\Untitled1.ps1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [Write-Error], WriteErrorException + FullyQualifiedErrorId: Microsoft.PowerShell.Commands.WriteErrorException

What could be the reason for this behaviour for methods inside classes?类内方法出现这种行为的原因可能是什么?

As an aside: Invoke-Expression ( iex ) should generally be avoided ; iex通常应该避免Invoke-Expression ( iex ) definitely don't use it to invoke an external program - just invoke it directly , as shown below.绝对不要用它来调用外部程序-只需调用它直接,如下图所示。


In PowerShell class methods:在 PowerShell 类方法中:

  • Do not use Write-Error , as classes are not designed to emit non-terminating errors.不要使用Write-Error ,因为类不是为了发出非终止错误而设计的。

    • The only reason you're seeing any output at all is a bug as of PowerShell Core 7.0.0-rc.3 with methods whose return type happens to be [void] - see this GitHub issue .您看到任何输出的唯一原因是 PowerShell Core 7.0.0-rc.3 的错误,其方法的返回类型恰好为[void] - 请参阅此 GitHub 问题
  • Instead, communicate errors solely by throwing them with the Throw statement or by not catching terminating errors (which include exceptions from .NET methods and cmdlet calls with -ErrorAction Stop ).相反,仅仅通过投掷他们沟通错误Throw陈述或者不要再追终止错误(包括从.NET方法,并与小命令调用例外-ErrorAction Stop )。

    • Note: Throw and -ErrorAction Stop (or $ErrorActionPreference = 'Stop' ) create script -terminating (thread-terminating) errors, whereas exceptions thrown by a .NET method (not caught and re-thrown in the class method) only create statement -terminating errors;注意: Throw-ErrorAction Stop (或$ErrorActionPreference = 'Stop' )创建脚本终止(线程终止)错误,而 .NET 方法抛出的异常(未在类方法中捕获并重新抛出)仅创建语句- 终止错误; that is, while the class-method body is terminated right away, execution continues in the caller by default;也就是说,虽然类方法主体立即终止,但默认情况下在调用者中继续执行; the latter also applies to the call operator ( & ) not finding an executable, errors in expressions such as 1 / 0 , and cmdlet calls that emit statement-terminating errors (the most severe error type they can report) without their being promoted to script -terminating ones with -ErrorAction Stop ;后者也适用于未找到可执行文件的调用运算符 ( & )、表达式中的错误(例如1 / 0 )以及发出语句终止错误(它们可以报告的最严重的错误类型)的 cmdlet 调用而没有将它们提升为脚本-用-ErrorAction Stop终止那些; see this GitHub docs issue for a comprehensive overview of PowerShell's complex error handling.有关 PowerShell 复杂错误处理的全面概述,请参阅此 GitHub 文档问题

See this answer for more information about error handling and stream-output behavior in class methods in particular.有关特别是类方法中的错误处理和流输出行为的更多信息,请参阅此答案

Here's a corrected version of your code.这是您的代码的更正版本。

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

I also have this problem!我也有这个问题! But I really wanted to figure out how to output information and return the desired type of information from the function!但我真的很想弄清楚如何从函数中获取 output 信息并返回所需类型的信息! I solved the problem using Write-Warning我使用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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM