In ConfigMgr 2012 there’s a handy little node on the ‘Monitoring’ panel called ‘Content Status’ under ‘Distribution Status’. This will return all content, whether that is Applications, Packages, OS Images, Drivers etc, and the current distribution status of them.
If you click one of them, you’ll get a nice pie chart showing a summary of Failed, In Progress and Successfully distributed/verified on your distribution points.
You can then click ‘View Status’ and it will give a breakdown of the individual distribution points for that package and a description of their individual status (i.e. awaiting content, failed to validate hash etc). Here’s an example of the ‘In Progress’ and ‘Failed’ nodes for a package recently distributed:
This is great, it shows which distribution points have failed distribution, those that are in progress, and those that have succeeded, but only for that package. What if you wanted to find all packages that were in a specific distribution state, or even those that have a specific status message (i.e. all those that had a content hash mismatch, or all those awaiting prestaged content).
I couldn’t find a built-in report to show me this, or at least not one that replicated the detail that I was seeing in the console, so I decided to write my own.
The SQL below will generate a report similar to that in the screenshot below. It shows the Package ID for the content, the name and type, the target distribution point with site code, the status (Success, In Progress or Failed, and also give the option of ALL), the actual Message as displayed in the console and the number of groups the distribution point is a member of. This can then be exported (e.g. to excel) for further data manipulation and sorting/filtering.
Main SQL Query:
dbo.v_Package.Manufacturer + ‘ ‘ + dbo.v_Package.Name + ‘ ‘ + dbo.v_Package.[Version] AS [Content Name],
REPLACE(dbo.RBAC_SecuredObjectTypes.ObjectTypeName, ‘SMS_’, ”) AS [Content Type],
REPLACE(SMS_DistributionDPStatus.Name, ‘\’, ”) AS [Distribution Point],
WHEN 1 THEN ‘Success’
WHEN 2 THEN ‘In Progress’
WHEN 4 THEN ‘Failed’
END AS [Status],
WHEN 2303 THEN ‘Content was successfully refreshed’
WHEN 2324 THEN ‘Failed to access or create the content share’
WHEN 2330 THEN ‘Content was distributed to distribution point’
WHEN 2384 THEN ‘Content hash has been successfully verified’
WHEN 2323 THEN ‘Failed to initialize NAL’
WHEN 2354 THEN ‘Failed to validate content status file’
WHEN 2357 THEN ‘Content transfer manager was instructed to send content to the distribution point’
WHEN 2360 THEN ‘Status message 2360 unknown’
WHEN 2370 THEN ‘Failed to install distribution point’
WHEN 2371 THEN ‘Waiting for prestaged content’
WHEN 2372 THEN ‘Waiting for content’
WHEN 2380 THEN ‘Content evaluation has started’
WHEN 2381 THEN ‘An evaluation task is running. Content was added to the queue’
WHEN 2382 THEN ‘Content hash is invalid’
WHEN 2383 THEN ‘Failed to validate content hash’
WHEN 2391 THEN ‘Failed to connect to remote distribution point’
WHEN 2398 THEN ‘Content Status not found’
WHEN 8203 THEN ‘Failed to update package’
WHEN 8204 THEN ‘Content is being distributed to the distribution point’
WHEN 8211 THEN ‘Failed to update package’
ELSE ‘Status message ‘ + CAST(SMS_DistributionDPStatus.MessageID AS VARCHAR) + ‘ unknown’
END AS [Message],
SMS_DistributionDPStatus.GroupCount AS [Group Count]
dbo.vSMS_DistributionDPStatus AS SMS_DistributionDPStatus
INNER JOIN dbo.RBAC_SecuredObjectTypes
ON SMS_DistributionDPStatus.ObjectTypeID = dbo.RBAC_SecuredObjectTypes.ObjectTypeID
LEFT OUTER JOIN dbo.v_Package
ON SMS_DistributionDPStatus.PackageID = dbo.v_Package.PackageID
WHERE (SMS_DistributionDPStatus.MessageState = @MessageState) OR (@MessageState = 999)
ORDER BY PackageID ASC
Prompt SQL Query:
WHEN 1 THEN ‘Success’
WHEN 2 THEN ‘In Progress’
WHEN 4 THEN ‘Failed’
END AS [Status],
SMS_DistributionDPStatus.MessageState AS [State Value]
vSMS_DistributionDPStatus AS SMS_DistributionDPStatus
‘ALL’ AS [Status],
999 AS [State Value]
Note: due to the way WordPress converts apostrophes and quotation marks, it’s probable that a direct copy and paste of the SQL will not run properly, please be sure to replace apostrophes with SQL-accepted quotes.
There are some unknown message IDs that I have missed off, I will add them in as and when I come across them. Please feel free to comment with any new ones and I will amend the post accordingly.
Or if there is a table in the ConfigMgr database that contains them all, please let me know.
Our ConfigMgr infrastructure is quite geographically dispersed, with many site offices and site servers in remote parts of the world, often with poor speed LAN and WAN links. This often leads to a massive backlog of active package distributions as packages are being transferred between sites.
ConfigMgr ships with a report to enumerate active package transfers – All active package distributions (Report ID: 136) but this is basically just a query on the v_DistributionPoint, v_Package and v_PackageStatusDistPointsSumm views in the database returning all package records where the distribution state is not 0.
This is great; it’s very helpful to know which packages have been requested to be transferred to the distribution points, but that’s about it. It doesn’t tell you any useful information such as which ones are actively transferring, how much data has been transferred, how much is remaining etc. If any packages get ‘stuck’ they will remain in the report and there’s no way of knowing whether they are still transferring or whether they have fallen into the transfer abyss.
The only place to locate this kind of information is in the sender.log file on the site server sending the package. Looking at the sender.log for more than about 30 seconds during an active package distribution is enough to give me a headache though, never mind trying to interpret it. I therefore decided it would be a good idea to write a simple application that would read in and interpret the sender.log and display all the details in a nice legible format.
The below application is the result of that line of thought. I have made it available in the Downloads section [Link] in case anyone else suffers the same package distribution frustrations that I do, and I pray that Microsoft develop such a utility, or incorporate it into the interface for ConfigMgr 2012.
A while ago now we started noticing a problem with Duplicate Execution Requests being shown in the execmgr.log on clients (“A Duplicate Execution Request is found for program <X>”) . In general, this problem occurs when a client receives a mandatory advert for a program that it already has an execution request for but is yet to run. The client sees that it now has two advert execution requests in the system for the same program and, not wanting to (or being able to) execute one in priority of the other, it logs a Duplicate Execution Request and executes neither.
In our enviornment we use a combination of collection maintenance windows, Wake-on-LAN for out-of-hours deployments, dynamically populated collections based on installed software and recurring adverts. The combination of these, but in particular the latter, led to a number of these events being logged. Here is an example of the sort of thing that was happening:
A mandate exists for all software installations to occur outside of working hours.
- CollectionX contains a dynamic collection of machines with ProductX NOT installed.
- CollectionX has an assigned maintenance window of 01:00 – 04:00 for out-of-hours deployments.
- Hardware inventory is run daily and machines that get ProductX installed, drop from CollectionX.
- AdvertX targets CollectionX with a recurring mandatory daily advert to install ProductX.
- AdvertX is scheduled to run at 03:00 every day.
- MachineX is powered on at 08:30 on Monday by UserX.
- MachineX rececives policy for AdvertX at 08:33.
- AdvertX changes state to waitingServiceWindow.
- MachineX is shut down by UserX at 17:30 on Monday having not run program.
- MachineX is powered on by Wake-On-LAN by the recurring advert at 02:00 on Tuesday.
- MachineX receives a new policy for the recurring advert.
- MachineX has not yet run the policy from Monday that is still pending a service window.
- MachineX therefore has 2 mandatory requests for the same program in the system and cannot run either.
- This process repeats every day thereafter, resulting in the software never getting installed.
There are a number of potential solutions (not all applicable to our scenario):
- Set the advertisement start date/time to the same as the mandatory assignment date/time so that a machine cannot receive the policy before it is set to run it.
- Set the advert to ignore maintenance windows so that if the machine misses the mandatory assignment date/time, it will run the program at the next available moment rather than the next recurrence.
- Turn recurrence off and set the program to always re-run (to include re-installations) so that the advert only goes out once to the desired collection, and then deal with any failures separately.
- Create a maintenance window during the day that would allow installations before UserX logs off (for example, if the reason for the out-of-hours maintenance window is to reduce the load around logon).
The following image shows an example of the behaviour as logged by the execmgr. The advert recurrs every week. In this example, the machine received the policy some time before the 04/01/2011, and was then woken up at 03:00 to install it, whereby it received the second execution request and from there on after, permanently had multiple requests in the system. Note, in the below example there is also a day-time maintenance window starting at 11:00.