如何在PowerShell中使用$PSCmdlet.WriteError实际生成错误?

huangapple go评论48阅读模式
英文:

How do I actually generate an error using $PSCmdlet.WriteError in PowerShell?

问题

我一直在研究在PowerShell中生成错误消息的方法,并偶然发现了这个示例...

$Exception = [Exception]::new("错误消息")
$ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
    $Exception,
    "错误ID",
    [System.Management.Automation.ErrorCategory]::NotSpecified,
    $TargetObject # 通常是触发错误的对象,如果可能的话
)
$PSCmdlet.WriteError($ErrorRecord)

然而,这不是一个有效的示例。我无法开始尝试它,因为我不知道如何使这个示例起作用。

InvalidOperation: 无法对空值表达式调用方法

我知道我可以使用Write-Error来生成一个非终止错误,但我真的不希望错误消息回显我用来生成错误消息的命令。

英文:

I've been reading up on generating error messages in PowerShell and stumbled across this example...

$Exception = [Exception]::new("error message")
$ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
    $Exception,
    "errorID",
    [System.Management.Automation.ErrorCategory]::NotSpecified,
    $TargetObject # usually the object that triggered the error, if possible
)
$PSCmdlet.WriteError($ErrorRecord)

However, this isn't a working example. I can't start experimenting with it, since I have no idea what would make the example tick to begin with.

InvalidOperation: You cannot call a method on a null-valued expression.

I do know I could use Write-Error instead to generate a non-terminating error. But I really don't like the error message to echo the command I used to generate the error message.

答案1

得分: 2

你的代码看起来不错,唯一的问题是,$PSCmdlet 只在 高级函数或脚本块 的上下文中可用:

function Testing {
    [CmdletBinding()]
    param($TargetObject)

    $Exception = [Exception]::new('error message')
    $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
        $Exception,
        'errorID',
        [System.Management.Automation.ErrorCategory]::NotSpecified,
        $TargetObject) # 通常是触发错误的对象,如果可能的话

    $PSCmdlet.WriteError($ErrorRecord)
}

Testing foo!

针对评论的后续,再次强调,要在脚本块的上下文中(无论是 Invoke-Command 还是 Start-Job 或任何其他脚本块),它需要是高级脚本块,因此需要有 [CmdletBinding()][Parameter(...)] 修饰才能使用:

Start-Job {
    [CmdletBinding()]
    param($TargetObject)

    $Exception = [Exception]::new('error message')
    $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
        $Exception,
        'errorID',
        [System.Management.Automation.ErrorCategory]::NotSpecified,
        $TargetObject) # 通常是触发错误的对象,如果可能的话

    $PSCmdlet.WriteError($ErrorRecord)
} -ArgumentList foo! | Receive-Job -AutoRemoveJob -Wait

$Error[0].TargetObject # foo!
英文:

Your code looks good, the only problem is that $PSCmdlet is only available for you in the context of an advanced function or script block:

function Testing {
    [CmdletBinding()]
    param($TargetObject)

    $Exception = [Exception]::new('error message')
    $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
        $Exception,
        'errorID',
        [System.Management.Automation.ErrorCategory]::NotSpecified,
        $TargetObject) # usually the object that triggered the error, if possible

    $PSCmdlet.WriteError($ErrorRecord)
}

Testing foo!

Following up on comments, again, in the context of a script block (be it an Invoke-Command or Start-Job or any other script block) it would need to be an advanced one, so it would need to have a [cmdletbinding()] or [Parameter(...)] decoration for that to happen:

Start-Job {
    [CmdletBinding()]
    param($TargetObject)

    $Exception = [Exception]::new('error message')
    $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
        $Exception,
        'errorID',
        [System.Management.Automation.ErrorCategory]::NotSpecified,
        $TargetObject) # usually the object that triggered the error, if possible

    $PSCmdlet.WriteError($ErrorRecord)
} -ArgumentList foo! | Receive-Job -AutoRemoveJob -Wait

$Error[0].TargetObject # foo!

huangapple
  • 本文由 发表于 2023年5月11日 03:24:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定