5 min read

ConfigMgr - Clear retired applications and content

ConfigMgr - Clear retired applications and content

Update

I made a tool out of this script as well, check it out!

MEMCM - Delete-RetiredApplications reborn!
So, the Delete-RetiredApplications script that i wrote, has more or less been reborn into a “tool” instead, as i decided to do a GUI for it and add more functionality. It now has a option to backup/archive the applications which is to be deleted from ConfigMgr. As it sits

Update 2022-03-04

Added options to export application and content, and/or save content at source


You know it's a pain, a bore, real tedious, but it has to be done.
Cleaning them old applications and their respective files.
It's a lot of clicking-about... zZzzZzzZZzZ

So, we create a new PowerShell function for it instead and let that handle it, you just have to mark you applications as "Retired" and this bad-boy will locate that sucker and eliminate it and all them files on your source share.

And, if you want, never worry about these things again by creating a scheduled task for it and let it go to town every other day, month or year, and you take your fishing gear and go to the lake instead. Just keep retiring them and then forget about it.

P.S If you wanna see them apps go down one-by-one instead, just specify what app you want gone with -SpecificApplication "NameOfAppToDelete".
And if your feeling anxious about firing away, use the -WhatIf switch to predict the future of your applications demise.

Otherwise this gets ALL your applications which is set at Retired, if you don´t use "$SpecificApplication", then gets the content location from the SDMPackgeXML (the XML information about your application), deletes the content, then deletes the app.

Note that the function can be run with -WhatIf, so that you first can check what will be deleted.

<#
    .SYNOPSIS
    This is is the script version of "Delete-RetiredApplications"-tool you can use if you dont care about saving any content or exporting/backing up your retired applications.
    Use it with eg scheduled task or run on demand.

    .VERSION
    2022-02-03 - script created with basic function to clear all retired applications and their content
    2022-03-04 - Added the options to have applicaiton exported before deletion, and/or save source content.


    .EXAMPLE
    Remove all you retired applications and their content
        Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1"
    
    Remove specific application and its content
        Remove-RetiredApplications -SpecificApplication "ApplicationName" -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1"

    Export application and related content before deletion and ignore related applications
        Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1" -ExportApplication $true -OmitContent $false -IgnoreRelated $true -ExportLocation "$env:SYSTEMDRIVE\Temp\ApplicationArchive"

    Save source content and delete applications
        Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1" -SaveContent $true
#>

Function Remove-RetiredApplications{
    [cmdletbinding(SupportsShouldProcess=$True)]
    Param(
        [Parameter(Mandatory=$true, HelpMessage='Siteserver FQDN, eg cm01.corp.viamonstra.com')]
	    [string]$ProviderMachineName,
        
        [Parameter(Mandatory=$true, HelpMessage='Sitecode, eg PS1')]
        [string]$SiteCode,

        [Parameter(HelpMessage='If you want to retire just a specific ')]
        [string]$SpecificApplication,

        [Parameter(Mandatory=$True,
        ParameterSetName='ExportApplication',
        HelpMessage='Set if you want the application to be exported before deletion.')]
        [bool]$ExportApplication,

        [Parameter(ParameterSetName='ExportApplication',
        HelpMessage='Indicates that the cmdlet exports related content to a separate folder in the same location as the .zip file.')]
        [bool]$OmitContent,

        [Parameter(ParameterSetName='ExportApplication',
        HelpMessage='Indicates that related objects, such as application dependencies, superseded applications, or related categories and global conditions, are not exported.')]
        [bool]$IgnoreRelated,

        [Parameter(HelpMessage='Set the location where you want app exported to.')]
        [string]$ExportLocation,

        [Parameter(Mandatory=$True, HelpMessage='Dont delete source content.')]
        [bool]$SaveContent
    )

    begin{
        # Load ConfigMgr PSModule and connect to site
        if((Get-Module ConfigurationManager) -eq $null){
            Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1"
        }
        if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null){
            New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName
        }

        # Get retired applications
        Set-Location "$($SiteCode):\"
        $AppLocations = @()
        If([string]::IsNullOrEmpty($SpecificApplication)){
            $RetiredApplications = Get-CMApplication -Fast | Where -Property IsExpired -eq "True" | Select -Property CI_ID,LocalizedDisplayName
        }
        Else{
            $RetiredApplications = Get-CMApplication -Name $SpecificApplication
        }
        
        # Get application content location
        Foreach($RetiredApplication in $RetiredApplications){
            $App = Get-CMApplication -ID $RetiredApplication.CI_ID
            $AppXML = [xml]$App.SDMPackageXML
            $AppLocations += $AppXML.AppMgmtDigest.DeploymentType.Installer.Contents.Content.Location
        }
    }
    Process{
        # Export Application
        Switch($ExportApplication){
            "true"{
                If (!(Test-path $ExportLocation)) {
                    New-Item -ItemType Directory -Path $ExportLocation -Force
                }
                Try {
                    Foreach ($RetiredApplication in $RetiredApplications ){
                        $Arguments = @{}
                        switch ($OmitContent) {
                            "true" { $Arguments += @{OmitContent = $true} }
                        }
                        switch ($IgnoreRelated) {
                            "true" { $Arguments += @{IgnoreRelated = $true} }
                        }
                        $AppArchiveDir = (New-Item -ItemType Directory -Force -Path "$ExportLocation\$($RetiredApplication.LocalizedDisplayName)").FullName 
                        Export-CMApplication -Id $RetiredApplication.CI_ID -Path ($AppArchiveDir + "\" + ($RetiredApplication.LocalizedDisplayName) + ".zip") @Arguments -Force
                    }
                }
                Catch {
                    $_.Exception.Message
                }
            }
        }

        # Delete application contentfiles
        Switch($SaveContent){
            "False"{
                Foreach($AppLocation in $AppLocations){
                    Write-Output "Removing Application content from $Applocation"
                    Set-Location $env:systemdrive
                    Remove-Item -Path $AppLocation -Recurse -Force
                }
            }
        }
    }
    End{
        # Delete the application from ConfigMgr
        Foreach($RetiredApplication in $RetiredApplications){
            Set-Location "$($SiteCode):\"
            Remove-CMApplication -ID $RetiredApplication.CI_ID -Force
        }
    }
}

Example

Remove all you retired applications and content

Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1"

Remove specific application and content

Remove-RetiredApplications -SpecificApplication "ApplicationName" -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1"

Export application and content, then remove

Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1" -ExportApplication $true -OmitContent $false -IgnoreRelated $true -ExportLocation "$env:SYSTEMDRIVE\Temp\ApplicationArchive"

Save Content at source, remove application

Remove-RetiredApplications -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1" -SaveContent $true

Remember the -WhatIf

Remove-RetiredApplications -SpecificApplication "ApplicationName" -ProviderMachineName "cm01.corp.viamonstra.com" -SiteCode "PS1" -WhatIf

Reference

Script

EndpointManagement/Delete-RetiredApplications-Script.ps1 at master · Love-A/EndpointManagement
Endpoint Management stuff galore! Contribute to Love-A/EndpointManagement development by creating an account on GitHub.

Tool

EndpointManagement/Delete-RetiredApplications-Tool.ps1 at master · Love-A/EndpointManagement
Endpoint Management stuff galore! Contribute to Love-A/EndpointManagement development by creating an account on GitHub.