So, as in my comment, as long as $ErrorActionPreference is set to Stop you script should be capturing the errors properly. In addition, you can use $_ to actually capture the error:
PS C:\> $admin.SetPassword('supers3cur3p4ssw0rd')
Exception calling "setpassword" with "1" argument(s): "Access is denied.
...
...
So, if we try with try {...} catch {...} you can actually get a properly formatted error with the details you want:
Note: You can also inspect the last error using $Error[0].
$ErrorActionPreference = 'Stop' # This should usually be at the top of your script.
$storedError = try
{
$admin.SetPassword('supers3cur3p4ssw0rd')
}
catch
{
[pscustomobject]@{
TimeGenerated = [datetime]::Now
Message = 'Failed to set password on {0}' -f $env:COMPUTERNAME
Exception = $_.Exception.InnerException.Message.Trim()
}
}
This would yield the following on my laptop:
PS C:\> $storedError
TimeGenerated Message Exception
------------- ------- ---------
7/14/2021 7:30:09 PM Failed to set password on XXXXX Access is denied.
This is how the ErrorRecord object looks:
PS C:\> $Error[0] | Select-Object *
PSMessageDetails :
Exception : System.Management.Automation.MethodInvocationException: Exception calling "setpassword" with "1" argument(s): "Access is denied.
" ---> System.UnauthorizedAccessException: Access is denied.
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject :
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : CatchFromBaseAdapterMethodInvokeTI
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}