Three tips for effectively using Try/Catch in PowerShell

Preamble

As my responsibilites have grown and I’ve found myself crafting tools not just for my own use, but that will outlive me at clients and within the firm, I’ve recently become a complete convert to using error-handling in my functions.

If you’ve ever been in a situation in which you’re using someone else’s tools and they don’t account for common errors, I’m sure you understand the need for including common error-checking an validation in your own toolmaking. If you’ve never run into it yourself, maybe my tale can help you.

Continue reading

Using Try/Catch efficiently over a large list of commands

If you want to try catch over multiple commands, try this. We’re using the Invoke character to run a number of commands through a single try/catch block because frankly we can’t be bothered to type that much!

#Invoke-Expression errors are considered non terminating, which means Try/Catch won't natively work.  You need to set
# errorActionPreference = 'Stop' in order to force this behavior, to allow try/catch to do its job
$ErrorActionPreference = 'Stop'
$com =@"
Get-ChildItem c:\drivers,
Get-ChildItem hklo:,
Get-ChildItem c:\temp
"@

$com.Split(',') | ForEach-Object {

try {
    Invoke-Expression $_ -ErrorAction Stop
    }

catch {
    "Something went wrong"
    }

}

 

First off, we set $ErrorActionPreference = ‘Stop’, as Invoke-Expression errors are considered non-terminating for the interests of robust script execution. This means that if an error is encountered, it will be written out to screen and the show will attempt to go on, the script will continue running, etc. A terminating error, by comparison, will stop the show and display its output to the screen. In order to coerce PowerShell into exploring our Catch scripting block, we need to set the $ErrorActionPreference to Stop, so PowerShell will treat this seriously. If you want to see this principle in action, try running the above from the console with $ErrorActionPreference = “Continue”. You’ll notice that the error is displayed on screen and the Catch is never initiated! For this reason, we’re setting the value to ‘Stop’. Don’t worry though, if you run this in a script, the default ErrorActionPreference setting of Continue will be reinstated after the script runs. Speaking of which, be careful in the ISE, as variables set there tend to stick through your whole session.

So, $com contains all of our commands we want to run. We’re splitting the array at the comma to get a number of commands, then ForEach invoking the contents of the variable (ForEach stores the current object in a group of objects within the $_ special variable). IF there is an error, we’re catching it. This is not ideal, as sometimes we want to only catch certain types of errors. You could create special catch commands for each type of error, as shown.

 

$com.Split(',') | ForEach-Object {

try {
    Invoke-Expression $_ -ErrorAction Stop
    }

catch [System.Management.Automation.DriveNotFoundException]{
    "Double check that drive letter..."
    }

catch {
    "Something else went wrong"
    }
}

In this case, we specifically catch for errors of the type ‘System.Management.Automation.DriveNotFoundException’, and then redirect all other output to a generic catch block.

If you’d like more information about catching specific errors, check Ed’s post here : http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/11/hey-scripting-guy-march-11-2010.aspx

Download a full YouTube playlist with PowerShell

Recently, a colleague approached me requesting pointers on the quickest possible way to download a YouTube playlist.  I’d used KeepVid.com previously, to download videos one at a time, but never found a good tool to use to download a full playlist.  So I decided to make one!

This tool depends on you already having the wonderfully useful youtube-dl.exe downloaded on your system.  I placed it in my %PATH% directory, but you can also run this code directly from wherever you placed the binary.  Get the tool here if you don’t already have it:  http://rg3.github.io/youtube-dl/

Continue reading

Listen to my team on the PowerScripting podcast

Hi guys,

A few weeks ago, our team–The Kitten Mittons–had the honor of being on the PowerShell.org PowerScripting podcast to talk about PowerShell and our experiences competing in and winning the 2014 Winter Scripting games.  My team mates, including Jason Morgan and Julie Andreacola, are incredibly sharp, and teaming up with them was such a great experience.

You can listen to us here: http://powershell.org/wp/2014/06/15/episode-273-powerscripting-podcast-the-scripting-games-team-winners/

Tune in later this week, I’m about to release a guide on how you should, and how you shouldn’t attempt to add -WhatIf support to your scripts.