gggggds 发表于 2018-9-2 12:36:25

14.PowerShell--抛出异常,错误处理


[*]  PowerShell – 错误处理
  1.What-if 参数 (试运行,模拟操作)
  简介:PowerShell 不会执行任何对系统有影响的操作,只会告诉你如果没有模拟运行,可能产生什么影响和后果。
  实例:
  PS C:\>Stop-Process-name calc -whatif
  What if: Performing theoperation "Stop-Process" on target "calc (119000)".
  2.-confirm参数 (逐步确认,逐个查询)
  简介:PowerShell在使用“*”通配符时,可能会在瞬间产生许多任务。为了防止产生失误操作,可以逐个进行确认,逐个进行放行。
  实例:
  Stop-Process -Name *cm* -Confirm
  确认程序提供了6个选项。
  是 – 仅继续执行操作的下一步骤。
  全是 – 继续执行操作的所有步骤。
  否 – 跳过此操作并继续执行下一操作。
  不全是 – 跳过此操作及所有后续操作。
  挂起 – 暂停当前管道并返回到命令提示符。键入“exit”可继续执行该管道。
  帮助 – 提供帮助信息
  3. 跳过PowerShell中的Confirm 提示
  
  解决方案:
  可以使用自动化变量$ConfirmPreference来设置:
  $ConfirmPreference 是一个枚举类型,分别有None,Low,Medium,High四个级别。在调用前备份$ConfirmPreference,然后将$ConfirmPreference设置为‘None’,在执行完Stop-Process后,再还原设置,即可。默认为“High”,对有风险的脚本,要设置为High.
  #查看$ConfirmPreference支持的设置
  ::GetNames($ConfirmPreference.GetType())
  None
  Low
  Medium
  High
  #查看当前的$ConfirmPreference
  $ConfirmPreference
  High
  #修改当前的$ConfirmPreference
  $ConfirmPreference=“None”
  实例:
  PS C:\> $ConfirmPreference="High"
  PS C:\> calc
  PS C:\> Stop-Process -name calc-confirm
  Confirm
  Are you sure you want to perform this action?
  Performing the operation "Stop-Process" on target"calc (87752)".
   Yes Yes toAll No No to All Suspend[?] Help (default is"Y"):
  4. 定义PowerShell的容错度

[*]  $ErrorView (可以简化输出错误信息)
  $ErrorView="categoryview"
  实例:
  $ErrorView
  NormalView
  $ErrorView="categoryview"
  Remove-Item www.mossfly.com
  ObjectNotFound: (E:www.mossfly.com:String) ,ItemNotFoundException
  b. $ErrorActionPreference(用于错误发生时候的处理方式)
  可以应用于整个脚本(全局设置),或某段函数,某个脚本;
  Member name         Description
  Continue                     将错误抛出来,但是脚本会继续往下执行。(默认)
  Ignore                         直接忽略错误,貌似在Powershell 2.0中已经没有了
  Inquire                                    提供选项由用户选择Error Action。
  SilentlyContinue      错误不抛出,脚本也会继续执行。
  Stop                            错误发生时,终止脚本执行
  5. 在PowerShell中识别和处理异常

