When you use
Try / Catch / Finally , the command to be executed is placed in a
Try block. If an error occurs during the execution of the command, it will be written to the
$ Error variable, and the script will go to the
Catch block.
The
TestTryCatchFinally.ps1 script uses a
Try command in an attempt to create an object. The creation object is in the
$ ob1 variable. The
New-Object cmdlet creates an object. After creating an object and placing it in the
$ a variable, you can view the members of the object using the
Get-Member cmdlet. The following code illustrates this:
Try { "Attempting to create new object $ob1" $a = new-object $ob1 "Members of the $ob1" "New object $ob1 created" $a | Get-Member }
Use the
Catch block to catch the error that occurred in the
Try block. You can specify the type of error to capture, as well as the action that would occur when an error occurred. In the
TestTryCatchFinally.ps1 script
, I watch for errors like
System.Exception . The
System.Exeption .Net Framework class is the base class on which all other exceptions depend. This means that
System.Exeption is a generic generic class; in essence, you can get all the predefined exceptions, both general and system-wide. When catching an error, you can specify which code you would like to execute. In this example, I display a simple line that indicates that the script caught a system exception. The
Catch block is shown below:
Catch { [system.exception] "caught a system exception" }
The
Finally block of the
Try / Catch / Finally sequence is always executed, regardless of whether an error occurred or not. This means that some things to complete that you want to do, for example, to explicitly release a COM object, should be placed in the
Finally block. In the
TestTryCatchFinally.ps1 script, the
finally block illustrates the status bar that the script has completed. This is shown below:
')
Finally { "end of script" }
Entire TestTryCatchFinally.ps1 script:
TestTryCatchFinally.ps1 $ob1 = "kenobie" "Begin test" Try { "Attempting to create new object $ob1" $a = new-object $ob1 "Members of the $ob1" "New object $ob1 created" $a | Get-Member } Catch [system.exception] { "caught a system exception" } Finally { "end of script" }
During the execution of the
TestTryCatchFinally.ps1 script
, when the
$ ob1 variable is assigned the value “kenobie”, an error occurs because there is not a single object named “kenobie” that could be created using the
New-Object cmdlet . The following picture shows the output of the script.

As you can see from the previous picture, the string “Begin Test” is output because it is outside the
Try / Catch / Finally loop. Inside the
Try block, the string “Attempting to create new object kenobie” is output because it is executed before the
New-Object command. This demonstrates that the
Try block is always trying to execute the code inside it. Members of the "kenobie" object are not displayed, just as the string "new object kenobie created" is not displayed. This indicates that after an error occurs, the script proceeds to the next block. In the
Catch block, an error of type
System.Exeption occurs and the string “caught a system exception” is output. Next, the script goes to the
Finally block and displays the string "end of script".
If in the script the variable
$ ob1 is assigned the value “system.object” (which is the correct value), the
Try block will succeed completely. This is seen in the following figure, the members of the object are inferred, and the string indicating that the object is successfully created is also output. The
Catch block does not work, and the string "end of script" from the
Finally block is output.

You can use multiple
Catch blocks in a
Try / Catch / Finally block. It should be borne in mind that when an exception occurs Windows Powershell leaves the
Try block and searches for the
Catch block. The first
Catch block will be used that satisfies the exception condition. Therefore, it is necessary to use the most specific exceptions first, moving on to more general ones.
This is seen in
TestTryMultipleCatchFinally.ps1 .
TestTryMultipleCatchFinally.ps1 $ob1 = "foo" "Begin test" $ErrorActionPreference = "stop" Try { Get-Content foo "Attempting to create new object $ob1" $a = new-object $ob1 "Members of the $ob1" "New object $ob1 created" $a | Get-Member } Catch [System.Management.Automation.PSArgumentException] { "invalid object" } Catch [system.exception] { "caught a system exception" } Finally { "end of script" }
The following figure shows the output of the
TestTryMultipleCatchFinally.ps1 script. Two changes were made: The
$ ErrorActionPreference and
Get-Content foo commands were
commented out . Thus, the generated error will occur when trying to create a non-existent object. To find a specific error, I explored the
$ error variable after running the
TestTryMultipleCatchFinally.ps1 script. The error is indicated in the
Exception field.
PS C:\> $error | fl * -F PSMessageDetails : Exception : System.Management.Automation.PSArgumentException: Cannot find type [foo]: verify that the assembly containing this type is loaded. at System.Management.Automation.MshCommandRuntime.ThrowTerminat ingError(ErrorRecord errorRecord) TargetObject : CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand ErrorDetails : InvocationInfo : System.Management.Automation.InvocationInfo ScriptStackTrace : at <ScriptBlock>, C:\Users\dyak\SkyDrive\Scripts\habrahabr\TestTry MultipleCatchFinally.ps1: line 10 PipelineIterationInfo : {}

If the script has several errors, and the value of the
$ ErroActionPreference variable is set to “stop”, the first error will cause the script to fail. If you remove comments from the
$ ErrorActionPreference and
Get-Content commands, the first error will be caught by the
System.Exception Catch block and therefore the exception argument will be skipped. This is seen in the following image:

In general, tried to translate
an article published in the Ed Wilson block. I hope it will be useful to someone.