When you’re doing a migration and migrate Packages and Deployments that are associated with them, the best practice is to not let the migration wizard enable the Program for each Package after the migration has successfully completed. Instead, it’s a good idea to review the Packages and their configuration before you enable the Programs, as written on TechNet here:

By default, collection-based migration jobs disable advertisements that migrate to the destination hierarchy. This includes any programs that are associated with the advertisement. When you create a collection-based migration job that contains advertisements, you see the Enable programs for deployment in Configuration Manager 2012 after an advertisement is migrated option on the Settings page of the Create Migration Job Wizard. If you select this option, programs that are associated with the advertisements are enabled after they have migrated. As a best practice, do not select this option and instead, enable the programs after they have migrated when you can verify the clients that will receive them.

Once you have verified all of the Programs, it could be quite time consuming to go through all of the Programs for each Package. Instead, we can leverage PowerShell to list all Packages with a disabled Program, and then enable those Programs. In order to do this, I’ve put together a small script that will help you along the way. Save the script below as Get-CMDisabledPrograms.ps1 in e.g. C:\Scripts on your Primary Site server (or CAS if you’re running a hierarchy).

    List all Disabled Programs of Packages in ConfigMgr 2012
    Use this script to list all of the disabled Programs for each Package in ConfigMgr 2012. This script will also give you the option to enable those Programs.
    Site server name with SMS Provider installed
    Specify this switch only if you wish to enable the disable Programs. Don't specify it if you wish to only list the disabled Programs.
    .\Get-CMDisabledPrograms.ps1 -SiteServer CM01 -Verbose
    Lists all disabled Programs and their Package Name association on a Primary Site server called 'CM01':
    Script name: Get-CMDisabledPrograms.ps1
    Author: Nickolaj Andersen
    Contact: @NickolajA
    DateCreated: 2015-03-10
[parameter(Mandatory=$true, HelpMessage="Site server where the SMS Provider is installed")]
    [parameter(Mandatory=$false, HelpMessage="Enable disabled programs")]
Begin {
    # Determine SiteCode from WMI
    try {
        Write-Verbose "Determining SiteCode for Site Server: '$($SiteServer)'"
        $SiteCodeObjects = Get-WmiObject -Namespace "root\SMS" -Class SMS_ProviderLocation -ComputerName $SiteServer -ErrorAction Stop -Verbose:$false
        foreach ($SiteCodeObject in $SiteCodeObjects) {
            if ($SiteCodeObject.ProviderForLocalSite -eq $true) {
                $SiteCode = $SiteCodeObject.SiteCode
                Write-Debug "SiteCode: $($SiteCode)"
    catch [Exception] {
        Throw "Unable to determine SiteCode"
    # Set SiteDrive variable
    $SiteDrive = $SiteCode + ":"
    # Get current location
    $CurrentLocation = $PSScriptRoot
    # Import ConfigMgr PowerShell module
    Import-Module (Join-Path -Path (($env:SMS_ADMIN_UI_PATH).Substring(0,$env:SMS_ADMIN_UI_PATH.Length-5)) -ChildPath "\ConfigurationManager.psd1" -Verbose:$false) -Force -Verbose:$false
    if ((Get-PSDrive $SiteCode -ErrorAction SilentlyContinue | Measure-Object).Count -ne 1) {
        New-PSDrive -Name $SiteCode -PSProvider "AdminUI.PS.Provider\CMSite" -Root $SiteServer -Verbose:$false
Process {
    # Change location to the Site Drive
    Set-Location $SiteDrive -Verbose:$false
    # Get all Programs
    $Programs = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_Program -ComputerName $SiteServer -Verbose:$false
    if ($Programs -ne $null) {
        foreach ($Program in $Programs) {
            if ($Program.ProgramFlags -eq ($Program.ProgramFlags -bor "0x00001000")) {
                $PSObject = [PSCustomObject]@{
                    "PackageName" = $Program.PackageName
                    "ProgramName" = $Program.ProgramName
                if ($PSBoundParameters["Enable"]) {
                    Write-Verbose -Message "Enabling program '$($Program.ProgramName)' for package '$($Program.PackageName)'"
                    try {
                        Get-CMProgram -ProgramName $Program.ProgramName -PackageId $Program.PackageID -Verbose:$false | Enable-CMProgram -Verbose:$false -ErrorAction Stop
                    catch {
                        Write-Warning -Message "Unable to enable program '$($Program.ProgramName)' for package '$($Program.PackageName)'"
                else {
                    Write-Output $PSObject
    else {
        Write-Warning -Message "No Programs found"
End {
    Set-Location -Path $CurrentLocation

Using the script

For this script I’ve chosen to make use of the ConfigMgr 2012 PowerShell cmdlets, or at least one of them, the Enable-CMProgram cmdlet. For this script to work, you’d have to run it on a machine that has the PowerShell module installed (that means it needs to have the ConfigMgr console installed). The script can either show the disabled Programs only, or it can enable them as well if you give a certain parameter called Enable. In order to demonstrate this, I’ve created two test Packages called Test Package 001 and Test Package 002 in my lab environment. For both of these Packages, I’ve created a single Program that I’ve disabled manually.


List disabled Programs

To list all of the disabled Programs, perform the following steps:

1. Once you have downloaded the script above, open an elevated PowerShell console and browse to where you saved the script e.g. C:\Scripts.
2. Run the following command:

.\Get-CMDisabledPrograms.ps1 -SiteServer CAS01 -Verbose


3. The script outputs a custom PowerShell object showing the name of the Program and Package.

Enabled the disabled Programs

Now that we’ve listed those Programs that are disabled, we can go ahead and try to enable them.

1. Open an elevated PowerShell console and run the following command:

.\Get-CMDisabledPrograms.ps1 -SiteServer CAS01 -Enable -Verbose


2. As you can see, the script will now try to enable those Programs that it found and since we added the Verbose parameter we’ll see the output of each Program that it enabled.

I hope this helps you with migrating Packages and their Programs!


There are no comments.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.