Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Try and Catch Me If You Can

Posted on April 5, 2012

In looking at entries in this year's Scripting Games, as well as posts I see in PowerShell forums, I thought I'd post a short guide to properly using Try/Catch. This is the way I think it should be used. Let's start with a Try/Catch block that might look ok.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!


Try {
Get-Service Foo
}

Catch {
Write-Warning "Oops"
Write-Warning $_.Exception.Message
}

You would expect that if the service FOO can't be found that the code in the Catch script block will run.


PS C:\work> .\trydemo.ps1
Get-Service : Cannot find any service with service name 'Foo'.
At C:\work\trydemo.ps1:4 char:14
+ Get-Service <<<< Foo + CategoryInfo : ObjectNotFound: (Foo:String) [Get-Service], Serv iceCommandException + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell. Commands.GetServiceCommand

Nope. I got an exception, but my code in the Catch script block did not run. You can only catch terminating exceptions. In order for my Try/Catch to work properly, I have to make sure that if there is an exception it gets treated as a terminating exception. The best way is to use the common -ErrorAction parameter and set it to Stop.


Try {
Get-Service Foo -ErrorAction Stop
}

Catch {
Write-Warning "Oops"
Write-Warning $_.Exception.Message
}

The parameter has an alias of -ea which you'll often see used. Now let's see what happens:


PS C:\work> .\trydemo.ps1
WARNING: Oops
WARNING: Cannot find any service with service name 'Foo'.
PS C:\work>

That's what I was expecting. Now for the tricky part. Look at this variation.


Try {
Get-Service -ComputerName Bogus
}

Catch {
Write-Warning "Oops"
Write-Warning $_.Exception.Message
}

What happens when I run this?


PS C:\work> .\trydemo.ps1
WARNING: Oops
WARNING: Cannot open Service Control Manager on computer 'Bogus'. This
operation might require other privileges.

How about that? Even without -erroraction, my catch code still ran. Based on this I can safely deduce that the remote connection failure created a terminating exception. But without a lot of trial and error I think it is impossible to know in advance what type of error will throw a terminating exception and what won't. Personally, I think the best thing is to always use -ErrorAction stop on a cmdlet in a Try scriptblock to guarantee you will always get a terminating exception.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

7 thoughts on “Try and Catch Me If You Can”

  1. JV says:
    April 5, 2012 at 7:33 pm

    Jeff –
    For all of your users when they get “tired typing syndrome”. -ea 0

    Good blog – I will keep a link to post for others.

    1. Jeffery Hicks says:
      April 5, 2012 at 8:45 pm

      One downside is that it isn’t clear in a script what 0 means. But in the console makes sense.

    2. Greg Wojan says:
      April 6, 2012 at 3:52 pm

      Isn’t -ea 0 the shorthand for ‘SilentlyContinue’?

      1. Jeffery Hicks says:
        April 6, 2012 at 4:04 pm

        That seems to be the case. Hardly intuitive which is why I would avoid it in a script.

        PS C:\work> [enum]::GetValues([system.management.automation.actionpreference]) |
        foreach {"$_ = $([int]$_)"}
        SilentlyContinue = 0
        Stop = 1
        Continue = 2
        Inquire = 3

  2. walid toumi says:
    April 6, 2012 at 12:14 pm

    hi,

    you can also use ‘ErrorActionPreference’ and finally block:


    Try {
    $ErrorActionPreference = 'Stop'
    Get-Service Foo
    Get-Process Boo
    }

    Catch {
    Write-Warning "Oops"
    Write-Warning $_.Exception.Message
    }
    finally{
    $ErrorActionPreference = 'SilentlyContinue'
    }

  3. walid toumi says:
    April 6, 2012 at 12:15 pm

    ‘sorry’

    Try {
    $ErrorActionPreference = ‘Stop’
    Get-Service Foo
    Get-Process Boo
    }

    Catch {
    Write-Warning “Oops”
    Write-Warning $_.Exception.Message
    }
    finally{
    $ErrorActionPreference = ‘Continue’
    }

    1. Jeffery Hicks says:
      April 6, 2012 at 12:24 pm

      That is certainly an easier way if you are including a number of commands in a single Try scriptblock.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d