Can you use "try..catch" more than once ?

This topic contains 15 replies, has 6 voices, and was last updated by Profile photo of Graham Beer Graham Beer 1 year, 10 months ago.

  • Author
    Posts
  • #25216
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Hi,

    I've written this script that looks at a text file for certain fields then adds an App-v application into SCCM.

    I'm pretty pleased but believe i can only use "try...catch" once, so how can i put in some error catching ?

    #Set Application details to add to SCCM from text template

    $DefaultAppPath = "\\theaa.local\dfsdata\sccm\software\"

    $Content = get-content "\\aa-cm002v\e$\scripts\AppV_Template.txt"
    $App_DT_Name = $Content[3]
    $App_Name = $Content[5]
    $App_Source_Location = $Content[7]
    $OptRef =
    $Publisher = $Content[9]
    $SoftVer = $Content[11]
    $Folder = $Content[13]

    #Full location path

    $LocationFull = "$DefaultAppPath"+"$App_Source_Location"

    #Set Module and CMsite directory

    $ModulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin"
    $SetDrive = "set-location AAC:"

    #Import module

    Import-Module $ModulePath\ConfigurationManager.psd1

    #Set directory

    Invoke-expression $SetDrive

    #Create new application. "#" if the below command is required.

    Try {
    New-CMApplication -Name $App_Name -AutoInstall $true -Publisher $Publisher -SoftwareVersion $SoftVer
    Write-Output "Application Created Successfully"
    exit 0 }
    Catch {
    Write-Output "Failed to create Application"
    Exit 1001 }

    #Create New Application deployment file

    Try {
    Add-CMDeploymentType -ApplicationName $App_Name -DeploymentTypeName $App_DT_Name -AppV5xInstaller -ForceForUnknownPublisher $true -InstallationFileLocation $LocationFull
    Write-Output "Application Deployment file Created"
    exit 0 }
    Catch {
    Write-Output "Failed to create Application Deployment file"
    Exit 1001 }

    #Move Application to folder

    Try {
    $GetApp = Get-CMApplication -name $App_Name
    Move-CMObject -FolderPath ".\Application\Publisher\$Folder" -InputObject $GetApp
    Write-Output "Application moved to $folder folder"
    exit 0 }
    Catch {
    Write-Output "Failed to move Application to Folder"
    Exit 1001 }

  • #25220
    Profile photo of David Zemdegs
    David Zemdegs
    Participant

    I have a similar application that uses a ton of try catches.
    Its a really messy error handling system and the best you can do is call a function for each catch to display generic info.
    With mine I always pass at least two parameters to this function – $_ and a user friendly text message.
    Sometimes I add an object to be deleted as some of my application create an object then do lots of things to it.
    If one of those "things" fails then passing the object allows me to delete it so you dont leave half built garbage behind.

    Cheers
    David Z

  • #25223
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You can use try/catch as many times as you need. You can even have another try/catch nested inside another try, catch or finally block, if needed.

  • #25224
    Profile photo of Will Anderson
    Will Anderson
    Keymaster

    You can also use execute commands in the catch block. It's not just for displaying generic info. I've actually used try/catch for decision making in cases where cmdlets would throw a terminating error if there was no data to display.

  • #25228
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Awesome, it works like a dream. One month into my learning and i'm really proud i've done this by myself !!

    ##Import App-V application

    #Set Application details to add to SCCM from text template
    $DefaultAppPath = "\\theaa.local\dfsdata\sccm\software\"

    $Content = get-content "\\aa-cm002v\e$\scripts\AppV_Template.txt"
    $App_DT_Name = $Content[3]
    $App_Name = $Content[5]
    $App_Source_Location = $Content[7]
    $OptRef =
    $Publisher = $Content[9]
    $SoftVer = $Content[11]
    $Folder = $Content[13]
    $DPGroup = "All Distribution Points"

    #Full location path
    $LocationFull = "$DefaultAppPath"+"$App_Source_Location"

    #Set Module, CMsite directory and revert back to orginal prompt
    $ModulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin"
    $SetDriveStart = "set-location AAC:"
    $SetDriveEnd = "set-location E:"

    #Import module
    Import-Module $ModulePath\ConfigurationManager.psd1

    try {
    #Set directory
    Invoke-expression $SetDriveStart

    #Create new application. "#" if the below command is required.
    Try {
    New-CMApplication -Name $App_Name -AutoInstall $true -Publisher $Publisher -SoftwareVersion $SoftVer | out-null
    Write-Output "Created $App_Name succesfully" }
    Catch {
    Write-Output "Creating $App_Name failed" }

    #Create New Application deployment file
    Try {
    Add-CMDeploymentType -ApplicationName $App_Name -DeploymentTypeName $App_DT_Name -AppV5xInstaller -ForceForUnknownPublisher $true -InstallationFileLocation $LocationFull | out-null
    Write-Output "Created $App_DT_Name succesfully" }
    Catch {
    Write-Output "Creating $App_DT_Name failed" }

    #Move Application to folder
    Try {
    $GetApp = Get-CMApplication -name $App_Name
    Move-CMObject -FolderPath ".\Application\Publisher\$Folder" -InputObject $GetApp
    Write-Output "Moved $App_Name to $Folder succesfully" }
    Catch {
    Write-Output "Moving $App_Name to $Folder failed" }

    #Distribute application
    Try {
    Start-CMContentDistribution -ApplicationName $App_Name -DistributionPointGroupName $DPGroup
    Write-Output "Distributed content to $DPGroup" }
    Catch {
    Write-Output "Failed to Distribute content to $DPGroup" }

    #Set location back to E drive
    Invoke-expression $SetDriveEnd

    Write-Output "Virtual App created in SCCM and currently distributing"
    exit 0 }
    Catch {
    Write-Output "Failed to Create Virtual App"
    Exit 1001 }

  • #25232
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    As you learn Powershell, keep in mind that not indenting your code results in the death of kittens and puppies are kicked. As your experience grows, so will your scripts, so you need to learn indention to see the flow of the script and be able to troubleshoot. Also, there isn't really a need to specify "Write-Output" and in your first try\catch (under the main try catch), I updated your catch. You are capturing something failed, but not why. Minimally, grabbing the exception message will get you troubleshooting information. Would you rather have this "Failed to Create Virtual App" or "Failed to Create Virtual App. Access Denied." as your message? Which one can your troubleshoot faster?

    ##Import App-V application
    
    #Set Application details to add to SCCM from text template
     $DefaultAppPath = "\\theaa.local\dfsdata\sccm\software\"
    
    $Content = get-content "\\aa-cm002v\e$\scripts\AppV_Template.txt"
    $App_DT_Name = $Content[3]
    $App_Name = $Content[5]
    $App_Source_Location = $Content[7]
    $OptRef =
    $Publisher = $Content[9]
    $SoftVer = $Content[11]
    $Folder = $Content[13]
    $DPGroup = "All Distribution Points"
    
    #Full location path
    $LocationFull = "$DefaultAppPath"+"$App_Source_Location"
    
    #Set Module, CMsite directory and revert back to orginal prompt
    $ModulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin"
    $SetDriveStart = "set-location AAC:"
    $SetDriveEnd = "set-location E:"
    
    #Import module
     Import-Module $ModulePath\ConfigurationManager.psd1
    
    try {
         #Set directory
         Invoke-expression $SetDriveStart
    
        #Create new application. "#" if the below command is required.
         Try {
             New-CMApplication -Name $App_Name -AutoInstall $true -Publisher $Publisher -SoftwareVersion $SoftVer | out-null
             Write-Output "Created $App_Name succesfully" 
         }
         Catch {
            "Creating {0} failed. {1}" -f $App_Name, $_.Exception.Message
         }
    
        #Create New Application deployment file
         Try {
             Add-CMDeploymentType -ApplicationName $App_Name -DeploymentTypeName $App_DT_Name -AppV5xInstaller -ForceForUnknownPublisher $true -InstallationFileLocation $LocationFull | out-null
             Write-Output "Created $App_DT_Name succesfully" 
         }
         Catch {
             Write-Output "Creating $App_DT_Name failed" 
         }
    
        #Move Application to folder
         Try {
             $GetApp = Get-CMApplication -name $App_Name
             Move-CMObject -FolderPath ".\Application\Publisher\$Folder" -InputObject $GetApp
             Write-Output "Moved $App_Name to $Folder succesfully" 
         }
         Catch {
            Write-Output "Moving $App_Name to $Folder failed"
         }
    
        #Distribute application
         Try {
             Start-CMContentDistribution -ApplicationName $App_Name -DistributionPointGroupName $DPGroup
             Write-Output "Distributed content to $DPGroup"
         }
         Catch {
            Write-Output "Failed to Distribute content to $DPGroup" 
         }
    
        #Set location back to E drive
        Invoke-expression $SetDriveEnd
    
        Write-Output "Virtual App created in SCCM and currently distributing"
        exit 0 
     }
     Catch {
        Write-Output "Failed to Create Virtual App"
        Exit 1001 
    }
    
    
  • #25234
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The lack of indentation might be just be on the forums, because the OP didn't use the [ pre ] and [ /pre ] tags (which hopefully show up because I stuck in some extra whitespace.)

  • #25237
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Hi Rob,

    Great tip with the error output, wasn't aware of that.
    Dave is right, i did indent the script but its not formatted very well when i pasted it.

    Thanks everyone.

  • #25239
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    Kittens lives are at stake here, use your [ pre ] and [ /pre ] tags. 🙂

  • #25241
    Profile photo of Graham Beer
    Graham Beer
    Participant

    I will do in future...can't risk the kittens !

  • #25258
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    If I may make a suggestion; don't use Write-Output unless it is actually output that needs to be handled in some way outside of the script. Use Write-Verbose/Write-Warning/Write-Error to write information to screen, and Write-Output to pass data along the pipeline.

    Another suggestion, don't return errorcodes. That's so 1990s. PowerShell has exceptional exception handling, which you yourself have discovered. Throw a useful error instead of 1001.

    [cmdletbinding()] #required to get -Verbose functionality
    param()
    
    ##Import App-V application
     
    #Set Application details to add to SCCM from text template
    $DefaultAppPath = "\\theaa.local\dfsdata\sccm\software\"
     
    $Content = get-content "\\aa-cm002v\e$\scripts\AppV_Template.txt"
    $App_DT_Name = $Content[3]
    $App_Name = $Content[5]
    $App_Source_Location = $Content[7]
    $OptRef =
    $Publisher = $Content[9]
    $SoftVer = $Content[11]
    $Folder = $Content[13]
    $DPGroup = "All Distribution Points"
     
    #Full location path
    $LocationFull = "$DefaultAppPath"+"$App_Source_Location"
     
    #Set Module, CMsite directory and revert back to orginal prompt
    $ModulePath = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin"
    $SetDriveStart = "set-location AAC:"
    $SetDriveEnd = "set-location E:"
     
    #Import module
    Import-Module $ModulePath\ConfigurationManager.psd1
     
    try {
         #Set directory
         Invoke-expression $SetDriveStart
     
        #Create new application. "#" if the below command is required.
         Try {
             New-CMApplication -Name $App_Name -AutoInstall $true -Publisher $Publisher -SoftwareVersion $SoftVer | out-null
             Write-Verbose "Created $App_Name succesfully" 
         }
         Catch {
             throw ("Creating {0} failed. {1}" -f $App_Name, $_.Exception.Message)
         }
     
        #Create New Application deployment file
         Try {
             Add-CMDeploymentType -ApplicationName $App_Name -DeploymentTypeName $App_DT_Name -AppV5xInstaller -ForceForUnknownPublisher $true -InstallationFileLocation $LocationFull | out-null
             Write-Verbose "Created $App_DT_Name succesfully" 
         }
         Catch {
             throw "Creating $App_DT_Name failed" 
         }
     
        #Move Application to folder
         Try {
             $GetApp = Get-CMApplication -name $App_Name
             Move-CMObject -FolderPath ".\Application\Publisher\$Folder" -InputObject $GetApp
             Write-Verbose "Moved $App_Name to $Folder succesfully" 
         }
         Catch {
             throw "Moving $App_Name to $Folder failed"
         }
     
        #Distribute application
         Try {
             Start-CMContentDistribution -ApplicationName $App_Name -DistributionPointGroupName $DPGroup
             Write-Verbose "Distributed content to $DPGroup"
         }
         Catch {
             throw "Failed to Distribute content to $DPGroup" 
         }
     
        #Set location back to E drive
        Invoke-expression $SetDriveEnd
     
        Write-Verbose "Virtual App created in SCCM and currently distributing"
    }
    Catch {
        Write-Error "Failed to Create Virtual App: $_"
    }
    
  • #25259
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    Heck if you want to go crazy with exception handling, read up on how to do custom exceptions.

    This post goes into a bit of detail.

  • #25264
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Thank you Martin, very helpful. Much appreciated.

  • #25265
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Martin,

    I've attempted the script with your amendments on an App i know should fail as its already in SCCM.

    I now get the "Red error writing" instead of an nicely outputted error. Have i missed something ?

  • #25269
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    Well it all depends on how you handle the exception. In my example I use Write-Error which produces the fancy red text. You could do Write-Warning instead, or something completely different. That's why it's called exception handling. You handle exceptions however you like.

  • #25277
    Profile photo of Graham Beer
    Graham Beer
    Participant

    Arrrr....i see. Thanks. I'm currently going through Jeff Hicks brilliant videos on the Pluralsight website. But all this is great to know.

You must be logged in to reply to this topic.