Powershell错误处理,try catch finally
脚本的调试向来是一个艰巨的任务,在powershell出现以前简直是一场灾难。在powershell中微软终于做出了诸多改进,不但有了$Error、-whatif,也有了ISE.而在语法上也增加了try-catch-finally,终于可以便利的进行调试和错误处理了。 在该语法中,finally并不是必需的,但是个人并不建议去掉该部分。建议将功能的预处理放在try部分,但没有错误时,再在finally完成功能。 下面将用一段代码演示如何进行错误处理。主要功能是将一段字符串写道硬盘上一个新建的文件中,完成后移出变量。-NoClobber表示不覆盖现有文件。 Try { $strContent = "try catch finally" Out-File -FilePath d:\test.txt -InputObject $strContent -NoClobber Write-Host "文件创建成功" } Catch [System.UnauthorizedAccessException] { Write-Host "访问失败。错误原因:"$Error[0] } Catch [System.IO.DirectoryNotFoundException] { Write-Host "访问失败。错误原因:"$Error[0] } Catch { Write-Host "访问失败。错误原因:"$Error[0] } Finally { Remove-Variable strContent } 按照目前的脚本运行后,成功运行,没有任何错误。如下图 ![]() 再次运行该脚本,会报下图的错误。这正是-NoClobber发挥了作用。而我们通过System.IO.DirectoryNotFoundException捕获了该异常。在catch部分,我们可以主动去捕获可以想到的错误,这样可以提高脚本的友好性,并可以对此类错误进行主动处理,提高脚本的可用性。 ![]() 而我们将输出文件的保存位置更改为d:\temp\这个并不存在的目录后,可以发现报如下图的提示,而这正是我们设计的结果。 ![]() |
PowerShell Tutorial – Try Catch Finally and error handling in PowerShell
One of the key parts of any good PowerShell script is error handling. Even in the shortest script, being able to handle errors helps to ensure that an unexpected event will not go on to wreck the system you are working on. Take the example below. Every week in our sample company (MyCompany.Com) Human Resources are going to upload a list telling us who should have access to the Expenses database. If a name isn’t in the list from HR we’re going to remove it from the group and that user will no longer be able to log expense claims:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt
$CurrentUsers=Get-ADGroupMember "Expenses Claimants" Foreach($User in $CurrentUsers)
{
If($AuthorizedUsers -notcontains $User)
{
Remove-ADGroupMember -Identity "Expenses Claimants" -User $User
}
}
Now, you can see where this is going to go wrong. One week HR doesn’t get around to uploading the list or, just as we are about to access the list, the file server dies. Suddenly PowerShell throws an error on the Get-Content cmdlet and the $AuthorizedUser variable remains empty. Because our script doesn’t handle errors, it continues to run and, in a very short space of time, it has removed every user from our expenses group. Pretty soon the irate phone calls start flooding in and life gets a little less happy. The way to avoid all this is to catch the errors and then handle the event that caused them (which in this case is halt the script and have a shout at someone in HR).
Terminating and Non-Terminating Errors
One of the key things to know when catching errors is that only certain errors can be caught by default. Errors come in two types – terminating and non-terminating. A terminating error is an error that will halt a function or operation. If you make a syntax error or run out of memory, that is a terminating error. Terminating errors can be caught and handled. Non-terminating errors allow Powershell to continue and usually come from cmdlets or other managed situations. Under normal circumstances they cannot be caught by Try-Catch-Finally. The Get-Content error in the example above is a non-terminating error.
Treating Non-Terminating Errors as Terminating
So how do you catch a Non-Terminating error? Basically, you tell PowerShell to treat it as terminating. To do this you use the ErrorAction parameter. Every PowerShell cmdlet supports ErrorAction. By specifying -ErrorAction Stop on the end of a cmdlet you ensure that any errors it throws are treated as terminating and can be caught. In our example above we are going to change our Get-Content line to:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
Treating All Errors as Terminating
It is also possible to treat all errors as terminating using the ErrorActionPreference variable. You can do this either for the script your are working with or for the whole PowerShell session. To set it in a script, make the first line $ErrorActionPreference = Stop. To set it for the session, type $ErrorActionPreference = Stop at the PowerShell console.
Catching a Terminating Error
Once you have ensured that the error you are trying to catch is going to be treated as terminating, you can build a Try Catch block around the command (or commands) that might cause the error. The first stage is to surround the section of your script that may throw the error with a Try block. In our example the Get-Content line becomes:
Try
{
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
}
Immediately after the Try block you must place a Catch block to deal with the error. The Catch block is only accessed if a terminating error occurs, otherwise it is ignored. In our example we are going to email an admin to say that there has been an error and then halt the script. Our Get-Content line is now:
Try
{
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
}
Catch
{
Send-MailMessage -From ExpensesBot@MyCompany.Com -To WinAdmin@MyCompany.Com -Subject "HR File Read Failed!" -SmtpServer EXCH01.AD.MyCompany.Com
Break
}
Accessing The Error Record
Once you are inside a catch block you can access the error record, which is stored in the current object variable, $_. Error records have various useful properties, but the main one you will want to access is $_.Exception. Exceptions are what we are really dealing with here as we catch and deal with errors – exceptions are the unexpected event that caused the error (the error record itself is actually only really a wrapper for presenting the exception to the PowerShell user). It is the exception that we are catching and the exception that contains all the really useful information about the problem. If there was a further underlying problem that caused our exception, it is also recorded at $_.exception.innerexception (and so on – the next underlying exception is stored at $_.exception.innerexception.innerexception etc.). For the purposes of our example we are going to use $_.Exception to put some extra information into our notification email, using the $_.Exception.Message and $_.Exception.ItemName properties:
Try
{
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Send-MailMessage -From ExpensesBot@MyCompany.Com -To WinAdmin@MyCompany.Com -Subject "HR File Read Failed!" -SmtpServer EXCH01.AD.MyCompany.Com -Body "We failed to read file $FailedItem. The error message was $ErrorMessage"
Break
}
Catching Specific Exceptions
Now, as our example stands we are catching any errors that occur during the file read and dealing with all of them in the same way. You can however catch specific exceptions and deal with them differently, but – and it’s a big but – only if the original error is terminating. Because the Get-Content cmdlet throws non-terminating errors (that we have only treated as terminating using ErrorAction) we cannot specifically catch the different exceptions that the cmdlet might throw. This is a feature of PowerShell and applies to any non-terminating error, regardless of the ErrorActionPreference and cannot be changed. Still, we can deal with other terminating exceptions, such as an out of memory error, that could crop up during the read operation. For the purposes of this example that is what we will do.
You catch specific terminating errors by specifying the exception name immediately after the Catch keyword. In our example we want to catch a System.OutOfMemory exception and, if we get one, will take the no nonsense approach of rebooting the computer immediately. We will also include a general catch block after our file not found block to catch all other exceptions:
Try
{
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
}
Catch [System.OutOfMemoryException]
{
Restart-Computer localhost
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Send-MailMessage -From ExpensesBot@MyCompany.Com -To WinAdmin@MyCompany.Com -Subject "HR File Read Failed!" -SmtpServer EXCH01.AD.MyCompany.Com -Body "We failed to read file $FailedItem. The error message was $ErrorMessage"
Break
}
Finally, Using Finally
The last part of Try Catch Finally is the Finally block. This must be defined immediately after the Catch block and runs every time, regardless of whether there was an error or not. In this way you can perform actions that need to be made regardless of whether an operation succeeds or fails. In our example we are going to log that a file read was attempted. Our Get-Content line now looks like:
Try
{
$AuthorizedUsers = Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
}
Catch [System.OutOfMemoryException]
{
Restart-Computer localhost
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Send-MailMessage -From ExpensesBot@MyCompany.Com -To WinAdmin@MyCompany.Com -Subject "HR File Read Failed!" -SmtpServer EXCH01.AD.MyCompany.Com -Body "We failed to read file $FailedItem. The error message was $ErrorMessage"
Break
}
Finally
{
$Time=Get-Date
"This script made a read attempt at $Time" | out-file c:\logs\ExpensesScript.log -append
}
Powershell错误处理,try catch finally的更多相关文章
- 【转】Javascript错误处理——try…catch
无论我们编程多么精通,脚本错误怎是难免.可能是我们的错误造成,或异常输入,错误的服务器端响应以及无数个其他原因. 通常,当发送错误时脚本会立刻停止,打印至控制台. 但try...catch语法结构可以 ...
- PowerShell随笔7 -- Try Catch
PowerShell默认的顺序执行命令,即使中间某一句命令出错,也会继续向下执行. 但是,我们的业务有时并非如此,我们希望出现异常情况后进行捕获异常,进行记录日志等操作. 和其他编程语言一样,我们可以 ...
- 错误处理try catch
<?phpfunction inverse($x) { if (!$x) { throw new Exception('被除数不能为0'); } if ($x>31) { throw ne ...
- 错误地使用catch
try { // do something } catch (Exception e) { } 错误:这里,catch了Exception,但是在catch中什么动作都没做,那么所有的Exceptio ...
- python错误处理—try…catch…finally、调用栈分析
高级语言包括python一般都内置了一套try…catch…finally的错误处理机制: >>> try: ... print('try...') ... r = 10 / 0 . ...
- php 语法错误定位 try catch Throwable
try { } catch (Exception $ex) { // 计算错误 } catch (Throwable $ex) { // 语法错误,致命错误 } Throwable { ...
- JavaScript 错误 - Throw、Try 和 Catch
http://www.w3school.com.cn/js/js_errors.asp try 语句测试代码块的错误.catch 语句处理错误.throw 语句创建自定义错误. 错误一定会发生 当 J ...
- JavaScript 错误处理 Throw、Try 和 Catch
try 语句测试代码块的错误. catch 语句处理错误. throw 语句创建自定义错误. JavaScript 错误 当 JavaScript 引擎执行 JavaScript 代码时,会发生各种错 ...
- javascript中的错误处理机制
× 目录 [1]对象 [2]类型 [3]事件[4]throw[5]try[6]常见错误 前面的话 错误处理对于web应用程序开发至关重要,不能提前预测到可能发生的错误,不能提前采取恢复策略,可能导致较 ...
随机推荐
- db2 存储过程迁移方法
大家在迁移数据库时,存储过程一般也要迁移过去,但一般有两个问题: 1. 非常多存储过程有先后关系(存储过程调用存储过程),假设存储过程数量少,还能手动操作.假设量大,那真是要疯了. 2. 存储过程过大 ...
- Install Oracle 10g on Red Hat Linux 5.3 Step by Step
一.虚拟机配置 1. 虚拟机(VBox 4.3.12) 2. 配置虚拟机网卡网络.选择host-only.VirtualBox Host-Only Network网卡IP为设置为192.168.1.1 ...
- CComPtr用法
COM接口指针很危险,因为使用过程中需要每一个使用者都要严格并且正确的AddRef和Release,一旦出现问题,就会造成对象不能被正常释放,或者对象被重复删除,造成程序崩溃.所以使用COM接口,必须 ...
- [每日一题] 11gOCP 1z0-052 :2013-09-2 ADDM(Automatic Database Diagnostic Monitor)...................A28
转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/10951207 正确答案:BC AWR简称Automatic Workload Reposi ...
- jquery跳出当前的each循环
break----用return false; continue --用return ture; jquery是对象链,所以$(..).each()返回的还是对象集合.each(function(){ ...
- 【网络流#4】UVA 753 最大流
最近开始刷网络流的题目了,先从紫书上的开始,这道题是P374上的,嘛,总之这道题最终还是参考了一下紫书. 中间是用了STL中map将字符串映射成编号,使用编号总比是用字符串简单的多. 超级源点S与各个 ...
- codevs 2494 Vani和Cl2捉迷藏
/* 一开始大意了 以为和bzoj上的祭祀是一样的(毕竟样例都一样) 这里不知相邻的点可以相互到达 间接相连的也可以到达 所以floyed先建立一下关系 再跑最大独立集 下面贴一下95 和 100的代 ...
- Html.RenderPartial和Html.RenderAction的区别
添加一个PartialController控制器 using System; using System.Collections.Generic; using System.Linq; using Sy ...
- VS快速定位文件、代码插件——DPack
之前用Myeclipse开发一个Java项目,发现其中“Open Resource”(Ctrl+Shirft+R)的功能比较好用,回到.Net后就找了找VS相应的功能,试了几个后觉得Dpack比较好用 ...
- hdu 4772
题意:给你两个矩阵,一个矩阵旋转90度,180度,270度, 然后和另外一个矩阵进行比较,如果对应值相同,则加一,最后得出最大的值 题目没什么难度....主要是纪念下....貌似这一题是当时比赛前一个 ...