In preparation for an SCCM cleanup project, I was tasked with compiling a list of all Applications and Packages that were not being deployed and had no dependent task sequences or deployment types. Here’s how I did it with PowerShell.

Before we begin: The ConfigMgr Module

Microsoft’s ConfigurationManager module needs to be installed prior to running this script, or it will fail. You can grab the installer here.

Filter, filter, filter

We need to start with a list of all Applications and Packages and filter down from there. The following code accomplishes this and additionally filters the Applications to our desired results since the objects returned by Get-CMApplication provide all the properties that we need to query.

# Grab all non-deployed/0 dependent TS/0 dependent DT applications, and all packages (can't filter packages like applications)
$FinalApplications = Get-CMApplication `
| Where-Object {($_.IsDeployed -eq $False) -and ($_.NumberofDependentTS -eq 0) -and ($_.NumberofDependentDTs -eq 0)}
$AllPackages = Get-CMPackage

This leaves us with Packages. To achieve the same result as Applications, we will first need a list of all of the existing Task Sequences’ References to their included items.

$TSReferences = Get-CMTaskSequence | Select-Object -ExpandProperty References

Next, we need a list of all existing deployments’ PackageIDs.

$DeploymentPackageIDs = Get-CMDeployment | Select-Object -ExpandProperty PackageID

Finally, we filter $AllPackages to only Packages that are not in either of $TSReferences and $DeploymentPackageIDs.

$FinalPackages = New-Object -TypeName 'System.Collections.ArrayList'

# Filter packages to only those that do not have their PackageID in the list of references
foreach ($package in $AllPackages) {
  if (($package.PackageID -notin $TSReferences) -and ($package.PackageID -notin $DeploymentPackageIDs)) {

And that’s it! You can find the full script here.