Matching ConfigMgr Software Updates to a Deployment Package with PowerShell

The content side of Software Updates in ConfigMgr can be a bit confusing. Unlike Packages and Applications, in which the entirety of the content is downloaded to the local cache, when the client downloads Software Updates it only downloads the individual update.  As such, the Deployment Package is nothing more than a means of getting groups of individual updates out onto the Distribution Points to make them available for download. 

The Deployment Packages are created independently of the Software Update Groups though, and from the client side it makes no difference whether the individual Software Updates in a SUG are in a single Deployment Package or scattered across two dozen as long as they’re available on a Distribution Point for that client’s boundary.  Suffice it to say there isn’t an obvious one-to-one correlation unless you’re extremely organized and disciplined in your SUG and Deployment Package naming, and there’s no simple way to see which Deployment Package an individual Software Update is part of.

If a client can query for the content location of an individual Software Update, then obviously that information is stored somewhere…we just need to find it. 

Enter WMI Explorer. There are three classes that contain the information we need:

SMS_SoftwareUpdate – This contains info on all of the Software Updates

   

SMS_AuthorizationList – This contains info on the Deployment Packages

   

SMS_CIRelation – This contains the relationship between the two

   

Using these three classes, we can tie together the Software Updates with the Deployment Packages with just a little PowerShell.  Assuming we set a variable $update to the text we’re looking for, let’s match it to its Deployment Package with the following:

$update = “KB2757638″

Get-WmiObject -Namespace root/SMS/site_$($SiteCode) -ComputerName $SiteServer -Query “select ALI.LocalizedDisplayName,UPD.LocalizedDisplayName from SMS_AuthorizationList ALI inner join SMS_CIRelation CIR on ALI.CI_ID = CIR.fromCIID inner join SMS_SoftwareUpdate UPD on UPD.CI_ID = CIR.toCIID WHERE UPD.LocalizedDisplayName like ‘%$update%’” | foreach-object {write-host $_.UPD.LocalizedDisplayName => $_.ALI.LocalizedDisplayName}

The returns will obviously depend on how specific you are with your search text as there are often multiple individual Software Updates for a given KB article for example, but this gives you the direct correlation you want.

You also have the option of tying in the source path for the Deployment Package by bringing in a fourth class: SMS_SoftwareUpdatesPackage.

By tying back to the Authorization List entry, we can bring the source path in to our results:

Get-WmiObject -Namespace root/SMS/site_$($SiteCode) -ComputerName $SiteServer -Query “select ALI.LocalizedDisplayName,UPD.LocalizedDisplayName,PKG.PkgSourcePath from SMS_AuthorizationList ALI inner join SMS_CIRelation CIR on ALI.CI_ID = CIR.fromCIID inner join SMS_SoftwareUpdate UPD on UPD.CI_ID = CIR.toCIID inner join SMS_SoftwareUpdatesPackage PKG on ALI.LocalizedDisplayName = PKG.Name WHERE UPD.LocalizedDisplayName like ‘%$update%’” | foreach-object {write-host $_.UPD.LocalizedDisplayName => $_.ALI.LocalizedDisplayName “(” $_.PKG.PkgSourcePath”)”}

 

Why didn’t we just tie it to this class in the first place since it has more information? Because it doesn’t contain the CI_ID for the Software Update so there’s no way to tie together a direct reference.  There is a way to tie together the Authorization List and the Software Updates Package using the name but there is a bit of a caveat: the Authorization List entry is created at the time the Deployment Package is first created and is static whereas the Software Updates Package entry is dynamic.  So, if you happen to change the name of your Deployment Package later, you have no way to tie the two together and you’ll need to use the name from the Authorization List entry to check the property of the Deployment Package in the console.

The lack of a more direct way to see the Deployment Package and download location of individual updates is definitely a shortcoming of the ConfigMgr 2012 console, and hopefully the team will be kind enough to at least add this type of tie-back to the ConfigMgr 2012 PowerShell module.

 

email

Written by , Posted .
  • Christophe

    Nice !
    Here is how i was performing this search:
    http://sccmosd.blogspot.fr/2014/01/powershell-script-to-find-in-which.html
    your method is better

  • Roger Truss

    sweet! now is there a way to batch run this puppy? Using only KB as a search would more than likely kill it but if there is a way to tell it to skip those that are not downloaded or only include those that are expired, and then create a csv file or something like that. Essentially I am looking to run some cleanup on my updates and we have loads of deployments and this tool would help immensely in know what is where.