[*]  抑制内置的错误信息;
  如:设置$ ErrorActionPreference=“ SilentlyContinue”,让错误信息不输出;
  b. 有一个能够发现异常是否发生的机制;
  实例一: ($?—返回上一个命名执行成功与否,成功为true;)
  Remove-Item "file not exist" -ErrorAction"SilentlyContinue"
  If(!$?)
  {
  "failed to delete the file.";
  break;
  };
  "succeed to delete the file"
  输出结果:(由于没有这个文件或文件夹"file not exist")
  "failed to delete the file.";
  实例二: $Error集合可以记录256条错误记录,$error)包含最后一条错误,上一个错误是$error)",可以将这个集合看作一个队列)
  Remove-Item "file not exist" -ErrorAction"SilentlyContinue"
  If(!$?)
  {
  #"there is an exception, information is $($error)";
  break;
  };
  "succeed to delete the file"
  输出结果:
  there is an exception, information isSystem.Management.Automation.IncompleteParseException: Missing statement blockafter If ( condition ).   atSystem.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)   at Microsoft.PowerShell.Executor.ExecuteCommandHelper(PipelinetempPipeline, Exception& exceptionThrown, ExecutionOp
  tions options)
  6. 使用Traps处理异常
  简介: 使用Traps可以捕获异常,在捕获到异常时,可以在做相应的处理。例如我们在PowerShell自动化工作中,出现了异常可以发一封邮件给管理员。
  实例一:捕捉发生的异常,不做处理,继续执行后面代码。
  trap
  {
  "you already captured the exception"
  }
  1/0
  "123"
  输出结果:
  you already captured the exception
  Attempted to divide by zero.
  At line:5 char:1
  + 1/0
  + ~~~
  + CategoryInfo          : NotSpecified: (:) [],RuntimeException
  +FullyQualifiedErrorId : RuntimeException
  123
  实例二:捕捉发生的异常,使用continue继续执行脚本/后面代码。
  trap
  {
  "you already captured the exception";
  continue;
  }
  stop-service -name "123" -erroraction "stop"
  write-host "continue to execute"
  输出结果:
  you already captured the exception
  continue to execute
  实例三:捕捉发生的异常,使用break中断脚本执行。
  trap
  {
  "you already captured the exception";
  break;
  }
  stop-service -name "123" -erroraction "stop"
  write-host "continue to execute"
  输出结果:
  you already captured the exception
  stop-service : Cannot find any service with service name'123'.
  At line:6 char:1
  + stop-service -name "123" -erroraction"stop"
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound: (123:String), ServiceCommandException   + FullyQualifiedErrorId :NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.StopServiceCommand
  实例四:捕捉发生的异常,查看异常的详细信息。
  (PowerShell会自动将异常保存在$_变量中)
  trap
  {
  write-host $_.exception.message;
  continue;
  }
  stop-service -name "123" -erroraction "stop"
  write-host "continue to execute"
  输出结果:
  Cannot find any service with service name '123'.
  continue to execute
  7.PowerShell 错误记录:详细错误
  实例一:将异常重定向,重定向操作符(2>)到变量$myerror中
  $myerror= remove-item "NoSuchDirectory" 2>&1
  $myerror.exception
  输出结果:
  Cannot find path 'D:\NoSuchDirectory' because it does not exist.
  #清晰查看错误信息
  PS D:\> $myerror.FullyQualifiedErrorId
  PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
  实例二:使用ErrorVariable参数,PowerShell 自动把出现的错误保存在这个变量中,不受ErrorAction配置的影响
  PS D:\> Remove-Item "NoSuchDirectory"-ErrorVariable ErrorStore -ErrorAction "SilentlyContinue"
  PS D:\> $ErrorStore
  Remove-Item : Cannot find path 'D:\NoSuchDirectory' because itdoes not exist. At line:1 char:1
  + Remove-Item "NoSuchDirectory" -ErrorVariableErrorStore -ErrorAction "SilentlyCo ...
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound:(D:\NoSuchDirectory:String) , ItemNotFoundException
  + FullyQualifiedErrorId :PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
  $ErrorStore.GetType().fullName
  # System.Collections.ArrayList
  $ErrorStore.gettype().fullName
  #System.Management.Automation.ErrorRecord
  $ErrorStore.Exception.Message
  #Cannot find path 'D:\NoSuchDirectory' becauseit does not exist.
  实例三:使用ErrorVariable参数,并作为数组来保存一次信息
  PS C:\Windows\system32> Get-Item"NOSuchDir1","NOSuchDir2","NOSuchDir3"-ErrorAction "SilentlyContinue" -ErrorVariable ErrorStore
  PS C:\Windows\system32> $Error.Count
  3
  实例四:还有一个小技巧,可以给-ErrorVariable参数前加一个“+”,代表追加存储错误,可以将一连串的错误合并在一个数组,后面可以统一进行分析处理,如下:
  PS C:\Windows\system32> Get-Item "NOSuchDir1"-ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore
  PS C:\Windows\system32> Remove-Item "NOSuchDir1"-ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore
  PS C:\Windows\system32> Get-Process "NOSuchDir1"-ErrorAction "SilentlyContinue" -ErrorVariable +ErrorStore
  PS C:\Windows\system32> $ErrorStore
  Get-Item : Cannot find path 'C:\Windows\system32\NOSuchDir1'because it does not exist. At line:1 char:1
  + Get-Item "NOSuchDir1" -ErrorAction"SilentlyContinue" -ErrorVariable +ErrorStore
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound:(C:\Windows\system32\NOSuchDir1:String) , ItemNotFoundExceptio
  n    + FullyQualifiedErrorId :PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand
  Remove-Item : Cannot find path 'C:\Windows\system32\NOSuchDir1'because it does not exist. At line:1 char:1
  + Remove-Item "NOSuchDir1" -ErrorAction"SilentlyContinue" -ErrorVariable +ErrorSt ...
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound:(C:\Windows\system32\NOSuchDir1:String) ,ItemNotFoundException    +FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
  Get-Process : Cannot find a process with the name"NOSuchDir1". Verify the process name and call the cmdlet again. Atline:1 char:1
  + Get-Process "NOSuchDir1" -ErrorAction"SilentlyContinue" -ErrorVariable +ErrorSt ...
  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : ObjectNotFound: (NOSuchDir1:String), ProcessCommandException
  +FullyQualifiedErrorId :NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
  PS C:\Windows\system32> $ErrorStore.count
  3
  实例五:通过$Error查看错误信息
  (PowerShell会自动收集异常,存储在自动化常量$Error中,$Error是一个数组,把每次最后发生的一次保存在索引为0的位置,存储异常时候,会占用资源,使用$Error.Clean()来清空异常,这个数组也有最大值的,最大值存储在$MaximumErrorCount自动化变量中,默认为256.)
  $MaximumErrorCount
  # 256
  $MaximumErrorCount=267
  $MaximumErrorCount
  # 267
  8. 理解PowerShell中的异常

