Offline Updates in ConfigMgr Task Sequences with MDT
As many folks know, there is a known issue with Software Updates in Windows 7 Task Sequences: http://blogs.technet.com/b/configmgrteam/archive/2011/01/28/known-issue-install-software-updates-action-hangs-on-windows-7.aspx. There is no official word of a fix for this issue which by most accounts happens for a number of seemingly different reasons once the number of updates to be applied gets “large” — although bafflingly enough, it doesn’t always happen. I have seen different numbers for just how many “large” is but I don’t think that there is an official definition. From what I know, the actual issue is quite complicated which implies that the fix will be also.
So, what do we do in the meantime? At a recent client engagement, I faced this exact question and initially had no good answer. I had done the handful of “normal” things which are outlined here: http://coreworx.blogspot.com/2010/08/configmgr-install-software-updates-task.html. (Note that the XML response size was increased by default in WSUS SP2 so that can be eliminated.) No dice though. I even tried a couple of other undocumented tricks without any luck. Then it hit me: Install Updates Offline from MDT. After some fiddling and help — because there is almost zero documentation on it — from Chris Nackers (who hadn’t actually ever used this task either) I got it working. So here’s my FAQ for MDT’s Install Updates Offline.
What does the Install Updates Offline task do?
It installs all applicable updates from a specified Update Package to a deployed Windows 7 (or Vista) image. Updates must already be in an Update Package and of course the Update Package must be available on an accessible DP.
Where in a task sequence does the Install Updates Offline task go?
It goes in the PostInstall group right before the Configure task in an MDT task sequence. Yes, it has to be an MDT task sequence.
Can I use multiple Install Updates Offline tasks?
Yes. This will allow you to install updates from multiple Update Packages as only one Update Package can be chosen per Install Updates Offline task.
Where do the updates come from?
They come from the specified Software Update Package configured in Configuration Manager. They do not come from WSUS or any other update source: that’s not the purpose of this task.
What does this task actually do?
Like all things MDT, there is a script behind this task: ZTIPatches.wsf. The script is relatively straight-forward. Here’s an outline of what it does.
Determine architecture of OS being deployed
Check to make sure we’re in the proper phase of deployment
Find the unattend.xml file
Create a packages.xml file containing info about each identified update in the specified Update Package
Copy the updates detailed in packages.xml from the DP to a local (temporary) location
Add the updates from packages.xml to the servicing section of unattend.xml
Run pkgmgr to install the updates designated in the unattend.xml to the offline image already applied to the system
Can I use an Install Updates Offline task in a build and capture task sequence?
No. A build and capture task sequence does not directly apply an image to deploy Windows, it uses Setup.exe. ZTIPatches was specifically written to apply updates to a deployed image. Even though there is an image at the heart of Windows setup, this image is not truly deployed to a system until setup.exe runs during the Setup Windows and ConfigMgr task.
Why is this script using pkgmgr instead of DISM?
pkgmgr was replaced by DISM in Windows 7 and WAIK 3.0 but to maintain backwards compatibility, they left a “stub” executable in its place that simply calls DISM passing it the appropriate properties. The syntax of DISM is completely different from pkgmgr so it would be more than a trivial task to convert the many tools and scripts that use pkgmgr to use DISM. Instead, they did the hard work by creating a new pkgmgr that redirects the work to DISM thus maintaining compatibility with anything that uses pkgmgr.
What if my Update Package has updates not applicable to the OS being deployed?
ZTIPatches first filters out any updates not contained in a CAB file. It then looks for a special file in the CAB called update.mum. This file is part of the Component-Based Servicing (CBS) architecture that was introduced in Windows Vista. This in an XML file that contains metadata about the update contained in the CAB file and its applicability; if this file does not exist, the CAB file is not considered any further. The script uses this metadata to first populate packages.xml and then in turn the unattend.xml.
DISM, which is the primary tool for interacting with the CBS subsystem, then uses this information to determine applicability and only install those updates which it determines are applicable. I’m sure that the process that DISM goes through in conjunction with the CBS subsystem is a little more involved, but there isn’t a whole lot of documentation on it and it isn’t any relevant anyway — all that is important now is that it ensures applicability before installing the update. Here’s a couple of links describing Deployment Image Servicing and Management:
To prove this (to you and myself)
I created a Windows 7 deployment task sequence that included an Install Updates Offline task specifying an Update Package containing a Windows XP update, a Windows Vista Update, and a Windows 7 update.
The Windows XP update is actually easy to rule out right away because it is not a CAB file, it is an EXE and so will not even be considered by ZTIPatches. To my knowledge, all Windows XP updates are packaged as EXEs and thus won’t be considered or copied to the local system.
Unfortunately, the packages.xml file gets deleted by ZTIPatches so I couldn’t grab it, but it is easy enough to check the unattend.xml file for the update information also. Here is the servicing element after the Install Updates Offline task in the task sequence ran:
<assemblyIdentity name="Package_for_KB2524375" version="22.214.171.124" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral"/>
<assemblyIdentity name="Package_for_KB2524375" version="126.96.36.199" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral"/>
Notice that it contains our two updates, each with its own version though.
Finally, we can check the log file for pkgmgr (ZTIPatches is kind enough to tell pkgmgr to create one). Here are the relevant sections for each update.
CBS Appl: Evaluating package applicability for package Package_for_KB2524375~31bf3856ad364e35~amd64~~188.8.131.52, applicable state: Absent
DISM DISM Package Manager: PID=764 Error in operation: the package is not applicable. (CBS HRESULT=0x800f081e) – CCbsConUIHandler::Error
CBS Appl: Evaluating package applicability for package Package_for_KB2524375~31bf3856ad364e35~amd64~~184.108.40.206, applicable state: Installed
DPX Started DPX phase: Resume and Download Job
DPX Started DPX phase: Apply Deltas Provided In File
DPX Ended DPX phase: Apply Deltas Provided In File
DPX Ended DPX phase: Resume and Download Job
CBS Extracting all files from cabinet \\?\C:\_SMSTA~1\Packages\PACKAG~2\WINDOW~1.CAB
As expected, the Windows Vista update was determined to be not applicable and skipped while the Windows 7 update was applied to the image. Note that the log file has a lot more details than that shown above. I didn’t try explicitly, but if the update is already included in the image, I would expect a very similar result as the CBS system was built specifically for this task.
Just to reinforce all of the above, here’s a statement directly from TechNet: “The applicability of each package will be checked. If the package is not applicable to the specified image, you will receive an error message.”
What are the benefits of using the Install Update Offline task?
The initial benefit is the reason I started using this task in the first place — because the normal Install Software Updates task has issues in a Windows 7 task sequence.
In my usage, it also appears to be faster. I won’t quantify that because it really depends on so many different factors. It is a much simpler process than online software updates though with a lot fewer moving parts. Also, because it is doing an update of an offline image, it doesn’t have to worry about files in use or the other complexities of updating an online, running OS.
Including updates in the actual image is still a good thing because it reduces deployment time and ensures that the deployed OS is updated before it goes live. If deployment time is not a concern, then using the Install Updates Offline task during a deployment task sequence can completely replace the overhead of maintaining updates in your image(s) because it applies updates before the OS is live.
Even if you do continue to add updates to your image(s) periodically, there will always be a delta between what is in your image and what is current (unless you fanatically update your image(s) every month). If you do this using a normal Install Software Updates task, there is a short period of time when the deployed OS is on the network and not fully patched because this is an online updating mechanism. This may (or may not) be a big deal to you but using the Install Updates Offline task completely eliminates this window because the updates are installed before the OS goes live.
Another benefit is that because you directly specify the Update Package in the task sequence, the task sequence process will ensure that the Update Package is available on an accessible DP before the task sequence kicks off just like it does with other directly referenced packages. It can’t do that with an Install Software Updates task because it doesn’t know which packages it will use until the task actually executes. And, although I didn’t try it, this also means that you should be able to use this task in stand-alone media.
Finally, using this task you also no longer have to worry about update targeting either; i.e., it doesn’t matter if the update is made available to the target system via an Update Deployment. It just applies every applicable update in the package regardless of Update Deployments.
What about non-OS (like Office) and third-party updates?
Unfortunately no, Install Updates Offline can only install Windows OS updates because of its
DISM roots. That shouldn’t be a big deal though because you can still use an Install Software Updates task to apply these types of updates. Application vulnerabilities only manifest themselves when an application is running so there is no way to exploit them during an OS deployment.
The best scenario though is to only deploy applications that are fully updated in the first-place. This is quite easy with Office (2007 & 2010) because all you have to do is drop the MSPs in the Updates folder and you’re done. It may or may not be as easy with other applications, but you should at least consider it.
What are the key files in this process
|ZTIPatches.wsf||MDT scripts folder||The main script that drives this entire task|
|packages.xml||c:\_SMSTaskSequence||Transient file for storing information extracted about each identified update|
|unattend.xml||various||The main file for driving an unattened Windows 7 (or Vista) installation|
|ZTIPatches.log||various||The main log file for ZTIGather.wsf|
|BDD_pkgmgr.log.txt||c:\_SMSTaskSequence\SMSOSD\OSDLOGS||The log file for the execution of pkgmgr called by ZTIPatch.wsf|
This is a great task that I wish I would have started using a long time ago; this one single task makes MDT worth installation to me.