SCCM: Copy all task sequence deployments to another task sequence

2 min read

I will show you how to:

  1. Get all the collections that a task sequence is deployed to
  2. Apply a consistent set of deployment settings to those collections for a different task sequence

… using PowerShell.

This ensures consistent settings are used for all deployments and that a task sequence is deployed to all the same collections as per the old task sequence. The biggest benefits are to eliminate human error and not spend time on a repetitive and tedious process.

All of the deployments for the new task sequence will have an assignment date and availability date set 1 year ahead from the point of which you run the below. This ensures the clients don’t immediately action on the new policy or begin downloading the content before the date, giving you time to review/stagger each deployment. I don’t think the clients would start downloading the content because in the below I’ve configured it to be only available to PXE and media, so I could have omitted the assignment schedule config, but I wasn’t 100% sure so I thought better to be safe than sorry. If your task sequence is deployed to be available to configuration manager clients also, I would definitely keep this in.

There’s also an exclusion list that may be useful for you.

It’s not by any means a work of art, but it got the job done.

Perhaps I could write a variant of this that mimics not just all the deployed collections of a given task sequence but also carry over the deployment settings too, rather than blanketing them all with one config.

  1. Update variables $taskSequenceId_old, $taskSequenceId_new and $collectionIds_exclude
  2. Configure New-CMTaskSequenceDeployment to how you want it
Param(
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$taskSequenceId_old,
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$taskSequenceId_new,
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$Date
)

# Example way to create simple datetime object to populate $Date
# $Date = Get-Date -Year 2019 -Month 06 -Day 24 -Hour 12 -Minute 0 -Second 0

try {
    $Date = Get-Date $Date
}
catch { 
    Throw $error[0].Exception.Message
}

$collectionIds = (Get-CMTaskSequenceDeployment -TaskSequenceId $taskSequenceId_old).CollectionId 
$collectionIds_exclude = $null

$CMSchedule = New-CMSchedule -Start $Date -Nonrecurring 

$Comment = "Created by user {0} on {1}" -f $env:username, (Get-Date).ToString()

ForEach ($collection in ($collectionIds | Where-Object { $collectionIds_exclude -notcontains $_ } )) { 
    $HashArguments = @{
        CollectionId                = $collection
        TaskSequencePackageId       = $taskSequenceId_new
        Comment                     = $Comment
        DeployPurpose               = "Required"
        Availability                = "MediaAndPxe"
        UseUtcForAvailableSchedule  = $true
        Schedule                    = $CMSchedule
        RerunBehavior               = "RerunIfFailedPreviousAttempt"
        ShowTaskSequenceProgress    = $true
        SoftwareInstallation        = $true
        SystemRestart               = $true
        InternetOption              = $false
        DeploymentOption            = "DownloadContentLocallyWhenNeededByRunningTaskSequence"
        AllowSharedContent          = $false
        AllowFallback               = $false
        AvailableDateTime           = $Date
        UseMeteredNetwork           = $false
        PersistOnWriteFilterDevice  = $true
        SendWakeupPacket            = $false
    }
    New-CMTaskSequenceDeployment @HashArguments | Out-Null
}
Last Updated on