Powershell: Update Distribution Priority for all Task Sequence Packages

Last week we had a most unfortunate incident. One of our domains we managed had 4 of the 5 drives fail in the SCCM Primary’s Disk Array. This domain fed off of our Packages from our SCCM 2007 environment. While most of the OSD media was created at the Central Site, the Task Sequence and Boot media were created and managed on this domain and on this SCCM Primary Server–Pretty much a total loss.

After the hardware was fixed, we updated the site to SCCM 2012 R2 and began rebuilding the OSD process. Since this new SCCM 2012 site needed to replicate content again, the multitude of packages began distributing. During the outage PC Deployments got behind so we needed a quick way to set the priority of all (50 or so) packages to “high” priority so they would distribute first. Rather than going through each package 1-by-1, I knew Powershell could do this quicker than I could 2 packages manually!

A few Cmdlets to familiarize ourselves with:

  • Get-CMTaskSequence – Gets a Config Manager Task Sequence
  • Get-CMPackage – Gets a Config Manager “Classic” Package
  • Get-CMDriverPackage – Gets a Config Manager Driver Package
  • Get-CMOperatingSystemImage – Gets a Config Manager Operating System Image (Not source media)
  • Get-CMBootImage – Gets a Config Manager Boot Image
  • Get-CMOperatingSystemInstaller – Gets a Config Manager Operating System Source Media Package

First thing is to get the Referenced Task Sequence Packages. This can be done with a quick one liner:

