PowerShell – Using Try Catch To Help With Decision Making In A Script

Recently, while working on my scripts for rolling out server deployments in Azure, I came across an interesting issue with a cmdlet throwing a terminating error when I wasn’t expecting one.

I was attempting to use the Get-AzureService cmdlet to verify if the cloud service that I specified already existed or not.  It was necessary to check its existence in case VMs had already been deployed to the service and we were adding machines to the pool.  If it didn’t exist, I would add script logic to create the cloud service before deploying the VMs.  So when I execute:

Get-AzureService -ServiceName 'LWINPRT'

Returns with the following terminating error:

TryCatch1

Now, I expected the service to not be there, because I haven’t created it, but I didn’t expect the cmdlet to terminate in a way that would stop the rest of the script from running.  Typically, when using a command to look for something, it doesn’t throw an error if it can’t find it.  For example, when I look to see if a VM exists in the service:

Get-AzureVM -ServiceName 'LWINPRT' -Name 'LWINPRT01'

I get the following return:

TryCatch2

While the error wasn’t expected, it’s certainly not a show-stopper.  We just have to rethink our approach.  So instead of a ForEach statement looking for a null-value, why don’t we instead look at leveraging Try-Catch?

The Try-Catch-Finally blocks are what allows you to catch .NET exception errors in PowerShell, and provide you with a means to alert the user and take a corrective action if needed.  You can read about them here, or there’s an exceptional article by Ashley McGlone on using it.   So we’ll go ahead and set this up to test.

    Try {
        Get-AzureService -ServiceName 'LWINPRT' -ErrorAction Stop 
        }#EndTry

    Catch [System.Exception]
        {
        Write-Host "An error occurred"
        }#EndCatch

And we execute…

TryCatch3

And we get a return!  But I don’t want an error in this case.  What I want is to create the cloud service if it doesn’t exist.  so let’s do this instead:

    Try {
        Get-AzureService -ServiceName 'LWINPRT' -ErrorAction Stop 
        }#EndTry

    Catch [System.Exception]
        {
        New-AzureService 'LWINPRT' -Location "West US"
        }#EndCatch

And we execute this…

TryCatch4

And now we get the service created.  And we can now see it in our Azure console:

TryCatch5

Now we can use this Try block to check if a cloud service exists or not, knowing that if it can’t find the cloud service it will throw a terminating error.  And when it does, we can use the Catch block to create the existing service.  Decision made.