Redistribute Failed Packages in ConfigMgr

Since the topic of redistributing failed packages is quite often surfacing in larger environments and there are quite a few PowerShell scripts out there to achieve this.

David O´Brien has written a PowerShell script that redistributes all packages that has any state (but successfull) to all DPs. In a larger environment this would be very risky (consider the amount of bandwidth you could potentially consume).

David went about the task by looking up the current state of the SMS_PackageStatusDistPointsSummarizer which has 7 states of a package , and then looping through all packages for all DPs and initiate the operation RefreshNow for each package and DP.

Within SCCM 2012 R2 there seems to be 9 possible states of a package, where a state 7 and 8 seems to be undocumented. State 7 would indicate that the source-files were not reachable for the SCCM 2012 server, and State 8 would indicate that a package validation failed (for any reason).

Quite often the need is more targeted and in particular we are required to only verify a single package or distribution point. As we would go through the console to check the state of a package and look under Content Status to see – it would be easiest to simply trigger a redistribute action for all DPs that are reported as failed. Previously Greg Ramsey released the great tool to start the action Validate All DPs, which can be initiated from any package under Content Status. Great tool! Lets take that one step further and create two additional menus within Configuration Manager console!

Redistribute a package to all DPs where it failed under Content Status

image

image


Param(
[Parameter(Mandatory=$true)]
[String]$SiteSrv,
[Parameter(Mandatory=$false)]
[String]$SiteNamespace,
[Parameter(Mandatory=$True)]
[String]$PackageID
)

$SiteCode = $SiteNamespace.Substring(14)

Write-Host "Checking" $PackageID -ForegroundColor red
Write-host "Will check for Installed Failed status (3) and Validation Failed (8)"
Write-Host ""

$sOpt = New-CimSessionOption –Protocol DCOM
$SiteServerCIM = New-CimSession -ComputerName $SiteSrv -SessionOption $sOpt