[*]

[*]  PowerShell的Exception和.NET的Exception对应
[*]  运行程序中在发生错误的时候,会抛出一个异常来弥补
[*]  开发者应能够捕获和处理潜在的异常;

  实例一:#查看最后的异常
  $Error.Exception.Message
  #找不到路径“Cddd”,因为该路径不存在。
  实例二:#列出当前Error变量中存储的Exception类型
  #当$Error中Exception为null时,不能调用Message,否则会报错。
  $Error | where {$_.Exception -ne $null} | foreach {$_.Exception.GetType().fullName}
  System.Management.Automation.RuntimeException
  System.Management.Automation.RuntimeException
  System.Management.Automation.ItemNotFoundException
  System.Management.Automation.CommandNotFoundException
  实例三:#处理特定的异常(类型.NET中的try一样捕获特定的异常)
  Trap {
  #"除数为空!";
  "divider could not be null";
  Continue;
  }
  Trap {
  #"参数不正确!";
  "parameter was wrong";
  Continue;
  }
  Trap {
  #"网络异常!"
  "network error";
  Continue;
  }
  1/$null
  Dir -MacGuffin
  $wc = new-object System.Net.WebClient
  $wc.DownloadFile("http://www.mossfly.com/powershell.txt","e:ps.txt")
  #除数为空!
  #参数不正确!
  #网络异常!
  实例四:#抛出自定义的异常信息(throw)
  PS C:\Windows\system32> Function Func-Test($a,$b)
  >> {
  >> if($b -eq $null)
  >> {
  >> #throw "参数b 不能为空!"
  >> throw "parameter b could not be null"
  >> }
  >> "{0}+{1}={2}" -f $a,$b,($a+$b)
  >> }
  >> Func-Test -a 10
  >>
  parameter b could not be null
  At line:6 char:1
  + throw "parameter b could not be null"
  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : OperationStopped: (parameter bcould not be null:String) [], RuntimeException
  +FullyQualifiedErrorId : parameter b could not be null
  实例五:#在函数参数中默认值为抛出一个异常,如果没有传入参数的话(throw)
  PS C:\Windows\system32> Function Func-Test($a,$b=$(throw"parameter b could not be null"))
  >> {
  >> "{0}+{1}={2}" -f $a,$b,($a+$b)
  >> }
  >> Func-Test -a 10 -b 9
  >> Func-Test -a 10
  >>
  10+9=19
  parameter b could not be null
  At line:1 char:28
  + Function Func-Test($a,$b=$(throw "parameter b could notbe null"))
  +                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  + CategoryInfo          : OperationStopped: (parameter bcould not be null:String) [], RuntimeException
  +FullyQualifiedErrorId : parameter b could not be null
  9. PowerShell在函数中捕获异常
  实例一:Trap中的continue使用
  如果将Trap放在函数的调用者中,并跟上Continue,这样函数中第一条错误发生,脚本就会终止执行,并且屏蔽Powershell默认的错误输出。
  function Caller
  {
  Trap
  {
  "Trap Error:$($_.Exception.Message)";
  Continue
  }
  Test-Func
  }
  function Test-Func
  {
  1/$null
  Get-Process "nosuchthing"-ea Stop
  Dir xyz: -ea Stop
  }
  Caller
  Trap Error: Attempted todivide by zero.
  #Trap Error: 试图除以零。
  实例二:Trap中的break使用
  如果你想让脚本在第一次遇到异常就停止工作,可以在Trap中添加Break,如下:
  Function Test-Func
  {
  Trap {
  "Trap到了异常:$($_.Exception.Message)";
  Break
  }
  1/$null
  Get-Process "NoSuchProcess"-ErrorAction Stop
  Dir MossFly: -ErrorActionStop
  }
  Test-Func
  Trap到了异常:试图除以零。
  试图除以零。
  所在位置E:MyScript.ps1:8 字符: 3
  + 1/ >> write-host "continue to execute"
  continueto execute
  参考:http://www.pstips.net/powershell-online-tutorials/

页: [1]
查看完整版本: 14.PowerShell--抛出异常,错误处理