Consider the following scenario. You run a command in PowerShell. It fails. It generates tons of scary red text. You don’t like this. You want to display a more friendly error message. Or better still, you want to take some action based on the error.
With PowerShell, you can do this easily with something called try / catch statements. There is lots of documentation online for how to use these. However, one thing I found difficult to figure out was how to define specific exceptions. Consider this code block:
Try {
# Do something
}
Catch [SpecificExceptionGoesHere]
{ # Do something else if the above fails }
The problem I’ve had is figuring out what exactly you type in the yellow box. I’m pleased to report I now have an easy way of figuring it out.
To do so, you first need to intentionally cause the error you want to capture. Once you’ve done that you can extract the exception text.
Oh, I should probably mention that PowerShell automatically saves all Errors in a custom variable called $Error and that the most recent error is always available from $Error[0]
Let’s dive straight into an example. Below we’ve run a simple cmdlet (in this case Get-ChildItem) against a file we know doesn’t exist. It generates an error.
In this case, the error is that the file does not exist. This command could generate other error messages as well such as “Access Denied” but we are only interested in the “not existing” scenario. To figure out how to capture that type:
$Error[0].Exception.GetType().FullName
It’ll return the name you need to put in the yellow text above. Now that you have that, look what we can do:
try { Get-ChildItem c:\thisfiledoesnotexist -ErrorAction Stop }
catch [System.Management.Automation.ItemNotFoundException]
{ Write-host “This block is executed instead of the error written to the screen” }
(Note: Most of the time the –ErrorAction Stop will be required for try/catch to work. If you want to know more, look up “terminating versus non-terminating errors” in Google/Bing/Etc)
I’m going to be using this a lot, that’s for sure. The possibilities are endless!
7 comments
Skip to comment form
Awesome, thanks!
Hi, really useful post but can you include how to handle the exceptions using the status codes too? that would be much appreciated, Thanks.
Thanks this was really useful! I managed to combine this error checking method into my own script to update job titles and departments in AD https://cloudwyse.blogspot.com/2019/02/update-job-title-and-department-in.html
Thanks! This was very helpful.
Note this method of catching exceptions only works if the exception you are catching is a known type in the powershell runtime. When writing cross-platform scripts say for PowerShell 5.1 (Windows) and PowerShell Core 6 or 7 Linux you can’t do this:
Invoke-WebRequest $Url -EA 0 -UseBasicParsing
} catch [System.Net.Http.WebException] {
# The Windows Exception
} catch [System.Net.Http.HttpRequestException] {
# The Linux (Core) Exception
Both runtimes will fail because Core doesn’t know WebException and vice versa. Instead you must do something like:
} catch {
if ($_.Exception.GetType().FullName -ne “System.Net.Http.HttpRequestException”) {
# The Windows Exception
}
elseif ($_.Exception.GetType().Name -ne “System.Net.WebException”) {
# The Linux (Core) Exception
} else {…
What type of work you in, Bob?
Great, thank you!
This small oneliner helps me a lot.