$DPs =  Get-CimInstance -CimSession $SiteServerCIM -Namespace $SiteNamespace -ClassName SMS_PackageStatusDistPointsSummarizer -Filter "PackageID = '$($PackageID)' AND (State = '3' OR State = '8')"
if ($DPs -ne $null)
{
$Count = $DPs |measure
Write-Host "There are $($Count.count) failed DPs at the moment."
Write-Host "Press any key to redistribute..."
Write-Host ""
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
foreach ($dp in $DPs) {
Write-Host "Redistributing $($DP.PackageID) to $($DP.ServerNALPath.Substring(12,7))...." -ForegroundColor Green
try {

Get-CimInstance -CimSession $SiteServerCIM -Namespace $SiteNamespace -ClassName SMS_DistributionPoint -Filter "PackageID='$($DP.PackageID)' and ServerNALPath like '%$($DP.ServerNALPath.Substring(12,7))%'" | Set-CimInstance -Property @{RefreshNow = $true}
}
catch {
Write-Host "Failed to redistribute to $($DP.ServerNALPath.Substring(12,7))" -ForegroundColor Red
}

}
Write-Host "Press any key to close window...."
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
else
{
Write-Host "There are no Failed DPs" -ForegroundColor Green
Write-Host "Press any key to close..."
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

}

Remove-CimSession -CimSession $SiteServerCIM 

Create the following XML-file to enable the right-click menu under Content Status. The file should be placed in the following folder;

14214306-59f0-46cf-b453-a649f2a249e1


<ActionDescription Class="Executable" DisplayName="Redistribute to all failed DPs" MnemonicDisplayName="Redistribute to all failed DPs" Description = "Redistribute to all failed DPs" RibbonDisplayType="TextAndSmallImage">
<ShowOn>
<string>ContextMenu</string>
<string>DefaultHomeTab</string>
</ShowOn>
<Executable>
<FilePath>PowerShell.exe</FilePath>
<Parameters>-Executionpolicy bypass -nologo -WindowStyle normal -command "&amp; 'C:\PowerShellScripts\RedistFailed.ps1' '##SUB:__Server##' '##SUB:__Namespace##' '##SUB:PackageID##'" </Parameters>
</Executable>
</ActionDescription>

To enable a second menu under Distribution Point Configuration Status you can use the following script;

image

image


Param(
[Parameter(Mandatory=$true)]
[String]$SiteSrv,
[Parameter(Mandatory=$false)]
[String]$SiteNamespace,
[Parameter(Mandatory=$True)]
[String]$Server
)

$SiteCode = $SiteNamespace.Substring(14)

Write-Host "Checking" $Server -ForegroundColor red
Write-host "Will check for all failed packages (NOT State 0)"
Write-Host ""

$sOpt = New-CimSessionOption –Protocol DCOM
$SiteServerCIM = New-CimSession -ComputerName $SiteSrv -SessionOption $sOpt
try {
$pkgs =  Get-CimInstance -CimSession $SiteServerCIM -Namespace $SiteNamespace -ClassName SMS_PackageStatusDistPointsSummarizer -Filter "ServerNALPath like '%$($Server)%' AND (State != '0')"

if ($pkgs -ne $null)
{
$Count = $pkgs |measure
Write-Host "There are $($Count.count) failed packages at the moment."
Write-Host "Press any key to redistribute..."
Write-Host ""
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
foreach ($pkg in $pkgs) {
Write-Host "Redistributing $($pkg.PackageID) to $($Server)...." -ForegroundColor Green
try {
Get-CimInstance -CimSession $SiteServerCIM -Namespace $SiteNamespace -ClassName SMS_DistributionPoint -Filter "PackageID='$($pkg.PackageID)' and ServerNALPath like '%$($Server)%'" | Set-CimInstance -Property @{RefreshNow = $true}
}
catch {
Write-Host "Failed to redistribute to $($pkg.ServerNALPath.Substring(12,7))" -ForegroundColor Red
}

}
Write-Host "Press any key to close window...."
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
else
{
Write-Host "There are no Failed pkgs" -ForegroundColor Green
Write-Host "Press any key to close..."
$a = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

}

Remove-CimSession -CimSession $SiteServerCIM

}
Catch {
Write-Error "Failed to query $($Sitesrv)"
Remove-CimSession -CimSession $SiteServerCIM
} 

To enable the right-click menu, create a new XML-file under the following folder;

d8718784-99d5-4449-bc28-a26631fafc07

Content;

<ActionDescription Class="Executable" DisplayName="Redistribute all failed Pkgs" MnemonicDisplayName="Redistribute all failed Pkgs" Description = "Redistribute all failed Pkgs" RibbonDisplayType="TextAndSmallImage">
<ShowOn>
<string>ContextMenu</string>
<string>DefaultHomeTab</string>
</ShowOn>
<Executable>
<FilePath>PowerShell.exe</FilePath>
<Parameters>-Executionpolicy bypass -nologo -WindowStyle normal -command "&amp; 'C:\PowerShellScripts\redistfailedpkgstodp.ps1' '##SUB:__Server##' '##SUB:__Namespace##' '##SUB:NAME##'" </Parameters>
</Executable>
</ActionDescription> 

You can download the scripts from here, but you need to copy the XML-files into the folder of the Admin-Console yourself to make them visible.

Location;

c:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\XmlStorage\Extensions\Actions

7 thoughts on “Redistribute Failed Packages in ConfigMgr

  1. Sascha Peter

    Hi, I really like your script.
    Except ;-):
    “PackageID=’$($DP.PackageID)’ and ServerNALPath like ‘%$($DP.ServerNALPath.Substring(12,7))%'”
    If you have a server name with 8 or more characters, than you might not get the expected result.
    Even more, if you have server names like that ‘myserver0001’ and ‘myserver0002’.
    I would replace the part $($DP.ServerNALPath.Substring(12,7)) with that one:
    $(($DP.ServerNALPath.Split(“”)[2]).Split(“.”)[0])
    That fits for me a bit better, hope it will catch all cases.
    But anyway, nice work.

    Reply
  2. Pullela Nagaraju

    Hi,

    1) Redistribute a package to all DPs where it failed under Content Status
    Is it possible to tweak the powershell script to include the DP’s which was not targetted the package instead of only failed packages

    2) to retarged all failed packages under a DP.

    is it possible to tweak this script . Is there any possibility to give input to stop the script after redistributing 100/ 200 packages. Instead if targeting all the packages.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *