For the last couple of weeks I have been required to import a data log file (CSV) from a legacy SCADA system into my centralized
data management system. It occured to me today that I might be able to use PowerShell to automate some of the importing steps
which include import to a DEV, QA and Production system. I’m still working on this script, but in the process of developing it, I
had a need to learn more about an exception that was occuring in the script. I had my try catch block already specified, but was simply
using Write-Error
, as in the following code sample, to report a generic message “Failed to…” whenever the catch block was executed.
1
2
3
4
5
6
7
8
try
{
$session = Logon...
}
catch
{
Write-Error "Failed to logon to DMS."
}
I searched the local PowerShell help and didn’t see any info on how to get more detail about a given exception. I searched a little online
including about_Try_Catch_Finally and didn’t find any gems. Then I thought
“Maybe there is a global object, like $host
, that as some error info”. I tried $Err and $Error with no success… then I tried $_
and surprise! It resulted in an object with exception details! See the code sample below, where the $_
object is used in the catch
block and converted to a string for output to the Write-Error
stream.
1
2
3
4
5
6
7
8
9
try
{
$session = Logon...
}
catch
{
# Using $_ in the catch block to include more details about the error that occured.
Write-Error ("Failed to logon to DMS." + $_)
}
When I run through Get-Member
, the $_
object in the catch block returns the following result:
TypeName: System.Management.Automation.ErrorRecord | ||
---|---|---|
Name | MemberType | Definition |
Equals | Method | bool Equals(System.Object obj) |
GetHashCode | Method | int GetHashCode() |
GetObjectData | Method | System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) |
GetType | Method | type GetType() |
ToString | Method | string ToString() |
CategoryInfo | Property | System.Management.Automation.ErrorCategoryInfo CategoryInfo {get;} |
ErrorDetails | Property | System.Management.Automation.ErrorDetails ErrorDetails {get;set;} |
Exception | Property | System.Exception Exception {get;} |
FullyQualifiedErrorId | Property | System.String FullyQualifiedErrorId {get;} |
InvocationInfo | Property | System.Management.Automation.InvocationInfo InvocationInfo {get;} |
PipelineIterationInfo | Property | System.Collections.ObjectModel.ReadOnlyCollection'1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] PipelineIterationInfo {get;} |
TargetObject | Property | System.Object TargetObject {get;} |
PSMessageDetails | ScriptProperty | System.Object PSMessageDetails {get=& { Set-StrictMode -Version 1; $this.Exception.InnerException.PSMessageDetails };} |
Of course, after having figured this out, I thought “Hmm… I bet others might have the same question about getting more exception detail inside a catch block”, and so was born this blog entry. Hope it helps!
Thanks for reading!