I use Try/Catch a lot in my scripts, but I usually catch all errors in a single error message… In this short blog post, I will show you how to be more specific when displaying errors.
What does Try/Catch do?
“Use try, catch, and finally blocks to respond to or handle terminating errors in scripts. The trap statement can also be used to handle terminating errors in scripts. For more information, see about_Trap.
A terminating error stops a statement from running. If PowerShell does not handle a terminating error in some way, PowerShell also stops running the function or script using the current pipeline. In other languages, such as C#, terminating errors are referred to as exceptions.
Use the try block to define a section of a script in which you want PowerShell to monitor for errors. When an error occurs within the try block, the error is first saved to the $Error automatic variable. PowerShell then searches for a catch block to handle the error. If the try statement does not have a matching catch block, PowerShell continues to search for an appropriate catch block or trap statement in the parent scopes. After a catch block is completed or if no appropriate catch block or trap statement is found, the finally block is run. If the error cannot be handled, the error is written to the error stream.
A catch block can include commands for tracking the error or for recovering the expected flow of the script. A catch block can specify which error types it catches. A try statement can include multiple catch blocks for different kinds of errors.
A finally block can be used to free any resources that are no longer needed by your script.
try, catch, and finally resemble the try, catch, and finally keywords used in the C# programming language.”
Source: about_Try_Catch_Finally – PowerShell | Microsoft Learn
The difference between PS5 and PS7 error output
You can Try to execute a specific action and Catch any error that comes out of it in a more user-friendly Error output than just seeing a bunch of red lines and not being sure what went wrong 😉 For example, if you try to get the filenames of a folder that you have no permissions in, you would generally get something like this in PowerShell v5:
PS C:\> Get-ChildItem C:\windows\System32\DriverState\
Get-ChildItem : Access to the path 'C:\windows\System32\DriverState' is denied.
At line:1 char:1
+ Get-ChildItem C:\windows\System32\DriverState\
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\windows\System32\DriverState\:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
But you get this in PowerShell v7:
PS C:\> Get-ChildItem C:\windows\System32\DriverState\ Get-ChildItem: Access to the path 'C:\Windows\System32\DriverState' is denied.
PowerShell v7 has a more user-friendly error output, but for proper Try/Catch, we need the Exception’s FullName. You can change the output style of PowerShell v7, however, by changing the $ErrorView Variable from ConsiseView (Default) to NormalView. (You have to do that for every new session that you start)
PS C:\> $ErrorView='NormalView' PS C:\> Get-ChildItem C:\windows\System32\DriverState\ Get-ChildItem : Access to the path 'C:\Windows\System32\DriverState' is denied. At line:1 char:1 + Get-ChildItem C:\windows\System32\DriverState\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (C:\Windows\System32\DriverState\:String) [Get-ChildItem], UnauthorizedAccessException + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
To get the Fullname of the Error, you can run $Error[0].Exception.GetType().FullName to see it. For example:
PS C:\> Get-ChildItem C:\windows\System32\DriverState\ Get-ChildItem : Access to the path 'C:\Windows\System32\DriverState' is denied. At line:1 char:1 + Get-ChildItem C:\windows\System32\DriverState\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (C:\Windows\System32\DriverState\:String) [Get-ChildItem], UnauthorizedAccessException + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand PS C:\> $Error[0].Exception.GetType().FullName System.UnauthorizedAccessException
So, in this example, System.UnauthorizedAccessException is the error you can check for in a Try/Catch block for that specific error. For a file-not-found error, it’s a different one: System.Management.Automation.ItemNotFoundException
PS C:\> Get-ChildItem C:\windows\System32\DriverStatePSIF\ Get-ChildItem : Cannot find path 'C:\windows\System32\DriverStatePSIF\' because it does not exist. At line:1 char:1 + Get-ChildItem C:\windows\System32\DriverStatePSIF\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\windows\System32\DriverStatePSIF\:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand PS C:\> $Error[0].Exception.GetType().FullName System.Management.Automation.ItemNotFoundException
Using Catch with specific Error Types
Now that we know that we need the Exception’s FullName (And how to display it in PowerShell v7 using $ErrorView=’NormalView’), we can use it to return specific error messages, for example, when trying to view the contents of a particular folder and being denied access, or when a folder doesn’t exist.
For example, I try to view an existing folder (To which I don’t have access) and one that doesn’t exist. Without Try/Catch, it would look like this:
PS C:\> Get-ChildItem C:\windows\System32\DriverState\ Get-ChildItem : Access to the path 'C:\Windows\System32\DriverState' is denied. At line:1 char:1 + Get-ChildItem C:\windows\System32\DriverState\ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : PermissionDenied: (C:\Windows\System32\DriverState\:String) [Get-ChildItem], UnauthorizedAccessException + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand PS C:\> Get-ChildItem C:\windows\System32\PSIF Get-ChildItem : Cannot find path 'C:\windows\System32\PSIF' because it does not exist. At line:1 char:1 + Get-ChildItem C:\windows\System32\PSIF + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\windows\System32\PSIF:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
But, you can use the Exception’s FullName (Which you can retrieve from the last error by running $Error[0].Exception.GetType().FullName) to give you more user-friendly, or just custom, error messages. In a Try/Catch script, that would look like this:

And if you ran that, it would look like this:
PS C:\> C:\scripts\TryCatch.ps1 Your account doesn't have access to C:\Windows\System32\DriverState, check permissions! The specified path C:\Windows\System32\PSIF doesn't exist, check file/folder name PS C:\>
But… If both Catch statements don’t match, the script will still throw a standard error. You can prevent that by adding a Catch below both specific ones, like this:

But perhaps with a more meaningful output than “Something went wrong :)” 😉
Wrapping up
And that’s how you can use Try/Catch to not only show a more user-friendly message, but also (depending on the type of error) show a particular user-friendly message 🙂 And I used showing messages as an example; you can take actions on error messages, too. Have a lovely weekend!
Hi Harm
Try/Catch error type is something I often have been struggling with. The new PS7 user-friendly error output looks good. It gives a change to make errors in script more simple to overview, without removing important informations. I will have to look into that myself.
Yes, PowerShell 7 is much less frightening 😅 But handling error and starting an action on specific ones, instead of just catching any error as one, makes it more flexible to handle. Gotta catch em all 👌