PowerShell Script to Move App/Package Content to Containment

Photo of author
By Jeff LeBlanc

For SCCM Admins working in large Enterprise environments supporting large numbers of users, you may have “Packaging” and “Software Distribution” teams that handle package content being created and delivered to end users.

In our environment, we have what we call a “Containment” process for software where we don’t just delete old software versions outright, instead we move it into a “Containment” state for a period of time (example: 60 days) before we delete the objects from the environment.

When running the Containment script, it does the following:

  • Checks to see if the software is referenced in any Task Sequences, if yes, skip
  • Checks for any Deployments, if any are found, remove them
  • Updates the Description/comment with “Containment yyyy-mm-dd”
  • Moves the object to zContainment folder within ConfigMgr
  • If it’s an Application, it is set to Retired
  • Removes the content from from all Distribution Point groups

Scenario 1:

  • New software application is packaged and added to SCCM and distributed to all Distribution Points
  • Old software version is moved to Containment to ensure we can easily roll back if any issues with the new software is discovered

Scenario 2:

  • SCCM Admins identify software that is not being used by any Task Sequences and no longer has any deployments
  • Move software to Containment before deleting
  • See SQL Query to Get All Content from SCCM/MECM for more information

This script handles Applications, packages, Task Sequences, or Driver Packages and can be used for one-offs, or a list using a file.

###########################################################################################################
#
#  Script Name:      AppPkgContainment_v1.5.ps1  
#
#  Description:      Retires a CM Application or Package
#
#  Authors:          Jeff LeBlanc
#
#  Version History:  1.0 - Initial Script
#                    1.1 - Added -ApplicationsFile parameter
#                    1.2 - Added -PackagesFile parameter
#                    1.3 - Added -TaskSequencesFile parameter
#                          Added -TaskSequenceID parameter
#                          Added Logging
#                          Added try/catch error handling
#                    1.4 - Added TS Checks
#                    1.5 - Added DriverPackageID parameter
#                          Added DriverPackageFile parameter
#
#  Command Line:     .\AppPkgContainment_v1.5.ps1 -ApplicationsFile .\Applications.txt
#                    .\AppPkgContainment_v1.5.ps1 -PackagesFile .\Packages.txt
#                    .\AppPkgContainment_v1.5.ps1 -TaskSequencesFile .\TaskSequences.txt
#                    .\AppPkgContainment_v1.5.ps1 -DriverPackagesFile .\DriverPackages.txt
#                    .\AppPkgContainment_v1.5.ps1 -DriverPackagesFile .\DriverPackages.txt
#  
###########################################################################################################

# Verify Command Line Parameters
[CmdletBinding()]
param(
    #Specify the App Name you want to put into Containment
    [parameter(Mandatory=$false)]
    $AppName,

    #Specify the PackageID that you want to put into Containment
    [parameter(Mandatory=$false)]
    $PackageID,

    #Specify the Driver Package ID that you want to put into Containment
    [parameter(Mandatory=$false)]
    $DriverPackageID,

    #Specify the Task Sequence PackageID that you want to put into Containment
    [parameter(Mandatory=$false)]
    $TaskSequenceID,

    #Specify the App Names you want to put into Containment
    [parameter(Mandatory=$false)]
    $ApplicationsFile,

    #Specify the Package IDs you want to put into Containment
    [parameter(Mandatory=$false)]
    $PackagesFile,

    #Specify the Driver Package IDs you want to put into Containment
    [parameter(Mandatory=$false)]
    $DriverPackagesFile,

    #Specify the Task Sequence Package IDs you want to put into Containment
    [parameter(Mandatory=$false)]
    $TaskSequencesFile
)

# Setup Log File Path
$SMSLogPath = $PSScriptRoot
$global:LogFile = "$SMSLogPath\AppPkgContainment.log"

Function Connect-Drive ($CASSiteCode, $CASSiteServer) {
    #Load the Configuration Manager Module
    Import-Module $env:SMS_ADMIN_UI_PATH.Replace("\bin\i386","\bin\ConfigurationManager.psd1")
    $CMDrive = Get-PSDrive -Name $CASSiteCode -ErrorAction Ignore

    # Connect to CMDrive
    if ($CMDrive)
    {
        Set-Location $CASSiteCode":"
    }
    else
    {
        $i = 1

        Do {
            Write-Host "Loop $i"
            $NewDrive = New-PSDrive -Name $CASSiteCode -PSProvider "CMSite" -Root $CASSiteServer -Scope Global
            $i++
        }
        Until ($NewDrive -ne $null -or $i -gt 10)
        Set-Location $CASSiteCode":"
    }
}

Function Get-Domain {
    $CompInfo = Get-WmiObject -Namespace root\cimv2 -Class Win32_ComputerSystem | Select Name, Domain
    Return $CompInfo.Domain.ToUpper()
}

