When an error is raised in PowerShell, an ErrorRecord object is created (explicitly or implicitly).
An ErrorRecord object contains a number of fields that are useful for diagnosing an error. An ErrorRecord can be explored using Get-Member. For example, an ErrorRecord will be generated when attempting to divide by 0:
100 / 0 $record = $Error[0]
The ErrorRecord that was generated includes a ScriptStackTrace:
PS> $record.ScriptStackTrace
at <ScriptBlock>, <No file>: line 1
As well as a .NET stack trace:
PS> $record.Exception.StackTrace
at System.Management.Automation.IntOps.Divide(Int32 lhs, Int32 rhs)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
In some cases, the TargetObject property of an ErrorRecord might contain the object being worked on.
For example, if the values for a division operation were dynamically set, an ErrorRecord might be created to return those values to assist with debugging:
$numerator = 10 $denominator = 0 try { $numerator / $denominator } catch { $errorRecord = New-Object Management.Automation.ErrorRecord( (New-Object Exception($_.Exception.Message)), 'InvalidDivision', # ErrorId 'InvalidOperation', # ErrorCategory ([PSCustomObject]@{ # TargetObject Numerator = $numerator Denominator = $denominator }) ) Write-Error -ErrorRecord $errorRecord }
The values pushed into the ErrorRecord may be viewed by exploring the TargetObject property:
PS> $Error[0].TargetObject
Numerator Denominator
--------- -----------
10 0
The try-catch statement used previously is covered in detail later in this chapter.