你可以通过Powershell中的自动化变量$Error和Trap 语句块中的$_的内置变量来输出异常的详细信息。在这篇文章来深入了解Error中的记录。在Powershell控制台中一旦错误发生,异常信息会被以红色显示。红色的的设置保存在:
$host.PrivateData.ErrorForegroundColor # Red $host.PrivateData.ErrorBackgroundColor # Black
Powershell控制台输出的错误信息为文本,只包含了部分的错误信息。如果想访问Error的对象信息,可以通过以下的途径:
Redirection:将错误流重定向到一个变量;
ErrorVariable parameter : 将异常保存到一个变量中;
$Error:也会以数组的形式保存出现的所有异常。
重定向错误记录
如果你想把一个命令的执行结果重定向,可以使用重定向操作符”>”
dir "NoSuchDirectory" > Error.txt Get-Content Error.txt
不幸的是,Error 信息并没有保存到Error.txt 因为Error信息不在标准输出流上,而在Error流上,需要使用”2>”操作符。
Get-Item "NoSuchDirectory" 2> Error.txt Get-Content .error.txt Get-Item : 找不到路径“E:NoSuchDirectory”,因为该路径不存在。 所在位置 行:1 字符: 9 + Get-Item <<<< "NoSuchDirectory" 2> Error.txt + CategoryInfo : ObjectNotFound: (E:NoSuchDirectory:String) [Get-Item], ItemNotFound Exception + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand #将异常重定向到$myerror $myerror = RemoveItem "NoSuchDirectory" 2>&1 $myError.Exception 找不到路径“E:nosuchthing”,因为该路径不存在。 $myError.InvocationInfo MyCommand : Remove-Item BoundParameters : {[Path, System.String[]]} UnboundArguments : {} ScriptLineNumber : 1 OffsetInLine : 15 HistoryId : 55 ScriptName : Line : $myerror = Del "nosuchthing" 2>&1 PositionMessage : 所在位置 行:1 字符: 15 + $myerror = Del <<<< "nosuchthing" 2>&1 InvocationName : Del PipelineLength : 1 PipelinePosition : 1 ExpectingInput : False CommandOrigin : Runspace #显示清晰的错误标识 $myerror.FullyQualifiedErrorId PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand $myError | select CategoryInfo, ErrorDetails,Exception,FullyQualifiedErrorId,InvocationInfo, PipelineIterationInfo,ScriptStackTrace CategoryInfo : ObjectNotFound: (E:nosuchthing:String) [Remove-Item], ItemNotFoundExceptio n ErrorDetails : Exception : System.Management.Automation.ItemNotFoundException: 找不到路径“E:nosuchth ing”,因为该路径不存在。 在 System.Management.Automation.LocationGlobber.ExpandMshGlobPath(String path, Boolean allowNonexistingPaths, PSDriveInfo drive, ContainerCmdletPro vider provider, CmdletProviderContext context) 在 System.Management.Automation.LocationGlobber.ResolveDriveQualifiedPat h(String path, CmdletProviderContext context, Boolean allowNonexistingPaths , CmdletProvider& providerInstance) 在 System.Management.Automation.LocationGlobber.GetGlobbedMonadPathsFrom MonadPath(String path, Boolean allowNonexistingPaths, CmdletProviderContext context, CmdletProvider& providerInstance) 在 System.Management.Automation.PathIntrinsics.GetResolvedPSPathFromPSPa th(String path, CmdletProviderContext context) 在 Microsoft.PowerShell.Commands.RemoveItemCommand.ProcessRecord() FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand InvocationInfo : System.Management.Automation.InvocationInfo PipelineIterationInfo : {0, 1} ScriptStackTrace :
重定向有时也没必要,因为绝大多数Cmdltes都支持-ErrorVariable 参数。只要你将变量名称传递给-ErrorVariable,Powershell就会自动把出现的错误保存到这个变量中,并且这种保存机制不受ErrorAction配置的影响。
Remove-Item "NoSuchDirectory" -ErrorVariable ErrorStore -ErrorAction "SilentlyContinue" $ErrorStore Remove-Item : 找不到路径“E:NoSuchDirectory”,因为该路径不存在。 所在位置 行:1 字符: 12 + Remove-Item <<<< "NoSuchDirectory" -ErrorVariable ErrorStore -ErrorAction "SilentlyContinue" + CategoryInfo : ObjectNotFound: (E:NoSuchDirectory:String) [Remove-Item], ItemNotFo undException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand $ErrorStore.GetType().fullName # System.Collections.ArrayList $ErrorStore[0].gettype().fullName #System.Management.Automation.ErrorRecord $ErrorStore[0].Exception.Message #找不到路径“E:NoSuchDirectory”,因为该路径不存在。
从上面的例子发现ErrorVariable存储类型为数组,数组元素的类型为:ErrorRecord。另一个问题是,为什么ErrorVariable存储类型为数组?因为有可能碰到下面的情况:
Get-Item "NOSuchDir1","NOSuchDir2","NOSuchDir3" -ErrorAction "SilentlyContinue" -ErrorVariable ErrorStore $Error.Count # 3 还有一个小技巧,可以给-ErrorVariable参数前加一个“+”,代表追加存储错误,可以将一连串的错误合并在一个数组,后面可以统一进行分析处理,如下: Get-Item "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore Remove-Item "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore Get-Process "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore $ErrorStore Get-Item : 找不到路径“E:NOSuchDir1”,因为该路径不存在。 所在位置 行:1 字符: 9 + Get-Item <<<< "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore + CategoryInfo : ObjectNotFound: (E:NOSuchDir1:String) [Get-Item], ItemNotFoundExcep tion + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand Remove-Item : 找不到路径“E:NOSuchDir1”,因为该路径不存在。 所在位置 行:1 字符: 12 + Remove-Item <<<< "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore + CategoryInfo : ObjectNotFound: (E:NOSuchDir1:String) [Remove-Item], ItemNotFoundEx ception + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand Get-Process : 找不到名为“NOSuchDir1”的进程。请验证该进程名称,然后再次调用 cmdlet。 所在位置 行:1 字符: 12 + Get-Process <<<< "NOSuchDir1" -ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore + CategoryInfo : ObjectNotFound: (NOSuchDir1:String) [Get-Process], ProcessCommandExc eption + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessC ommand
通过$Error查看错误信息
即使你忘记使用ErrorVariable参数去收集异常,Powershell也会自动收集异常,存储在自动化变量$Error中。$Error同样也是数组,每次会把最后发生的异常保存在索引为0的位置,所以查看最后的一个异常可以使用$Error[0]。有没有一种可能,这个数组拼命地存储异常,也会占用内存资源啊。所以可以使用$Error.Clear(),清空异常。即使你不清理异常,这个数组也有最大值的,最大值存储在$MaximumErrorCount自动化变量中,默认为256.
$MaximumErrorCount # 256 $MaximumErrorCount=267 $MaximumErrorCount # 267
通过Traps查看错误信息
最后Trap语句中也提供了一种存储错误的方式,自动化变量$_ ,你可以对$_进行深加工,定制你自己的异常信息。
Trap { "完蛋了, 貌似出错了: $($_.Exception.Message)"; Continue; } Remove-Item "Books" -ea Stop # 完蛋了, 貌似出错了: 找不到路径“C:UsersMosser LeeBooks”,因为该路径不存在。
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!
$($_.Exception.Message), 问下,前面的$有什么用啊?
你试试,如果不加前面的$,字符串插值就不能正常输出异常信息咯