Function Log-Write {

##########################################################################################################
<#
.SYNOPSIS
   Log to a file in a format that can be read by Trace32.exe / CMTrace.exe 

.DESCRIPTION
   Write a line of data to a script log file in a format that can be parsed by Trace32.exe / CMTrace.exe

   The severity of the logged line can be set as:

        1 - Information
        2 - Warning
        3 - Error

   Warnings will be highlighted in yellow. Errors are highlighted in red.

   The tools to view the log:

   SMS Trace - http://www.microsoft.com/en-us/download/details.aspx?id=18153
   CM Trace - Installation directory on Configuration Manager Site Server - <Install Directory>\Tools\

.EXAMPLE
   Log-Write c:\output\update.log "Application of MS15-031 failed" Apply_Patch 3

   This will write a line to the update.log file in c:\output stating that "Application of MS15-031 failed".
   The source component will be Apply_Patch and the line will be highlighted in red as it is an error 
   (severity - 3).

#>
##########################################################################################################

#Define and validate parameters
[CmdletBinding()]
Param(
      #Path to the log file
      [parameter(Mandatory=$True)]
      [String]$NewLog,

      #The information to log
      [parameter(Mandatory=$True)]
      [String]$Value,

      #The source of the error
      [parameter(Mandatory=$True)]
      [String]$Component,

      #The severity (1 - Information, 2- Warning, 3 - Error)
      [parameter(Mandatory=$True)]
      [ValidateRange(1,3)]
      [Single]$Severity
)


#Obtain UTC offset
$DateTime = New-Object -ComObject WbemScripting.SWbemDateTime 
$DateTime.SetVarDate($(Get-Date))
$UtcValue = $DateTime.Value
$UtcOffset = $UtcValue.Substring(21, $UtcValue.Length - 21)


#Create the line to be logged
$LogLine =  "<![LOG[$Value]LOG]!>" +`
            "<time=`"$(Get-Date -Format HH:mm:ss.fff)$($UtcOffset)`" " +`
            "date=`"$(Get-Date -Format M-d-yyyy)`" " +`
            "component=`"$Component`" " +`
            "context=`""" " +`
            "type=`"$Severity`" " +`
            "thread=`" " +`
            "file=`"`">"

#Write the line to the passed log file
Add-Content -Path $NewLog -Value $LogLine

}

Function DisplayUsage {
    Write-Host ""
    Write-Host "Usage Examples:" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -AppName 'My Application Name'" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -PackageID 'ABC00000'" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -TaskSequenceID 'ABC00123'" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -DriverPackageID 'ABC00123'" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -ApplicationsFile .\Applications.txt" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -PackagesFile .\Packages.txt" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -TaskSequencesFile .\TaskSequences.txt" -ForegroundColor Green
    Write-Host "     .\AppPkgContainment.ps1 -DriverPackagesFile .\DriverPackages.txt" -ForegroundColor Green

    Set-Location $PSScriptRoot
    Exit(-1)
}


##########################################################################################################
#
#   MAIN SCRIPT
#
##########################################################################################################

Write-Host "Starting Script Execution..." -ForegroundColor Cyan
Log-Write $LogFile "Starting Script Execution..." AppPkgContainment 1

# Get Domain
Write-Host "Getting Domain environment..." -ForegroundColor Gray
Log-Write $LogFile "Getting Domain environment..." AppPkgContainment 1
$Domain = Get-Domain


# Setup Site Code and Site Server Based on Domain
Switch ($Domain) {
    DEV-DOMAIN.COM {
        $CASSiteCode = "DEV"
        $CASSiteServer = "<ServerFQDN>"

        Write-Host "Domain: $Domain"
        Write-Host "Using CASSiteCode $CASSiteCode"
        Write-Host "Using CASSiteServer $CASSiteServer"

        Log-Write $LogFile "Domain: $Domain" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteCode $CASSiteCode" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteServer $CASSiteServer" AppPkgContainment 1
    }
    UAT-DOMAIN.COM {
        $CASSiteCode = "UAT"
        $CASSiteServer = "<ServerFQDN>"

        Write-Host "Domain: $Domain"
        Write-Host "Using CASSiteCode $CASSiteCode"
        Write-Host "Using CASSiteServer $CASSiteServer"

        Log-Write $LogFile "Domain: $Domain" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteCode $CASSiteCode" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteServer $CASSiteServer" AppPkgContainment 1
    }
    PROD-DOMAIN.COM {
        $CASSiteCode = "PRD"
        $CASSiteServer = "<ServerFQDN>"

        Write-Host "Domain: $Domain"
        Write-Host "Using CASSiteCode $CASSiteCode"
        Write-Host "Using CASSiteServer $CASSiteServer"

        Log-Write $LogFile "Domain: $Domain" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteCode $CASSiteCode" AppPkgContainment 1
        Log-Write $LogFile "Using CASSiteServer $CASSiteServer" AppPkgContainment 1
    }
    default {
        Write-Host "No supported Domain found. Exiting script." -ForegroundColor Red
        Log-Write $LogFile "No supported Domain found. Exiting script." AppPkgContainment 1

        Set-Location $PSScriptRoot
        Exit(-1)
    }
}


# Connect to CM Drive
Connect-Drive $CASSiteCode $CASSiteServer


# Check for AppName or PackageID or $TaskSequenceID or $DriverPackageID Parameter
if ($AppName -or $PackageID -or $DriverPackageID -or $TaskSequenceID -or $ApplicationsFile -or $PackagesFile -or $DriverPackagesFile -or $TaskSequencesFile) {

    Write-Host "Application Name, PackageID, DriverPackageID, TaskSequenceID or file(s) found. Start processing..." -ForegroundColor DarkCyan
    Log-Write $LogFile "Application Name, PackageID, DriverPackageID, TaskSequenceID or file(s) found. Start processing..." AppPkgContainment 1


    # Set Path to Move Retired Applications or Packages
    $AppsPath    = "$CASSiteCode" + ":\Application\zContainment"
    $PkgPath     = "$CASSiteCode" + ":\Package\zContainment"
    $TSPath      = "$CASSiteCode" + ":\TaskSequence\zContainment"
    $DrvPkgPath  = "$CASSiteCode" + ":\DriverPackage\zContainment"
    $Description = "Containment " + (Get-Date -Format yyyy-MM-dd)


    # Process Application
    if ($AppName) {

        # Get Application Information
        $AppInfo = Get-CMApplication -Name $AppName

        Write-Host "Processing Application $AppName [$($AppInfo.PackageID)]" -ForegroundColor Green
        Log-Write $LogFile "Processing Application $AppName [$($AppInfo.PackageID)]" AppPkgContainment 1

        if ($AppInfo) {

            # Check For Task Sequence References for Application
            if($($AppInfo.NumberOfDependentTS -gt 0)) {
                Write-Host "$($AppInfo.NumberOfDependentTS) Task Sequence References found for $AppName. Skipping..." -ForegroundColor Yellow
            }
            else {
                # No Task Sequence References Found for Application
                Write-Host "No Task Sequence references found for $AppName. Continue script execution."
                

                # Check Number of Deployments for Application
                if($($AppInfo.NumberOfDeployments -gt 0)) {
                    Write-Host "$($DeployCount.NumberOfDeployments) Active Deployments found for $app.  Removing deployments for Application..."
                    Log-Write $LogFile "$($DeployCount.NumberOfDeployments) Active Deployments found for $app.  Removing deployments for Application..." AppPkgContainment 1

                    # Remove All Deployments for Application
                    try {
                        Remove-CMApplicationDeployment -Name $AppName -Force
                    }
                    catch {
                        Write-Host "An error occurred running Remove-CMApplicationDeployment to remove Deployments."
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Remove-CMApplicationDeployment to remove Deployments." AppPkgContainment 3
                    }
                }
                else {
                    # No Deployments Exist for Application
                    Write-Host "No Deployments exist for $AppName. Continue script execution."
                    Log-Write $LogFile "No Deployments exist for $AppName. Continue script execution." AppPkgContainment 1
                }

                # Update Application Comment
                Write-Host "Updating Application comments for $AppName to $Description..."
                Log-Write $LogFile "Updating Application comments for $AppName to $Description..." AppPkgContainment 1

                try {
                    Set-CMApplication -Name $AppName -Description $Description
                }
                catch {
                    Write-Host "An error occurred running Set-CMApplication. Could not update application Description:"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Set-CMApplication. Could not update application Description." AppPkgContainment 3
                }
            
                # Move Application to Containment Folder
                Write-Host "Moving Application $AppName to zContainment folder..."
                Log-Write $LogFile "Moving Application $AppName to zContainment folder..." AppPkgContainment 1

                try {
                    Get-CMApplication -Name $AppName | Move-CMObject -FolderPath $AppsPath
                }
                catch {
                    Write-Host "An error occurred running Move-CMObject. Could not move object to $AppsPath"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $AppsPath" AppPkgContainment 3
                }

                # Get List of Distribution Point Groups for Application
                $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE SMS_DPGroupContentInfo.Name = '$AppName'"
                $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                if ($DPGroups) {
                    forEach ($dpg in $DPGroups) {
                        Write-Host "Removing Application $AppName from Distribution Point Group $dpg"
                        Log-Write $LogFile "Removing Application $AppName from Distribution Point Group $dpg" AppPkgContainment 1

                        try {
                            Remove-CMContentDistribution -ApplicationName $AppName -DistributionPointGroupName $dpg -Force
                        }
                        catch {
                            Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $AppName from $dpg"
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $AppName from $dpg" AppPkgContainment 3
                        }
                    }
                }
                else {
                    Write-Host "No Distribution Point Groups found for application $AppName"
                    Log-Write $LogFile "No Distribution Point Groups found for application $AppName" AppPkgContainment 1
                }

                
                # Set Application to Retired
                Write-Host "Retiring application $AppName"
                Log-Write $LogFile "Retiring application $AppName" AppPkgContainment 1

                try {
                    Suspend-CMApplication -Name $AppName
                }
                catch {
                    Write-Host "An error occurred running Suspend-CMApplication. Could not put $AppName into Retired state."
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Suspend-CMApplication. Could not put $AppName into Retired state." AppPkgContainment 3
                }
            }
        }
        else {
            Write-Host "No application object with name $AppName found in SCCM. Please specify a valid Application name." -ForegroundColor Red
            Log-Write $LogFile "No application object with name $AppName found in SCCM. Please specify a valid Application name." AppPkgContainment 1
        }
    } # End Process Application


    # Process Package
    if ($PackageID) {

        # Get Package Information
        $PkgInfo = Get-CMPackage -Id $PackageID -Fast

        Write-Host "Processing Package $($PkgInfo.Name) [$PackageID]" -ForegroundColor Green
        Log-Write $LogFile "Processing Package $($PkgInfo.Name) [$PackageID]" AppPkgContainment 1

        if ($PkgInfo) {

            # Get All Task Sequence References
            Write-Host "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..."
            Log-Write $LogFile "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..." AppPkgContainment 1
            $TaskSequences = Get-CMTaskSequence -ErrorAction SilentlyContinue | Where-Object { $_.References -ne $null }

            # Check Task Sequence References for Package
            $TSReferences = ($TaskSequences | Where {$_.References.Package -eq $($PkgInfo.PackageID)})
            
            if (($TSReferences | Measure-Object).Count -gt 0) {        
                Write-Host "$($PkgInfo.Name) has $(($TSReferences | Measure-Object).Count) TS References Found..." -ForegroundColor Red
                $TSRef = $true
                #Exit(-1)
            }
            else {
                # No Task Sequence References Found for Package
                Write-Host "No Task Sequence references found for package [$($PkgInfo.PackageID)]. Continue script execution."
            }


            # Proceed Based on TS References
            if ($TSRef -eq $true) {
                Write-Host "Skip remaining processing for package [$($PkgInfo.PackageID)] as TS References found." -ForegroundColor Red
            }
            else {

                # Check Number of Deployments for Package
                $Deployments = Get-CMPackageDeployment -PackageId $PackageID | Select-Object AdvertisementID

                if ($($Deployments.Count) -gt 0) {
                    Write-Host "$($Deployments.Count) Active Deployments found for package $($PkgInfo.Name) [$PackageID].  Removing all package Deployments..."
                    Log-Write $LogFile "$($Deployments.Count) Active Deployments found for package $($PkgInfo.Name) [$PackageID].  Removing all package Deployments..." AppPkgContainment 1

                    # Remove All Deployments for Package
                    try {
                        Remove-CMPackageDeployment -PackageId $PackageID -Force
                    }
                    catch {
                        Write-Host "An error occurred running  Remove-CMPackageDeployment. Could not remove Deployments for $($PkgInfo.Name) [$PackageID]."
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running  Remove-CMPackageDeployment. Could not remove Deployments for $($PkgInfo.Name) [$PackageID]." AppPkgContainment 3
                    }
                }
                else {
                    # No Deployments Exist for Package
                    Write-Host "No Deployments exist for package $PackageID. Continue script execution."
                    Log-Write $LogFile "No Deployments exist for package $PackageID. Continue script execution." AppPkgContainment 1
                }

                # Update Package Description
                Write-Host "Updating package Description and moving $PackageID to zContainment"
                Log-Write $LogFile "Updating package Description and moving $PackageID to zContainment" AppPkgContainment 1

                try {
                    Set-CMPackage -Id $PackageID -Description $Description
                }
                catch {
                    Write-Host "An error occurred running Set-CMPackage. Could not update package Description:"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Set-CMPackage. Could not update package Description." AppPkgContainment 3
                }

                # Move Package to Containment Folder
                Write-Host "Moving Package $PackageID to zContainment folder..."
                Log-Write $LogFile "Moving Package $PackageID to zContainment folder..." AppPkgContainment 1

                try {
                    Get-CMPackage -Id $PackageID -Fast | Move-CMObject -FolderPath $PkgPath
                }
                catch {
                    Write-Host "An error occurred running Move-CMObject. Could not move object to $PkgPath"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $PkgPath" AppPkgContainment 3
                }

                # Get List of Distribution Point Groups for Package
                $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE PackageID = '$PackageID'"
                $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                if ($DPGroups) {
                    forEach ($dpg in $DPGroups) {
                        Write-Host "Removing package $PackageID from Distribution Point Group $dpg."
                        Log-Write $LogFile "Removing package $PackageID from Distribution Point Group $dpg." AppPkgContainment 1

                        try {
                            Remove-CMContentDistribution -PackageId $PackageID -DistributionPointGroupName $dpg -Force
                        }
                        catch {
                            Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $PackageID from $dpg"
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $PackageID from $dpg" AppPkgContainment 3
                        }
                    }
                }
                else {
                    Write-Host "No Distribution Point Groups found for package $PackageID."
                    Log-Write $LogFile "No Distribution Point Groups found for package $PackageID." AppPkgContainment 1
                }
            }
        }
        else {
            Write-Host "No package object with PackageID $PackageID found in SCCM. Please enter a valid Package ID." -ForegroundColor Red
            Log-Write $LogFile "No package object with PackageID $PackageID found in SCCM. Please enter a valid Package ID." AppPkgContainment 1
        }
    } # End Process Packages


    # Process Driver Package
    if ($DriverPackageID) {

        # Get Driver Package Information
        $DrvPkgInfo = Get-CMDriverPackage -Id $DriverPackageID -Fast

        Write-Host "Processing Driver Package $($DrvPkgInfo.Name) [$DriverPackageID]" -ForegroundColor Green
        Log-Write $LogFile "Processing Driver Package $($DrvPkgInfo.Name) [$DriverPackageID]" AppPkgContainment 1

        if ($DrvPkgInfo) {

            # Get All Task Sequence References
            Write-Host "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..."
            Log-Write $LogFile "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..." AppPkgContainment 1
            $TaskSequences = Get-CMTaskSequence -ErrorAction SilentlyContinue | Where-Object { $_.References -ne $null }

            # Check Task Sequence References for Package
            $TSReferences = ($TaskSequences | Where {$_.References.Package -eq $($DrvPkgInfo.PackageID)})
            
            if (($TSReferences | Measure-Object).Count -gt 0) {        
                Write-Host "$($DrvPkgInfo.Name) has $(($TSReferences | Measure-Object).Count) TS References Found..." -ForegroundColor Red
                $TSRef = $true
            }
            else {
                # No Task Sequence References Found for Driver Package
                Write-Host "No Task Sequence references found for Driver package [$($DrvPkgInfo.PackageID)]. Continue script execution."
            }


            # Proceed Based on TS References
            if ($TSRef -eq $true) {
                Write-Host "Skip remaining processing for package [$($DrvPkgInfo.PackageID)] as TS References found." -ForegroundColor Red
            }
            else {

                # Update Driver Package Description
                Write-Host "Updating driver package Description and moving $DriverPackageID to zContainment"
                Log-Write $LogFile "Updating driver package Description and moving $DriverPackageID to zContainment" AppPkgContainment 1

                try {
                    Set-CMDriverPackage -Id $DriverPackageID -Description $Description
                }
                catch {
                    Write-Host "An error occurred running Set-CMDriverPackage. Could not update Driver Package Description:"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Set-CMDriverPackage. Could not update Driver Package Description." AppPkgContainment 3
                }

                # Move Driver Package to zContainment Folder
                Write-Host "Moving Driver Package $DriverPackageID to zContainment folder..."
                Log-Write $LogFile "Moving Driver Package $DriverPackageID to zContainment folder..." AppPkgContainment 1

                try {
                    Get-CMDriverPackage -Id $DriverPackageID -Fast | Move-CMObject -FolderPath $DrvPkgPath
                }
                catch {
                    Write-Host "An error occurred running Move-CMObject. Could not move object to $DrvPkgPath"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $DrvPkgPath" AppPkgContainment 3
                }

                # Get List of Distribution Point Groups for Driver Package
                $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE PackageID = '$DriverPackageID'"
                $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                if ($DPGroups) {
                    forEach ($dpg in $DPGroups) {
                        Write-Host "Removing driver package $DriverPackageID from Distribution Point Group $dpg."
                        Log-Write $LogFile "Removing driver package $DriverPackageID from Distribution Point Group $dpg." AppPkgContainment 1

                        try {
                            Remove-CMContentDistribution -DriverPackageId $DriverPackageID -DistributionPointGroupName $dpg -Force
                        }
                        catch {
                            Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $DriverPackageID from $dpg"
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $DriverPackageID from $dpg" AppPkgContainment 3
                        }
                    }
                }
                else {
                    Write-Host "No Distribution Point Groups found for driver package $DriverPackageID."
                    Log-Write $LogFile "No Distribution Point Groups found for driver package $DriverPackageID." AppPkgContainment 1
                }
            }
        }
        else {
            Write-Host "No driver package object with PackageID $DriverPackageID found in SCCM. Please enter a valid Driver Package ID." -ForegroundColor Red
            Log-Write $LogFile "No driver package object with PackageID $DriverPackageID found in SCCM. Please enter a valid Driver Package ID." AppPkgContainment 1
        }
    } # End Process Driver Packages


    # Process Task Sequence
    if ($TaskSequenceID) {

        # Get Task Sequence Information
        $TSInfo = Get-CMTaskSequence -TaskSequencePackageId $TaskSequenceID -Fast

        Write-Host "Processing Task Sequence $($TSInfo.Name) [$TaskSequenceID]" -ForegroundColor Green
        Log-Write $LogFile "Processing Task Sequence $($TSInfo.Name) [$TaskSequenceID]" AppPkgContainment 1

        if ($TSInfo) {
            # Check for Existing Deployments
            $Deployments = Get-CMTaskSequenceDeployment -TaskSequenceId $TaskSequenceID -Fast | Select-Object AdvertisementID

            if ($($Deployments.Count) -gt 0) {
                Write-Host "$($Deployments.Count) Active Deployments found for Task Sequence $TaskSequenceID.  Removing all Deployments..."
                Log-Write $LogFile "$($Deployments.Count) Active Deployments found for Task Sequence $TaskSequenceID.  Removing all Deployments..." AppPkgContainment 1

                # Remove All Deployments for Package
                try {
                    Remove-CMTaskSequenceDeployment -TaskSequenceId $TaskSequenceID -Force
                }
                catch {
                    Write-Host "An error occurred running Remove-CMTaskSequenceDeployment. Could not remove deployments for Task Sequence $($TSInfo.Name) [$TaskSequenceID]"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Remove-CMTaskSequenceDeployment. Could not remove deployments for Task Sequence $($TSInfo.Name) [$TaskSequenceID]" AppPkgContainment 3
                }
            }
            else {
                Write-Host "No Deployments found.  Skipping Deployment removal."
                Log-Write $LogFile "No Deployments found.  Skipping Deployment removal." AppPkgContainment 1
            }

            
            # Update Task Sequence Description and Move Task Sequence to zContainment Folder
            Write-Host "Updating Task Sequence comments and moving Task Sequence $TaskSequenceID to zContainment"
            Log-Write $LogFile "Updating Task Sequence comments and moving Task Sequence $TaskSequenceID to zContainment" AppPkgContainment 1

            # Update Task Sequence Description
            try {
                Set-CMTaskSequence -TaskSequenceId $TaskSequenceID -Description $Description
            }
            catch {
                Write-Host "An error occurred running Set-CMTaskSequence. Could not update Task Sequence Description:"
                Write-Host $_
                Log-Write $LogFile "An error occurred running Set-CMTaskSequence. Could not update Task Sequence Description." AppPkgContainment 3
            }

            # Move Task Sequence to Containment Folder
            try {
                Get-CMTaskSequence -TaskSequencePackageId $TaskSequenceID -Fast | Move-CMObject -FolderPath $TSPath
            }
            catch {
                Write-Host "An error occurred running Move-CMObject. Could not move object to $TSPath"
                Write-Host $_
                Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $TSPath" AppPkgContainment 3
            }
        }
        else {
            Write-Host "No Task Sequence object with PackageID $TaskSequenceID found in SCCM. Exiting." -ForegroundColor Red
            Log-Write $LogFile "No Task Sequence object with PackageID $TaskSequenceID found in SCCM. Exiting." AppPkgContainment 1
        }
    } # End Process Task Sequence


    # Process Applications File
    if ($ApplicationsFile) {

        Write-Host "Processing Applications found in $ApplicationsFile" -ForegroundColor Yellow
        Log-Write $LogFile "Processing Applications found in $ApplicationsFile" AppPkgContainment 1

        $Applications = Get-Content -Path $PSScriptRoot\$ApplicationsFile

        Write-Host "Processing $($Applications.Count) Applications found in $ApplicationsFile" -ForegroundColor Green
        Log-Write $LogFile "Processing $($Applications.Count) Applications found in $ApplicationsFile" AppPkgContainment 1

        ForEach ($Application in $Applications) {
            Write-Host "Processing $Application..." -ForegroundColor Cyan
            Log-Write $LogFile "Processing $Application..." AppPkgContainment 1

            # Get Application Information
            $AppInfo = Get-CMApplication -Name $Application

            if ($AppInfo) {

                # Check For Task Sequence References for Application
                if($($AppInfo.NumberOfDependentTS -gt 0)) {
                    Write-Host "$($AppInfo.NumberOfDependentTS) Task Sequence References found for $Application. Skipping..." -ForegroundColor Yellow
                    Log-Write $LogFile "$($AppInfo.NumberOfDependentTS) Task Sequence References found for $Application. Skipping..." AppPkgContainment 2
                    #Exit(-1)
                }
                else {
                    # No Task Sequence References Found for Application
                    Write-Host "No Task Sequence references found for $Application. Continue script execution."
                    Log-Write $LogFile "No Task Sequence references found for $Application. Continue script execution." AppPkgContainment 1
                

                    # Check Number of Deployments for Application
                    if($($AppInfo.NumberOfDeployments -gt 0)) {
                        Write-Host "$($DeployCount.NumberOfDeployments) Active Deployments found for $app.  Removing deployments for Application..."
                        Log-Write $LogFile "$($DeployCount.NumberOfDeployments) Active Deployments found for $app.  Removing deployments for Application..." AppPkgContainment 1

                        # Remove All Deployments for Application
                        try {
                            Remove-CMApplicationDeployment -Name $Application -Force
                        }
                        catch {
                            Write-Host "An error occurred running Remove-CMApplicationDeployment to remove Deployments for $Application"
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running Remove-CMApplicationDeployment to remove Deployments for $Application" AppPkgContainment 3
                        }
                    }
                    else {
                        # No Deployments Exist for Application
                        Write-Host "No Deployments exist for $Application. Continue script execution."
                        Log-Write $LogFile "No Deployments exist for $Application. Continue script execution." AppPkgContainment 1
                    }

                    # Update Application Comment
                    Write-Host "Updating Application comments for $Application to $Description..."
                    Log-Write $LogFile "Updating Application comments for $Application to $Description..." AppPkgContainment 1

                    try {
                        Set-CMApplication -Name $Application -Description $Description
                    }
                    catch {
                        Write-Host "An error occurred running Set-CMApplication. Could not update application Description:"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Set-CMApplication. Could not update application Description." AppPkgContainment 3
                    }
            
                    # Move Application to Containment Folder
                    Write-Host "Moving Application $Application to zContainment folder..."
                    Log-Write $LogFile "Moving Application $Application to zContainment folder..." AppPkgContainment 1

                    try {
                        Get-CMApplication -Name $Application | Move-CMObject -FolderPath $AppsPath
                    }
                    catch {
                        Write-Host "An error occurred running Move-CMObject. Could not move object to $AppsPath"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $AppsPath" AppPkgContainment 3
                    }

                    # Get List of Distribution Point Groups for Application
                    $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE SMS_DPGroupContentInfo.Name = '$Application'"
                    $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                    if ($DPGroups) {
                        forEach ($dpg in $DPGroups) {
                            Write-Host "Removing Application $Application from Distribution Point Group $dpg"
                            Log-Write $LogFile "Removing Application $Application from Distribution Point Group $dpg" AppPkgContainment 1

                            try {
                                Remove-CMContentDistribution -ApplicationName $Application -DistributionPointGroupName $dpg -Force
                            }
                            catch {
                            Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $Application from $dpg"
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $Application from $dpg" AppPkgContainment 3
                            }
                        }
                    }
                    else {
                        Write-Host "No Distribution Point Groups found for application $Application"
                        Log-Write $LogFile "No Distribution Point Groups found for application $Application" AppPkgContainment 1
                    }

                    # Set Application to Retired
                    Write-Host "Retiring application $Application"
                    Log-Write $LogFile "Retiring application $Application" AppPkgContainment 1

                    try {
                        Suspend-CMApplication -Name $Application
                    }
                    catch {
                        Write-Host "An error occurred running Suspend-CMApplication. Could not put $Application into Retired state."
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Suspend-CMApplication. Could not put $Application into Retired state." AppPkgContainment 3
                    }
                }
            }
            else {
                Write-Host "No application object with name $Application found in SCCM. Exiting." -ForegroundColor Red
                Log-Write $LogFile "No application object with name $Application found in SCCM. Exiting." AppPkgContainment 1
            }

            Write-Host "Sleep for 10s before processing next application..." -ForegroundColor Yellow
            Log-Write $LogFile "Sleep for 10s before processing next application..." AppPkgContainment 1

            Sleep -Seconds 10
        }
    } # End Process ApplicationsFile


    # Process Packages File
    if ($PackagesFile) {
        Write-Host "Processing Packages found in $PackagesFile" -ForegroundColor Yellow
        Log-Write $LogFile "Processing Packages found in $PackagesFile" AppPkgContainment 1

        $Packages = Get-Content -Path $PSScriptRoot\$PackagesFile

        Write-Host "Found $($Packages.Count) packages to process" -ForegroundColor Yellow
        Log-Write $LogFile "Found $($Packages.Count) packages to process" AppPkgContainment 1

        # Get All Task Sequence References
        Write-Host "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..."
        Log-Write $LogFile "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..." AppPkgContainment 1
        $TaskSequences = Get-CMTaskSequence -ErrorAction SilentlyContinue | Where-Object { $_.References -ne $null }

        # Process Packages
        ForEach ($Package in $Packages) {
            Write-Host "Processing $Package..." -ForegroundColor Cyan
            Log-Write $LogFile "Processing $Package..." AppPkgContainment 1

            # Get Package Information
            $PkgInfo = Get-CMPackage -Id $Package -Fast

            if ($PkgInfo) {

                # Check Task Sequence References for Package
                $TSReferences = ($TaskSequences | Where {$_.References.Package -eq $Package})

                if (($TSReferences | Measure-Object).Count -gt 0)
                {        
                    Write-Host "$($PkgInfo.Name) [$Package] has $(($TSReferences | Measure-Object).Count) TS References Found..." -ForegroundColor Yellow
                    Log-Write $LogFile "$($PkgInfo.Name) [$Package] has $(($TSReferences | Measure-Object).Count) TS References Found..." AppPkgContainment 1

                    Write-Host "Skip remaining processing for package $($PkgInfo.Name) [$($PkgInfo.PackageID)] as TS References found." -ForegroundColor Yellow
                    Log-Write $LogFile "Skip remaining processing for package $($PkgInfo.Name) [$($PkgInfo.PackageID)] as TS References found." AppPkgContainment 2

                    #Exit(-1)
                }
                else {
                    # No Task Sequence References Found for Package
                    Write-Host "No Task Sequence references found for package $($PkgInfo.Name) [$($PkgInfo.PackageID)]. Continue script execution."
                    Log-Write $LogFile "No Task Sequence references found for package $($PkgInfo.Name) [$($PkgInfo.PackageID)]. Continue script execution." AppPkgContainment 1

                    # Check Number of Deployments for Package
                    $Deployments = Get-CMPackageDeployment -PackageId $Package | Select-Object AdvertisementID

                    if ($($Deployments.Count) -gt 0) {
                        Write-Host "$($Deployments.Count) Active Deployments found for package $Package.  Removing all package Deployments..."
                        Log-Write $LogFile "$($Deployments.Count) Active Deployments found for package $Package.  Removing all package Deployments..." AppPkgContainment 1

                        # Remove All Deployments for Package
                        Write-Host "Removing all Deployments for Package $Package"
                        Log-Write $LogFile "Removing all Deployments for Package $Package" AppPkgContainment 1

                        try {
                            Remove-CMPackageDeployment -PackageId $Package -Force
                        }
                        catch {
                            Write-Host "An error occurred running  Remove-CMPackageDeployment. Could not remove Deployments for $($PkgInfo.Name) [$Package]."
                            Write-Host $_
                            Log-Write $LogFile "An error occurred running  Remove-CMPackageDeployment. Could not remove Deployments for $($PkgInfo.Name) [$Package]." AppPkgContainment 3 
                        }
                    }
                    else {
                        # No Deployments Exist for Package
                        Write-Host "No Deployments exist for package $Package. Continue script execution."
                        Log-Write $LogFile "No Deployments exist for package $Package. Continue script execution." AppPkgContainment 1
                    }

                    # Update Package Description
                    Write-Host "Updating package Description and moving $Package to zContainment"
                    Log-Write $LogFile "Updating package Description and moving $Package to zContainment" AppPkgContainment 1

                    try {
                        Set-CMPackage -Id $Package -Description $Description
                    }
                    catch {
                        Write-Host "An error occurred running Set-CMPackage. Could not update package Description:"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Set-CMPackage. Could not update package Description." AppPkgContainment 3
                    }

                    # Move Package to Containment Folder
                    Write-Host "Moving Package $Package to zContainment folder..."
                    Log-Write $LogFile "Moving Package $Package to zContainment folder..." AppPkgContainment 1

                    try {
                        Get-CMPackage -Id $Package -Fast | Move-CMObject -FolderPath $PkgPath
                    }
                    catch {
                        Write-Host "An error occurred running Move-CMObject. Could not move object to $PkgPath"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $PkgPath" AppPkgContainment 3
                    }

                    # Get List of Distribution Point Groups for Package
                    $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE PackageID = '$Package'"
                    $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                    if ($DPGroups) {
                        forEach ($dpg in $DPGroups) {
                            Write-Host "Removing package $Package from Distribution Point Group $dpg."
                            Log-Write $LogFile "Removing package $Package from Distribution Point Group $dpg." AppPkgContainment 1

                            try {
                                Remove-CMContentDistribution -PackageId $Package -DistributionPointGroupName $dpg -Force
                            }
                            catch {
                                Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $Package from $dpg"
                                Write-Host $_
                                Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $Package from $dpg" AppPkgContainment 3
                            }
                        }
                    }
                    else {
                        Write-Host "No Distribution Point Groups found for package $Package."
                        Log-Write $LogFile "No Distribution Point Groups found for package $Package." AppPkgContainment 1
                    }
                } # End Else TSCheck

                Write-Host "Sleep for 10s before processing next package..."
                Log-Write $LogFile "Sleep for 10s before processing next package..." AppPkgContainment 1

                Sleep -Seconds 10

            } # End If PkgInfo
            else {
                Write-Host "No package object found in SCCM for package ID $Package. Exiting." -ForegroundColor Red
                Log-Write $LogFile "No package object found in SCCM for package ID $Package. Exiting." AppPkgContainment 1
            }
        }
    } # End Process PackagesFile


    # Process Driver Packages File
    if ($DriverPackagesFile) {
        Write-Host "Processing Driver Packages found in $DriverPackagesFile" -ForegroundColor Yellow
        Log-Write $LogFile "Processing Driver Packages found in $DriverPackagesFile" AppPkgContainment 1

        $DriverPackages = Get-Content -Path $PSScriptRoot\$DriverPackagesFile

        Write-Host "Found $($DriverPackages.Count) driver packages to process" -ForegroundColor Yellow
        Log-Write $LogFile "Found $($DriverPackages.Count) driver packages to process" AppPkgContainment 1

        # Get All Task Sequence References
        Write-Host "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..."
        Log-Write $LogFile "Getting all Task Sequence References from SCCM. Ignore the WARNING, we need the lazy properties. This will take a few moments..." AppPkgContainment 1
        $TaskSequences = Get-CMTaskSequence -ErrorAction SilentlyContinue | Where-Object { $_.References -ne $null }

        # Process Driver Packages
        ForEach ($DriverPackage in $DriverPackages) {
            Write-Host "Processing $DriverPackage..." -ForegroundColor Cyan
            Log-Write $LogFile "Processing $DriverPackage..." AppPkgContainment 1

            # Get Package Information
            $DrvPkgInfo = Get-CMDriverPackage -Id $DriverPackage -Fast

            if ($DrvPkgInfo) {

                # Check Task Sequence References for Driver Package
                $TSReferences = ($TaskSequences | Where {$_.References.Package -eq $DriverPackage})

                if (($TSReferences | Measure-Object).Count -gt 0)
                {        
                    Write-Host "$($DrvPkgInfo.Name) [$DriverPackage] has $(($TSReferences | Measure-Object).Count) TS References Found..." -ForegroundColor Yellow
                    Log-Write $LogFile "$($DrvPkgInfo.Name) [$DriverPackage] has $(($TSReferences | Measure-Object).Count) TS References Found..." AppPkgContainment 1

                    Write-Host "Skip remaining processing for Driver Package $($DrvPkgInfo.Name) [$($DrvPkgInfo.PackageID)] as TS References found." -ForegroundColor Yellow
                    Log-Write $LogFile "Skip remaining processing for Driver Package $($DrvPkgInfo.Name) [$($DrvPkgInfo.PackageID)] as TS References found." AppPkgContainment 2
                }
                else {
                    # No Task Sequence References Found for Driver Package
                    Write-Host "No Task Sequence references found for Driver Package $($DrvPkgInfo.Name) [$($DrvPkgInfo.PackageID)]. Continue script execution."
                    Log-Write $LogFile "No Task Sequence references found for Driver Package $($DrvPkgInfo.Name) [$($DrvPkgInfo.PackageID)]. Continue script execution." AppPkgContainment 1

                    # Update Driver Package Description
                    Write-Host "Updating Driver Package Description and moving $DriverPackage to zContainment"
                    Log-Write $LogFile "Updating Driver Package Description and moving $DriverPackage to zContainment" AppPkgContainment 1

                    try {
                        Set-CMDriverPackage -Id $DriverPackage -Description $Description
                    }
                    catch {
                        Write-Host "An error occurred running Set-CMDriverPackage. Could not update driver package Description:"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Set-CMDriverPackage. Could not update driver package Description." AppPkgContainment 3
                    }

                    # Move Driver Package to Containment Folder
                    Write-Host "Moving Driver Package $DriverPackage to zContainment folder..."
                    Log-Write $LogFile "Moving Driver Package $DriverPackage to zContainment folder..." AppPkgContainment 1

                    try {
                        Get-CMDriverPackage -Id $DriverPackage -Fast | Move-CMObject -FolderPath $DrvPkgPath
                    }
                    catch {
                        Write-Host "An error occurred running Move-CMObject. Could not move object to $DrvPkgPath"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $DrvPkgPath" AppPkgContainment 3
                    }

                    # Get List of Distribution Point Groups for Driver Package
                    $DPGQuery = "SELECT SMS_DistributionPointGroup.Name FROM SMS_DistributionPointGroup JOIN SMS_DPGroupContentInfo ON SMS_DistributionPointGroup.GroupID = SMS_DPGroupContentInfo.GroupID WHERE PackageID = '$DriverPackage'"
                    $DPGroups = (Get-WmiObject -ComputerName $CASSiteServer -Namespace "root\sms\site_$CASSiteCode" -Query $DPGQuery).Name

                    if ($DPGroups) {
                        forEach ($dpg in $DPGroups) {
                            Write-Host "Removing Driver Package $DriverPackage from Distribution Point Group $dpg."
                            Log-Write $LogFile "Removing Driver Package $DriverPackage from Distribution Point Group $dpg." AppPkgContainment 1

                            try {
                                Remove-CMContentDistribution -DriverPackageId $DriverPackage -DistributionPointGroupName $dpg -Force
                            }
                            catch {
                                Write-Host "An error occurred running Remove-CMContentDistribution. Could not remove $DriverPackage from $dpg"
                                Write-Host $_
                                Log-Write $LogFile "An error occurred running Remove-CMContentDistribution. Could not remove $DriverPackage from $dpg" AppPkgContainment 3
                            }
                        }
                    }
                    else {
                        Write-Host "No Distribution Point Groups found for driver package $DriverPackage."
                        Log-Write $LogFile "No Distribution Point Groups found for driver package $DriverPackage." AppPkgContainment 1
                    }
                } # End Else TSCheck

                Write-Host "Sleep for 10s before processing next driver package..."
                Log-Write $LogFile "Sleep for 10s before processing next driver package..." AppPkgContainment 1

                Sleep -Seconds 10

            } # End If DrvPkgInfo
            else {
                Write-Host "No driver package object found in SCCM for package ID $DriverPackage. Exiting." -ForegroundColor Red
                Log-Write $LogFile "No driver package object found in SCCM for package ID $DriverPackage. Exiting." AppPkgContainment 1
            }
        }
    } # End Process DriverPackagesFile


    # Process Task SequencesFile
    if ($TaskSequencesFile) {
        Write-Host "Processing Task Sequences in $TaskSequencesFile" -ForegroundColor Yellow
        Log-Write $LogFile "Processing Task Sequences in $TaskSequencesFile" RetireApplicationPackage 1

        # Read $TaskSequencesFile for TS List
        $TaskSequences = Get-Content $PSScriptRoot\$TaskSequencesFile

        Write-Host "Found $($TaskSequences.Count) Task Sequences to process" -ForegroundColor Yellow
        Log-Write $LogFile "Found $($TaskSequences.Count) Task Sequences to process" AppPkgContainment 1


        ForEach ($ts in $TaskSequences) {

            # Get Task Sequence Information
            $TSInfo = Get-CMTaskSequence -TaskSequencePackageId $ts -Fast

            Write-Host "Processing Task Sequence $($TSInfo.Name) [$ts]" -ForegroundColor Green
            Log-Write $LogFile "Processing Task Sequence $($TSInfo.Name) [$ts]" AppPkgContainment 1

            if ($TSInfo) {
                # Check for Existing Deployments
                $Deployments = Get-CMTaskSequenceDeployment -TaskSequenceId $ts -Fast | Select-Object AdvertisementID

                if ($($Deployments.Count) -gt 0) {
                    Write-Host "$($Deployments.Count) Active Deployments found for Task Sequence $ts.  Removing all Deployments..."
                    Log-Write $LogFile "$($Deployments.Count) Active Deployments found for Task Sequence $ts.  Removing all Deployments..." RetireApplicationPackage 2

                    # Remove All Deployments for Task Sequence
                    try {
                        Remove-CMTaskSequenceDeployment -TaskSequenceId $ts -Force
                    }
                    catch {
                        Write-Host "An error occurred running Remove-CMTaskSequenceDeployment. Could not remove deployments for Task Sequence ts"
                        Write-Host $_
                        Log-Write $LogFile "An error occurred running Remove-CMTaskSequenceDeployment. Could not remove deployments for Task Sequence $($TSInfo.Name) [$TaskSequenceID]" AppPkgContainment 3
                    }
                }
                else {
                    Write-Host "No Deployments found.  Skipping Deployment removal."
                    Log-Write $LogFile "No Deployments found.  Skipping Deployment removal." RetireApplicationPackage 1
                }
    
                # Update Task Sequence Description and Move Task Sequence to zContainment Folder
                Write-Host "Updating Task Sequence comments and moving Task Sequence $ts to zContainment"
                Log-Write $LogFile "Updating Task Sequence comments and moving Task Sequence $ts to zContainment" RetireApplicationPackage 1

                # Update Task Sequence Description
                try {
                    Set-CMTaskSequence -TaskSequenceId $ts -Description $Description
                }
                catch {
                    Write-Host "An error occurred running Set-CMTaskSequence. Could not update Task Sequence Description:"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Set-CMTaskSequence. Could not update Task Sequence Description." AppPkgContainment 3
                }

                # Move Task Sequence to Containment Folder
                try {
                    Get-CMTaskSequence -TaskSequencePackageId $ts -Fast | Move-CMObject -FolderPath $TSPath
                }
                catch {
                    Write-Host "An error occurred running Move-CMObject. Could not move object to $TSPath"
                    Write-Host $_
                    Log-Write $LogFile "An error occurred running Move-CMObject. Could not move object to $TSPath" AppPkgContainment 3
                }
            }
            else {
                Write-Host "No Task Sequence object found in SCCM for TS ID $ts. Exiting." -ForegroundColor Red
                Log-Write $LogFile "No Task Sequence object found in SCCM for TS ID $ts. Exiting." AppPkgContainment 1
            }
        }
    } # End Process TaskSequencesFile
}
else {
    Write-Host "No Applications, Packages or Task Sequences or input files specified. Exiting." -ForegroundColor Red
    Log-Write $LogFile "No Applications, Packages or Task Sequences or input files specified. Exiting." AppPkgContainment 1

    DisplayUsage

    Set-Location $PSScriptRoot
    Exit(-1)
}


Write-Host "Finished script execution." -ForegroundColor Cyan
Log-Write $LogFile "Finished script execution." AppPkgContainment 1

Set-Location $PSScriptRoot

Happy Computing!

Leave a Comment