Powershell, System Center

Force SCCM Distribution Point to refresh failed packages

If a Distribution Point in System Center Configuration Manager has failed packages it probably has a cause and resending the packages might not be the right solution to the problem.

But I had the need to resend all failed packages on a distribution point and I was in no mood to click around in the GUI so I investigated the WMI classes listed on MSDN: http://msdn.microsoft.com/en-us/library/hh949540.aspx

First of all, what I am looking for is packages on a certain distribution point. These are listed in the class SMS_PackageStatusDistPointsSummarizer documented here: http://msdn.microsoft.com/en-us/library/hh949126.aspx

The class has a Property called State with the following states available:

0INSTALLED
1INSTALL_PENDING
2INSTALL_RETRYING
3INSTALL_FAILED
4REMOVAL_PENDING
5REMOVAL_RETRYING
6REMOVAL_FAILED

For starters I filtered the packages after Status being 2 or 3 but there is no obvious property containing the name of the Distribution Point, only the property ServerNALPath.

After some more digging on MSDN I found the WMI class SMS_DistributionPointInfo which can be used to retrieve the Name and the ServerNALPath for a distribution point. WIN!

So for starters, get the Distribution Point info:

On the first row I use the operator ‘Like’ which in WQL supports wildcarding by using “%” and regex-like syntax (more on that to come).
On the second row I use a trick to return the result in an array, that is what the @() is all about. This way I get the property Count on $DistributionPoint even if the query only returns one item.

Then I need to find all failed or retrying packages in that DistributionPoint. First I tried something like this:

But wait, that gives me an Error stating:

Get-WmiObject : Invalid query “Select PackageID From SMS_PackageStatusDistPointsSummarizer Where ServerNALPath Like ‘[“Display=\SERVER01.
lab.lcl”]MSWNET:[“SMS_SITE=S01″]\SERVER01.lab.lcl’ AND (State = 2 OR state = 3)”
At line:1 char:23
+     $FailedPackages = Get-WmiObject -Namespace “rootSMSSite_$SiteCode” -Query  …
+                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

Problem is that the ServerNALPath Contains brackets “[]” which tells WQL to look for one of the chars between the brackets and that won’t find what I want. The solution to this is to surround the [-char with brackets like this: “[[]” telling WQL to look for any on the chars “[“, which is just one char. Since the opening bracket wont be interpreted by WQL the closing bracket “]” will also be ignored. The next problem is that backslash “” is an escape character telling WQL that the next character should be interpreted literally and not as a special character, meaning that \ will translate to only . To solve this we’ll also have to escape each with a .

Both of these operations is easily done in PowerShell by using the replace operator on the $ServerNalPath:

$ServerNalPath = $DistributionPoint.NALPath -replace “([[])”,'[$1]’ -replace “(\)”,’$1′

This will make my $ServerNalPath look like this:

[[]”Display=\\SERVER01.lab.lcl\”]MSWNET:[[]”SMS_SITE=S01″]\\SERVER01.lab.lcl
This looks a bit strange, but it will make my query execute without errors. Now I just have to loop through each of the failed packages and set the property “RefreshNow” to True and call the method Put to apply my new setting:

 

This will tell System Center Configuration Manager that the packages should be refreshed now.

For your convenience I’ve posted the script on TechNet Gallery:

http://gallery.technet.microsoft.com/Force-SCCM-Distribution-5c243aee