When I learned PowerShell and discovered the try/catch/finally statements I was immediately puzzled by the usefulness of the Finally statement and I never found its real functional purpose clearly documented somewhere.
Useless usage of the Finally statement
Example with no error
Here is a first example with the finally statement.
try{ 'Try' } catch{ 'Catch' } finally{'Finally'} 'After finally'
And here is a second example without the finally statement.
try{ 'Try' } catch{ 'Catch' } 'Finally' 'After finally'
As you can notice, there is no difference if you use the finally statement or not.
Example catching an error
Here is a first example with the finally statement.
try{ 'Try' 1/0 } catch{ 'Catch' } finally{'Finally'} 'After finally'
And here is a second example without the finally statement.
try{ 'Try' 1/0 } catch{ 'Catch' } 'Finally' 'After finally'
Here again, you can notice that there is no difference if you use the finally statement or not.
Real usage of the finally statement
In fact, the finally statement becomes useful when you exit your script or function from inside the try or catch section with an exit or a break statement.
Example when exiting from inside the try
try{ 'Try' break } catch{ 'Catch' } finally{'Finally'} 'After finally'
As you can notice, the finally section has been executed, but not the code after this section.
Example when exiting from inside the catch
try{ 'Try' 1/0 } catch{ 'Catch' break } finally{'Finally'} 'After finally'
Here again, you can notice that the finally section has been executed, but not the code after this section.
Conclusion
I am not sure there are a lot of cases where you want to exit your script or function from inside the try or catch section… However, at least now you know that if you don’t exit your code from inside those two sections, the finally statement has no utility.
But yes, if you really want to exit your code from inside the try or catch section, then you can use the finally section for a common code (to the Try and Catch section) when you need to do some “final” cleanup.
One really good use for Finally is when you’re making a connection or opening a resource of some sort that you want to make sure closes correctly, regardless of outcome. For example, one place I use it is in a script that transfers files to an SFTP server. If the connection completes but the transfer fails for some reason (disk full, read/write permissions, file doesn’t exist on the server, etc), then the rest of the script will fail, so I throw a terminating error in the catch block (catching so I can properly log the error and notify me by email rather than spit it to a host process that no human is looking at). Either way, whether the transfer succeeded or failed, I need to close the connection.
I could put the $session.Dispose() in both the try and catch blocks to accomplish this, but I don’t like duplicating code when it isn’t necessary, so into the finally block it goes. There: now, no matter what happens with the transfer, the session is properly disposed of (as opposed to just letting it die with the host process and possibly tying up a port on the server until a timeout occurs).
LikeLike
Thanks for sharing!
LikeLike