(Get-CMTaskSequence -TaskSequencePackageId AAA######).References.Package

From here we have packages to feed into other cmdlets and modify the priority. But there’s one catch…Depending on the type of package (OSImage, Package, Boot Media, Driver Package, etc…) a different cmdlet is required. To work around this, I went to SQL; while i realize this isn’t a *great* workaround, it does the job.

The following SQL Query can be used to easily get the appropriate Package Type:

[System.Data.SqlClient.SqlConnection]$sms = New-Object System.Data.SqlClient.SqlConnection("Data Source=$SqlServerName;Integrated Security=SSPI;Initial Catalog=$SqlTableName")
        [System.Data.SqlClient.SqlCommand]$qry = New-Object System.Data.SqlClient.SqlCommand("SELECT PackageID, Name, PackageType FROM v_package WHERE PackageID = '$packageId'", $sms)
        [System.Data.SqlClient.SqlDataReader]$res = $qry.ExecuteReader()

        while ($res.Read() -eq $true)
            $tmp = @{}
            for ($i=0;$i -lt $res.FieldCount; $i++) {
                $tmp[$res.GetName($i)] = $res.GetValue($i)
            $output += $tmp
            Write-Host "SQL Connection / Query Failed:`n$_"

This will return the results into a very nice object to work with: “$output” in this case. Grabbing a column is easy as well: $output.<columnName> ($output.PackageType).

From here we do a switch statement on the “PackageType” value and update the priority. Free Samples:

Standard Package:

$pkg = Get-CMPackage -Id  -ErrorAction SilentlyContinue
$pkg.Priority = 1 #Set to High Priority
Set-CMPackage -InputObject $pkg -ErrorAction SilentlyContinue

Driver Package

$dp = Get-CMDriverPackage -ID $p -ErrorAction SilentlyContinue
$dp.Priority = 1  #Set to High Priority
Set-CMDriverPackage -InputObject $dp -ErrorAction SilentlyContinue

OS Image Package

$osp = Get-CMOperatingSystemImage -Id $p -ErrorAction SilentlyContinue
$osp.Priority = 1  #Set to High Priority
Set-CMOperatingSystemImage -InputObject $osp -ErrorAction SilentlyContinue

Boot Image Package

$bi = Get-CMBootImage -Id $p -ErrorAction SilentlyContinue
$bi.Priority = 1  #Set to High Priority
Set-CMBootImage -InputObject $bi -ErrorAction SilentlyContinue

Operating System Install Package

$osi = Get-CMOperatingSystemInstaller -Id $p -ErrorAction SilentlyContinue
$osi.Priority = 1  #Set to High Priority
Set-CMOperatingSystemInstaller -InputObject $osi -ErrorAction SilentlyContinue

…And that’s just about the basics of it. After using this script to set all of this up, I expanded to allow either a Task Sequence Package ID or an array of Package ID’s. There are some required items including Read Access to your Config Manager Sql Database, and the 2012R2 console has to be installed on the computer (to use the cmdlets).

See the complete script here: https://onedrive.live.com/redir?resid=3D90B836AD7F51CF%21984

Please let me know if you discover any bugs or any improvements as well! Hopefully this will help you out too!


TPM Not Found After OSD

Today I experienced something frustrating. After applying OSD on some new hardware I attempted to enable BitLocker (TPM+PIN Configuration). To my surprise I received an error that a valid TPM could not be found. Here is my experience and methodology for troubleshooting a missing TPM.

(1) Check WMI
Using Powershell:

Get-WmiObject Win32_TPM -Namespace root/cimv2/security/MicrosoftTPM | Select IsActivated_InitialValue, IsEnabled_InitialValue, IsOwned_InitialValue | Format-List

Usually you’d see something like this:

IsActivated_InitialValue : True
IsEnabled_InitialValue   : True
IsOwned_InitialValue     : True

(2) Check TPM MMC Console
If and when WMI is blank I move on to the TPM MMC console snap-in (tpm.msc).

(3) Check BIOS
At this point I’ve determined the TPM isn’t visible to the Operating System; It happens! On most BIOS you’ll have settings whether or not the Operating System can see and/or manage the TPM Device. Boot into the BIOS, look for a security section and check the TPM Status. In my instance this looked good! TPM was listed as Enabled and Activated. I rebooted back to the OS, repeated steps 1 and 2…both still with the same result.

(4) Vendor Software
When it comes to using vendor-provided installers/software/executables to install drivers, I typically have one rule: I DON’T! In my experience (Dell, Lenovo, HP, Samsung, MS Surface) Plug-n-Play will identify and capture 99% of the hardware without the necessity to install the vendor’s software. In this instance this was an Infineon TPM device so I grabbed the driver CD, extracted and ran. Unless absolutely necessary, I’ll usually use the software to install only the driver where possible. A lot of driver installations will also provide an application that tromps over the built in Windows functions with their own; Bloatware, Crapware…call it what you want, I find it extremely unnecessary. The most infuriating being the old “HP Wireless Assistant” which was a clunky “remix” of Windows’ normal Wireless Connection Menu and tray icon–I found this to be slow, clunky, and down right unnecessary!

Back to the TPM…I launched the “Infineon TPM Professional Package”. I select custom install hoping to see “Driver”. Instead I see a bunch of extra stuff I don’t need and when I went to tell the installer to “not install” a component, I saw this wasn’t an option…It would appear that in order to get an Infineon TPM device seen to the OS, I have to use their crappy application to “manage and control” it. Not gonna happen!

As I contemplated what to do next I eventually did what I probably should have done at step (1)…

Check Device Manager
Usually, device manger would show a TPM device under the “security” category as seen:




Unfortunately, not found! I then started digging in Device Manager and eventually stumbled across “Infineon Trusted Platform Module” under “System Devices”. That explains why the TPM MMC couldn’t find it!


Right-Click -> Uninstall (making sure to check “Delete the driver software for this device”.


Richt-Click –> “Scan for Hardware Changes”

Just like magic, the TPM was detected and placed in the “Security Devices” category. TPM.msc detected it. BitLocker was enabled and there was much rejoicing. I then removed the “tpm driver” from the Driver Package, updated distribution points and all was well!


My hope is that this will save some of you from additional headaches if this comes up in your OSD world.