powershellpowershell-cmdletwrite-error

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


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.


Solution

  • 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!