PowerShell error handling best practices

Question on PowerShell error handling.  Which method is 'better' and why?

Using Try/Catch to handle any errors for Do-Something

try {
    Do-Something -ErrorAction 'Stop'
}
catch {
    $errormessage = $_.Exception.Message
    Write-Verbose "An error occurred: $errormessage"
}

Open in new window

Using an If statement to handle errors for Do-Something

if (Do-Something) {
    Do-SomethingElse
}
else {
    $errormessage = $_.Exception.Message
    Write-Verbose "An error occurred: $errormessage"
}

Open in new window

LVL 17
Jason CrawfordTransport NinjaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bell TechLogixSystems EngineerCommented:
I will say that Try Catch doesn't always work, in those cases maybe store the result in a $var and then check if the $var is $null -or "" and then stop your script
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
You can't really compare both.try/catch can act on stopping errors only - those errors which would halt execution of the script.
Checking for results works (usually) much better. But most commandlets are supposed to provide pipeline output, only a few return a boolean - e.g. Test-Path.

So you need to use what can be used at that moment in the appropriate context.
0
Jason CrawfordTransport NinjaAuthor Commented:
@Qlemo here's what prompted the question - I had these two sections of my script sitting right next to each other and I honestly couldn't nail down why I used try/catch for Disable-MailContact whereas I used an if statement for Get-MailContact:

try {
    Disable-MailContact $user -Confirm:$false -ErrorAction 'stop'
}
catch {
    $errormessage = $_.Exception.Message
    Write-Verbose "An error occurred: $errormessage"
}

if (!(Get-MailContact $user)) {
    if (Enable-MailUser $aduser.SamAccountName -ExternalEmailAddress $contact.ExternalEmailAddress) {
        Set-MailUser $user -EmailAddresses @{add=$contact.emailaddresses}
        Set-MailUser $user -EmailAddresses @{add=$legdn}
    }
}

Open in new window

Is there a better way to do this?
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

Bell TechLogixSystems EngineerCommented:
what is the result you are getting, and what is the result you are expecting?
0
Jason CrawfordTransport NinjaAuthor Commented:
The specific results don't matter I'm just asking from a best practices point of view for my own education.
0
Bell TechLogixSystems EngineerCommented:
The best answer is try the (Try,Catch) but if it doesn't work in your scenario then move to the next option, and that's checking the results, and if that doesn't work, then pull the source a second time and verify you have changed what you wanted.
0
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
The difference usually is between a real error (important file not existing, privileges missing, ...), and an expected case. In above code, you want to do something if the contact does not exist. It would be strange to use try/catch here.
In general, try/catch is to catch the unexpected. If you need to differ between different cases, an if is always better.
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Jason CrawfordTransport NinjaAuthor Commented:
That's an interesting thought though.  For instance if I wanted to take action when a MailContact isn't found I could catch the specific error generated for object not found:

try {
    Get-MailContact $_
}

catch [ManagementObjectNotFoundException] {
    Enable-MailUser $aduser.samaccountname -ExternalEmailAddress $_
    Set-MailUser $_ -EmailAddresses @{add=$contact.emailaddresses}
}

catch {
    Write-Verbose "An error occurred: $($error[0].exception.message)"
}

Open in new window

Thanks for helping me talk this through.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.