PowerShell 中的错误和异常是结构化对象。您在控制台上看到的错误消息实际上是一条格式化消息,其中包含来自错误/异常对象的多个元素的信息。您可以像这样自己(重新)构建它:
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
如果您只想在 catch 块中显示错误消息,您可以简单地回显当前对象变量(此时包含错误):
try {
...
} catch {
$_
}
如果您需要彩色输出,请使用带有上述格式化字符串的Write-Host:
try {
...
} catch {
...
Write-Host -Foreground Red -Background Black ($formatstring -f $fields)
}
话虽如此,通常您不想在异常处理程序中按原样显示错误消息(否则-ErrorAction Stop 将毫无意义)。结构化错误/异常对象为您提供可用于更好地控制错误的附加信息。例如,您有 $_.Exception.HResult 与实际错误号。 $_.ScriptStackTrace 和 $_.Exception.StackTrace,所以你可以在调试时显示堆栈跟踪。 $_.Exception.InnerException 使您可以访问嵌套异常,这些异常通常包含有关错误的附加信息(顶级 PowerShell 错误可能有些通用)。您可以通过以下方式展开这些嵌套异常:
$e = $_.Exception
$msg = $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n" + $e.Message
}
$msg
在您的情况下,您要提取的信息似乎在 $_.ErrorDetails.Message 中。我不太清楚那里是否有对象或 JSON 字符串,但您应该能够通过运行获取有关 $_.ErrorDetails 成员的类型和值的信息
$_.ErrorDetails | Get-Member
$_.ErrorDetails | Format-List *
如果$_.ErrorDetails.Message 是一个对象,您应该能够像这样获得消息字符串:
$_.ErrorDetails.Message.message
否则需要先将JSON字符串转为对象:
$_.ErrorDetails.Message | ConvertFrom-Json | Select-Object -Expand message
根据您要处理的错误类型,特定类型的异常还可能包含有关当前问题的更具体信息。例如,在您的情况下,您有一个 WebException,除了错误消息 ($_.Exception.Message) 之外,它还包含来自服务器的实际响应:
PS C:\> $e.Exception |获取会员
类型名称:System.Net.WebException
名称 MemberType 定义
---- ---------- ----------
Equals 方法 bool Equals(System.Object obj), bool _Exception.E...
GetBaseException 方法 System.Exception GetBaseException(), System.Excep...
GetHashCode 方法 int GetHashCode(), int _Exception.GetHashCode()
GetObjectData 方法 void GetObjectData(System.Runtime.Serialization.S...
GetType 方法类型 GetType(),类型 _Exception.GetType()
ToString 方法 string ToString(), string _Exception.ToString()
数据属性 System.Collections.IDictionary 数据 {get;}
HelpLink 属性字符串 HelpLink {get;set;}
HResult 属性 int HResult {get;}
InnerException 属性 System.Exception InnerException {get;}
消息属性字符串消息 {get;}
响应属性 System.Net.WebResponse 响应 {get;}
Source 属性字符串 Source {get;set;}
StackTrace 属性字符串 StackTrace {get;}
状态属性 System.Net.WebExceptionStatus 状态 {get;}
TargetSite 属性 System.Reflection.MethodBase TargetSite {get;}
它为您提供如下信息:
PS C:\> $e.Exception.Response
IsMutuallyAuthenticated : 假
饼干 : {}
标头:{Keep-Alive、Connection、Content-Length、Content-T...}
SupportsHeaders:真
内容长度:198
内容编码:
内容类型:文本/html;字符集=iso-8859-1
字符集:iso-8859-1
服务器:Apache/2.4.10
最后修改时间:17.07.2016 14:39:29
状态码:未找到
状态描述:未找到
协议版本:1.1
ResponseUri:http://www.example.com/
方法:POST
IsFromCache : 假
由于并非所有异常都具有完全相同的一组属性,因此您可能希望对特定异常使用特定的处理程序:
try {
...
} catch [System.ArgumentException] {
# handle argument exceptions
} catch [System.Net.WebException] {
# handle web exceptions
} catch {
# handle all other exceptions
}
如果您有需要完成的操作,无论是否发生错误(清理任务,如关闭套接字或数据库连接),您可以在异常处理后将它们放在finally 块中:
try {
...
} catch {
...
} finally {
# cleanup operations go here
}