shishir kushawaha
Accelerate SCCM task sequence package distribution with an automated and optimized solution
Updated: Mar 3

Suppose you have recently installed a new SCCM distribution point and you have a task sequence that includes several packages, some of which are large (such as images and drivers) and some are small (such as applications and scripts). If you try to distribute all of these packages at once, it could lead to network congestion and slow down the distribution process. On the other hand, distributing the packages manually, one at a time, can be time-consuming and requires you to wait for the previous package to finish before distributing the next one. You may want to take advantage of the weekend scenario as well when most people are not using the corporate network, to distribute the packages more efficiently.
In this scenario, you may be looking for an automated solution that can help you distribute the task sequence packages in a more efficient way, avoiding network congestion and minimizing the time required to distribute all packages to the distribution point.
Find the script here.
Important Note:
It is important to follow a few key steps before running the script.
Firstly, make sure to run the script on a machine that has the SCCM console installed and the appropriate SCCM PowerShell modules loaded.
Additionally, ensure that you are running the script with an account that has the necessary permissions on both SCCM and the SCCM database to avoid any errors or complications during the script execution.
Provide the required information like task sequence packageID, Distribution point server name, Database server, catalog etc. in the script in variable declaration section.
Working of script
The script initiates a connection with MECM database and PowerShell modules.
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName
Once the connection is established, it retrieves the list of packages missing on the distribution point for the provided task sequence package ID. Below is the SQL Query.
SELECT DISTINCT PS.PackageID,p.PackageType,n.SourceSize, PSD.Name FROM v_TaskSequencePackageReferences AS TSR JOIN v_PackageStatus AS PS ON TSR.RefPackageID = PS.PackageID JOIN v_PackageStatusDetailSumm AS PSD ON TSR.RefPackageID = PSD.PackageID JOIN v_Package as P on ps.PackageID = p.PackageID JOIN v_PackageStatusRootSummarizer n ON p.PackageID = n.PackageID WHERE TSR.PackageID = '$tasksequencePackageid' AND PS.PackageID NOT IN (SELECT PS.PackageID FROM v_PackageStatus AS PS JOIN v_TaskSequencePackageReferences AS TSR ON PS.PackageID = TSR.RefPackageID WHERE PS.PkgServer like '%$distributionPoint%') order by n.SourceSize
If above query returns no packages, the script will exit. If it gets the list, it will maintain a record of all packages that require distribution.
During weekdays, the script distributes packages with sizes less than 100 MB, while during weekends, it distributes packages with sizes less than 500 MB at once without any wait time.
$maxSize=100000
$isweekend=(get-date).DayOfWeek.value__ -in (6,0)
if($isweekend){$maxSize=500000}
To distribute the package , It will use the 'Start-CMContentDistribution' commandlet. The script waits for 120*the total number of packages seconds to complete before proceeding further, as the packages take some time to finish distributing.
Start-CMContentDistribution -<packagetypeid> "Packageid or name" -DistributionPointName $distributionpoint
More information on start-CMContentDistribution
The script loops through all packages and tries to distribute the remaining packages while checking whether the package is already distributed or in distribution phase.
select * from v_PackageStatusDistPointsSumm where ServerNALPath like '%$distributionPoint%' and PackageID ='$packageid'
It will wait for a package to finish distributing before proceeding to the next package.
The script distributes packages in order of smallest to largest in size and waits for a shorter time if the package size is smaller, and a longer time if the package size is larger.
The script creates a log file which will record the status of all distribution performed.
Script will end once the loop is finished and will exit.
Learning from this GitHub code
Calling SCCM command-let
Creating connection to SQL Database
Call SCCM SQL query using SqlDataAdapter class
Use DataSet object to collect SQL returned data
Implementing Try-catch