A common problem in SCCM is Package 'in progress' in some Distribution Points
Here some of errors we can find and that never been distributed
"2335" = "Distribution Manager instructed Scheduler and Sender to send package "PRI00123" to child site "SEC".
"2372","The content files for package "PRI00123" have not yet arrived from the source site PRI. Distribution Manager will try again later to distribute the content."
"2380","Start to evaluate package "PRI00123" on distribution point "["Display=\\MYCOMPUTER.mydom.net\"]MSWNET:["SMS_SITE=PRI"]\\MYCOMPUTER.mydom.net\"
"30010","User "MYDOM\myuser" modified a distribution point on \\MYPULLDP.mydom.net at site "SEC - MyCompany - SEC Secondary Site" for a package with package ID PRI00123."
"Informational"
As you can see below in \Monitoring\Overview\Distribution Status\Content Status in this "Software Update Package" example, a lot of targeted are "pending"
Here we can see there is 2315 targeted Distribution Point and 219 pending since at least 5 days
Solution 1
You try to redistribute a package (manually it is "\Administration\Overview\Site Configuration\Servers and Site System Roles" then in "Distribution Point" properties then in tab "content". Select package then click on button redistribute )
-> here in my example that failed for these 219 servers (sure I use a script to do it)
Solution 2
You try to "Update Distribution Points" with create a new version for your package (manually for Software Updates it is in \Software Library\Overview\Software Updates\Deployment Packages, right button "Update Distribution Points, same thing for package or any other content)
-> here in my example that failed for these 219 servers
Solution3
You delete Package from your Distribution Point, then after waiting some minutes you "Distribute Content" on the same DP
-> here in my example that work
Things is I surely have other package for some Distribution Point with same problem.
So I decide to find how to find them. Are you ready ?
I first try to find in SQL some related table
I found DistributionJobs table could be a good table
but when I try my query on my Secondary I finally see number found does correspond to this problem:
"2357","Distribution Manager instructed Package Transfer manager to send package "PRI00233" to distribution point "["Display=\\MYCOMPUTER.mydom.net\"]MSWNET:["SMS_SITE=PRI"]\\MYCOMPUTER.mydom.net\" ."
and these Distribution Points found in this query seems just works
Below query to find number of DistributionJobs for a package:
Select count(*)
From [DistributionJobs] as DJ
JOIN [DistributionPoints] as DP
ON DJ.DPID = DP.DPID
WHERE PkgID = 'PRI00233'
For information to see DP name use for example (here secondary XXH have 2 rows with same message):
Select DP.ServerName, DJ.*
From [DistributionJobs] as DJ
JOIN [DistributionPoints] as DP
ON DJ.DPID = DP.DPID
WHERE PkgID = 'PRI00233'
Then I found a Microsoft Article Understanding and Troubleshooting Content Distribution in Microsoft Configuration Manager https://support.microsoft.com/en-ae/help/4000401/content-distribution-in-mcm
in Useful query with a view
-- All Package/DPs in InProgress state for more than 3 days
SELECT distinct DPSD.DPName, DPSD.PackageID, SP.Name, DPSD.MessageState, DPSD.LastStatusTime, DPSD.SiteCode
FROM vSMS_DPStatusDetails DPSD
JOIN SMSPackages_All SP ON DPSD.PackageID = SP.PkgID
WHERE DPSD.LastStatusTime > DATEAdd(dd,-3,GETDate())
AND MessageState = 2
and another interesting article with table https://blogs.technet.microsoft.com/umairkhan/2014/10/02/the-case-of-the-unexplained-the-package-gets-distributed-successfully-but-does-not-show-in-the-console/
select * from PkgServers_G where pkgid = 'PRI00233'
select * from ContentDistributionNotification where pkgid = 'PRI00233'
select * from ContentDistribution where pkgid = 'PRI00233'
So as you can see in my example table ContentDistributionNotification is OK
SELECT count(*)
FROM [ContentDistributionNotification]
WHERE PkgID = 'PRI00233'
(No column name)
2315
Table ContentDistribution is OK too in my example
SELECT count(*)
FROM ContentDistribution
WHERE PkgID = 'PRI00233'
(No column name)
2315
Table PkgServers is OK too in my example
SELECT *
FROM PkgServers_G
WHERE PkgID = 'PRI00233'
Table PkgStatus has not same number BUT perhaps it is normal
JOIN DistributionPoints as DP ON PKGS.PkgServer = DP.NALPath
WHERE ID = 'PRI00233'
(No column name)
2095--
GOOD CATCH
Try testing some Distribution Points I see computer NOT in PkgStatus_G table are those with problems
For example we can see below %17% computer displayed in PkgStatus_G and not %36%
here %36% Distribution Point is 'in progress'
here %17% Distribution Point is 'Success'
So now I give you SQL Query to find ALL Distribution Points with this problem
-- Find Distribution Point 'in progress' with problems
-- by F.RICHARD 2019-01
-- Declare the variables to store the values returned by FETCH.
DECLARE @PackageID varchar(50);
DECLARE @tblResult TABLE (PackageID varchar(50), ServerName varchar(255), SiteCode varchar(10));
DECLARE PackageID_cursor CURSOR FOR
SELECT DISTINCT PackageId
FROM vSMS_DPStatusDetails DPSD
JOIN SMSPackages_All SP ON DPSD.PackageID = SP.PkgID
WHERE 1=1
AND DPSD.LastStatusTime < DATEAdd(dd,-3,GETDate())
AND MessageState = 2
OPEN PackageID_cursor;
FETCH NEXT FROM PackageID_cursor INTO @PackageID
WHILE @@FETCH_STATUS = 0
BEGIN
print @PackageID
-- create temp table after drop
if(OBJECT_ID('tempdb..#TempPkgStatusServerName') Is Not Null)
Begin
Drop Table #TempPkgStatusServerName
End
CREATE TABLE #TempPkgStatusServerName
(
PkgServer Varchar(255)
,ServerName Varchar(255)
,PkgID varchar(50)
);
-- insert data
INSERT INTO #TempPkgStatusServerName
SELECT PkgServer
,ServerName =
CASE
WHEN CHARINDEX('\\', Pkgserver) > 0
THEN SUBSTRING(Pkgserver, CHARINDEX('\\', Pkgserver) + 2, CHARINDEX('"]', Pkgserver) - CHARINDEX('\\', Pkgserver) - 3 )
ELSE
Pkgserver
END
,ID
FROM PkgStatus
WHERE 1=1
AND ID = @PackageID
INSERT @tblResult
SELECT
PackageID, DPSD.DPName, DPSD.SiteCode
FROM vSMS_DPStatusDetails DPSD
JOIN SMSPackages_All SP ON DPSD.PackageID = SP.PkgID
WHERE 1=1
AND DPSD.LastStatusTime < DATEAdd(dd,-3,GETDate())
AND MessageState = 2
AND PackageID = @PackageID
AND DPSD.DPName NOT IN
(
SELECT TMPTABLE.ServerName FROM #TempPkgStatusServerName as TMPTABLE
)
-- drop temp table
Drop Table #TempPkgStatusServerName
-- next data
FETCH NEXT FROM PackageID_cursor INTO @PackageID
END
CLOSE PackageID_cursor;
DEALLOCATE PackageID_cursor;
SELECT PackageID, ServerName, SiteCode FROM @tblResult
And as I am really a nice guy I give the same in powershell
below
<#
.Synopsis
SCCM_Get-Problematic-SMS_PackageStatus.ps1
.EXAMPLE
.\SCCM_Get-Problematic-SMS_PackageStatus.ps1
.NOTES
Version: 1.0
Author: Franck RICHARD
Creation Date: 2019-01
Purpose/Change:
#>
[cmdletbinding()]
Param(
[String]$CM="mycm.mydomain.net"
,[String]$PrimarySiteCode="XXX"
)
# *************************
# For Time checking
$MeasureCommandBegin = Get-Date
$strCurDir = Split-Path -parent $MyInvocation.MyCommand.Path
$strScriptName = $MyInvocation.MyCommand.Name
$date_for_file = Get-Date -format "yyyy-MM-dd_HHmmss"
$strSaveFile = $strCurDir + "\" + $date_for_file + "_" + $Hostname + "_" + $strScriptName.replace(".ps1",".csv")
# Get all packages
#
Write-Host "Get all Packages"
[HashTable] $hashPackageByPackageID = @{}
$arrSMS_PackageBaseclass = @(Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -Class SMS_PackageBaseclass -ComputerName $CM)
Foreach ($SMS_PackageBaseclass in $arrSMS_PackageBaseclass) {
if (!$hashPackageByPackageID.ContainsKey($SMS_PackageBaseclass.PackageID) ) {
$hashPackageByPackageID[$($SMS_PackageBaseclass.PackageID)] = $SMS_PackageBaseclass
}
}
Write-Host "Nb Package : $($hashPackageByPackageID.count)"
# Date Min = date LastStatusTime
#
$Nbdays = 3
$DateMin = (Get-date).AddDays(-$Nbdays)
# Get all SMS_DPStatusDetails 'in progress'
#
Write-Host "Get all SMS_DPStatusDetails 'in progress' "
$Query = @"
SELECT * FROM SMS_DPStatusDetails as DPS
WHERE DPS.MessageState='2'
AND DPS.LastStatusTime <= '$DateMin'
AND DPS.PackageID <> ''
"@
$arrSMS_DPStatusDetails = Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -ComputerName $CM -Query $Query
Write-Host "Nb SMS_DPStatusDetails 'in progress' > $Nbdays days: $($arrSMS_DPStatusDetails.count)"
# Get Distinct PackageID 'in progress'
#
Write-Host "Get Distinct PackageID 'in progress' "
[HashTable] $hashDistinctPackageID = @{}
Foreach ($SMS_DPStatusDetails in $arrSMS_DPStatusDetails) {
if ($hashPackageByPackageID.ContainsKey($SMS_DPStatusDetails.PackageID) ) {
if (!$hashDistinctPackageID.ContainsKey($SMS_DPStatusDetails.PackageID) ) {
$hashDistinctPackageID[$($SMS_DPStatusDetails.PackageID)] = 1
}
}
}
Write-Host "Nb Distinct PackageID : $($hashDistinctPackageID.count)"
# For each PackageID we get
#
[ARRAY] $arrInfos=@()
Foreach ($PackageID in $hashDistinctPackageID.Keys) {
$SMS_PackageBaseclass = $hashPackageByPackageID[$($PackageID)]
Write-Host "-> Check PackageID $PackageID 'in progress' ($($SMS_PackageBaseclass.Name))"
# Get All SMS_PackageStatus for $PackageID
#
Write-Host "Get All SMS_PackageStatus for $($PackageID) "
[HashTable] $hashPackageIDByPkgServer = @{}
#$Query = @"
#SELECT * FROM SMS_PackageStatus WHERE PackageID='$PackageID'
#"@
#$Query = @"
$Query = "SELECT PkgServer FROM SMS_PackageStatus WHERE PackageID='$PackageID'"
#"@
$arrSMS_PackageStatus = Get-WmiObject -Namespace "root\SMS\Site_$PrimarySiteCode" -ComputerName $CM -Query $Query
Foreach ($SMS_PackageStatus in $arrSMS_PackageStatus) {
$ServerNALPath = $SMS_PackageStatus.PkgServer
# ex: ["Display=\\MYCOMPUTER.mydom.net\"]MSWNET:["SMS_SITE=XXX"]\\MYCOMPUTER.mydom.net\
# -> MYCOMPUTER.mydom.net
$PkgServer = $ServerNALPath.Substring($ServerNALPath.LastIndexOf("]")+3).Trim("\")
if (!$hashPackageIDByPkgServer.ContainsKey($PkgServer) ) {
$hashPackageIDByPkgServer[$($PkgServer)] = 1 # $SMS_PackageStatus.PackageID
}
}
# Check if exist in SMS_DPStatusDetails but NOT in SMS_PackageStatus
#
Write-Host "Check if exist in SMS_DPStatusDetails but NOT in SMS_PackageStatus for $($PackageID) "
Foreach ($SMS_DPStatusDetails in $arrSMS_DPStatusDetails) {
if ($SMS_DPStatusDetails.PackageID -eq $PackageID) {
if ($hashPackageByPackageID.ContainsKey($SMS_DPStatusDetails.PackageID) ) {
if (!$hashPackageIDByPkgServer.ContainsKey($SMS_DPStatusDetails.DPName) ) {
$custObj = New-Object -TypeName psobject
$custObj | Add-Member -MemberType NoteProperty -Name PackageID -Value $SMS_DPStatusDetails.PackageID
$custObj | Add-Member -MemberType NoteProperty -Name DistributionPoint -Value $SMS_DPStatusDetails.DPName
$custObj | Add-Member -MemberType NoteProperty -Name SiteCode -Value $SMS_DPStatusDetails.SiteCode
$arrInfos += $custObj
}
}
}
}
}
Write-Host "Write file with all package informations"
$arrInfos | Export-Csv -NoType -Path $strSaveFile -Delimiter ";"
#$strContent | Out-File -FilePath "$strSaveFile
$MeasureCommandEnd = Get-Date
$MeasureCommandTime = $MeasureCommandEnd - $MeasureCommandBegin
Write-host "Script Executing in $($MeasureCommandTime.Day) day(s) $($MeasureCommandTime.Hour) hour(s) $($MeasureCommandTime.Minutes) minute(s) $($MeasureCommandTime.Seconds) second(s) "
[EDIT 2019-01-21]
Please here SCCM_AddPackageToDP.ps1 (https://franckrichard.blogspot.com/2019/01/sccm-powershell-script-to-add-package.html) powershell solution to remove and add content and resolve this problem
.\SCCM_AddPackageToDP.ps1 -CM mycm.mydomain.net -PrimarySiteCode XXX -ForceToDeletePackageBeforeIfExist -ImportFilePath file_generated_by_SCCM_Get-Problematic-SMS_PackageStatus.csv
1 comment:
sccm online training hyderabad
sccm online course
Post a Comment