PowerShell: Try...Catch...Finally Comes To Life

So, PowerShell has some good error handling, but being so used to .NET, I really missed my Try...Catch...Finally statements. Especially when I needed to make sure a block of code always executed. Well, after some playing, I think I have the solution! I've tested this function in a few different ways. I hope this turns out to be as helpful to someone else as it is for me. Maybe Microsoft will add this functionality to the core of PowerShell.

function Try
{
    param
    (
        [ScriptBlock]$Command = $(throw "The parameter -Command is required."),
        [ScriptBlock]$Catch   = { throw $_ },
        [ScriptBlock]$Finally = {}
    )
   
    & {
        $local:ErrorActionPreference = "SilentlyContinue"
       
        trap
        {
            trap
            {
                & {
                    trap { throw $_ }
                    &$Finally
                }
               
                throw $_
            }
           
            $_ | & { &$Catch }
        }
       
        &$Command
    }

    & {
        trap { throw $_ }
        &$Finally
    }
}

# Example usage 

Try {
    echo " ::Do some work..."
    echo " ::Try divide by zero: $(0/0)"
} -Catch {
    echo "  ::Cannot handle the error (will rethrow): $_"
    #throw $_
} -Finally {
    echo " ::Cleanup resources..."
}

4 Comments

  • Great stuff. I can't figure out what the 'local' on ErrorActionPreference actually accomplishes. Is the behavior actually different if you leave it off?

  • No, it isn't needed, I was just being explicit to show that this is only valid for the current scope.

    It is just my personal standard when overriding a possible non-local variable.

  • This looks great! I have been looking for this functionality for a long time.

    Thanks for sharing this.

  • Thanks for the function. I'm really excited to try this out. I've been playing around with this for the past 30 mins and am scratching my head more than I expected.

    Could you by chance add additional example of calling the function (particularly examples of real-world catch blocks)? I think seeing more working examples would be very helpful.

    Thanks again!

Comments have been disabled for this content.