10 Tips for a More Successful Windows Image Build & Capture
In a recent build and capture (b&c) task sequence for ConfigMgr 2012 R2 that I was helping a customer with, I decided it was worthwhile to list the top things that can be overlooked. If these are done prior to beginning the process, then it can help to shorten and troubleshooting time involved. Also, be sure to see my tips for installing apps during OSD.
- Create an IP address range for content boundaries. When doing a b&c, it is a best practice to not join the system to the domain. So if AD Sites are used for the boundaries, then content cannot be found. To workaround this, add a IP address range boundary for the subnet of the virtual system.
- In task sequence step “Setup Windows and Configuration Manager”, include entry “SMSMP=SiteMPServerFQDN”. Example FQDN: CM1.contoso.com.
- Include installation of the latest cumulative update that is installed on the primary site. The easiest trick for ensuring the latest CU is installed during OSD is to do:
- Copy the hotfix install package from “C:\Program Files\Microsoft Configuration Manager\hotfix\KBxxxxxx\Client\” into “C:\Program Files\Microsoft Configuration Manager\Client\hotfix\KBxxxxxx\”.
- In the task sequence step “Setup Windows and Configuration Manager”, include the line “PATCH=’%_SMSTSMDataPath%\OSD\PkgID\hotfix\KBxxxxxx\x64\patchKBinstallname.msp’. Note that the path x64/i386 will need to be updated based upon the target OS.
- ConfigMgr boot media (.iso, USB, etc.) has been configured to allow unknown computers.
- Use the offline servicing functionality to pre-inject / install any Windows and .NET Framework 3.5.x security updates. Doing this to the original Windows image that was imported into the primary site will reduce the deployment time for the b&c. Note that if you are deploying Win7 Hotfix Rollup 1 (KB2775511), it can be helpful to add it into the list for Software Updates (see http://blogs.technet.com/b/brandonlinton/archive/2013/03/13/how-to-deploy-phantom-updates-with-system-center-configuration-manager.aspx).
- Prepare for Software Updates (e.g. MS security updates)
- Use multiple Install Software Updates steps. I like to use one immediately after installing core MS software (newer versions of .NET, MSXML, PowerShell, etc.) and then use two more at the very end of the task sequence.
- Optional: Create a script to which associates Microsoft Office with the Windows update agent so that those patches can be installed.
- Implement fixes and workarounds for installing packages and applications.
- Set additional task sequence variables to prevent “Error 80070002”. This is outlined in a TechNet support tip blog post, but impacts more than just MDT.
- SMSTSDownloadRetryCount = 5
- SMSTSDownloadRetryDelay = 15
- Configure the Windows image to be able to “run from the server”. In this way, the image does not need to download to the disk then finally extract … thereby causing a longer delay and more fragmentation. To do this:
- On the properties of the image, go to the Data Access tab and select the option to “copy the content in this package to a package share on distribution points”.
- In the task sequence’s step for Apply Operating System, go to the Options tab and select “Access content directly from the distribution point”.
- Configure the distribution point to allow anonymous connections.
In general the above items should help you to be more successful when doing an OSD image b&c. So that it’s not left unsaid, the below items could also prove useful.
- Setup the Network Access Account for the ConfigMgr primary site. For security, ensure that the account is a low rights domain user with a complex password and not an account with extended access rights to any systems on the network.
- Deploy the task sequence to All Unknown Computers. In this way an record of the ConfigMgr client will not need to be created first and added into a special collection.
Automatically Add Required Patches to Pkg
On a recent ConfigMgr 2012 engagement, I was migrating a customer from using standalone WSUS to CM12 Software Updates. They requested to have the ability at ‘bypassing’ the steps required for downloading and distributing patches to the Distribution Points (but still desired to approve the patches before deployment). To be clear, this ONLY for adding patches into a package automatically. Other than for AV updates, it is never recommended to automatically approve and distribution patches.
Using CM12’s Automatic Deploy Rules (ADR), I was able to set up a process which would auto detect and distribute required patches to DPs within their organization so that they could rapidly deploy updates. To do this:
- Create an “empty” collection that will NEVER contain any members
- If you do not have one already, create an “All Distribution Points” group with all DPs
- Create a new ADR in the console
- General page: add an appropriate name, target the EMPTY collection, and add the patches to an existing Software Updates Group, and deselect “Enable this rule…”
- Deployment Settings page: use defaults
- Software Updates page: add filters for
- Evaluation schedule page: Run the rule after any Software Updates sync (if only doing once per day) or set to run only overnight
- Deployment schedule page: for safety, set both the availability and deadline for 12 months in advance
- User Experience page: use defaults
- Download Settings page: select both options to “Do not install”
- Deployment Package page: create a new package or use an existing package
- Distribution Points page: add your “All Distribution Points” group
- Complete the remainder of the wizard with your desired patch download and language preferences
- After completion of the ADR, run it to ensure that patches are downloaded
- Open the deployment which was created to ensure it is disabled
Then you’re good to have them ready for approval in the future!
CM12 Software Updates Gotcha
An added feature to ConfigMgr 2012 is the ability to directly deploy software updates without them being a deployment group. This can result in a “gotcha” moment when update are incidentally deployed to systems. This situation occurred to me recently when IE9 was deployed to a collection (fortunately non-mandatory!) but I could not find that update in any deployment group. If it has been deployed as part of many updates, then this would have never occurred and I could have easily removed the update.
The way to get yourself into this predicament is by doing the following. Note: this is just a lesson, don’t actually do this in production!
- In the console, navigate to Software Library > Software Updates > All Software Updates
- Select a single updates to install
- Select “Deploy” on the wunderbar
- Note that in the first page of the wizard, it LOOKS like you’re adding updates into a software update group.
- Finish the wizard with whatever settings (please don’t make this a Required install, lest you screw yourself)
Now go into node Software Update Groups. Where is the deployment group that was supposed just created? It isn’t there!! To then delete the deployment, find an individual update, go to the Deployment “tab” and delete the deployment. Note how the update group says “Individual”
To prevent this from accidentally occurring to you, a general rule of thumb is to add the update(s) to be installed into a new or existing Software Update Group and then deploy that group to a collection.
Migration Strategy for WSUS to SCCM & Software Updates
The key to protecting an environment from incidental patching during a transition from using WSUS to using SCCM with Software Updates is to reconfigure three group policies which have an impact on SCCM software updates.
- Specify intranet Microsoft update service location: the SCCM client sets this as a local GPO pointing to the SCCM\WSUS server. (Note: It could be possible to set these values as domain GPO, but the trouble is that there are two SCCM servers acting as WSUS for their clients, so managing multiple GPOs would be more pain than value.)
- Configure Automatic Updates: this will set the automatic update settings. I’ve seen that once this was turned off in GPO, it kept the default to automatically download and install updates. It is possible to set this to Disabled without impacting SCCM’s delivery of security updates, but it will impact delivery of FEP definition updates. With SCCM 2007 and FEP 2010, in order for definition updates to automatically install, auto approval actually gets set in WSUS itself, so therefore disabling AU would mean no delivery of those updates and need to be re-enable in the future.
- The final GPO is just configuration of the Automatic Updates windows service. If the GPO disables the service, then no updates will work. A forced enable of the service through GPO would be a good thing.
A route for the WSUS to SUP migration could look like this:
- Configure Automatic Updates set to Disabled
- Enable the AU windows service
- Optional: continue to disable user’s ability to get updates themselves from Windows Update
- Set all other WSUS related GPOs to not configured
- Updated 6/14 (Tip from Kevin in Denver) – remove any Domain Group Policy setting pointing to a location for Automatic Updates. This needs to be left“Unconfigured” in order for SCCM’s SUP to work correctly.
- Deploy the SCCM client upgrade/changeover
- Later, as part of a FEP migration, use GPO to configure automatic updates to be enabled (since that will be needed for automating the definition update releases)
IIS Bindings and SCCM Software Updates
You may be asking, what does IIS bindings have to do with SCCM software updates. Well, let me tell you lol.
I’ve stood up a new SCCM infrastructure including site configuration/roles and deployed a few clients. When testing software updates on a client, software update scan/deployment cycles kept failing. Upon investigation of logs, the scan were failing with “Scan failed with error = 0x80072efd”. Furthermore, reporting showed scan error failure code -2147012867. These errors indicate that the Windows Update Agent could not communicate with the defined source location.
The troubleshooting difficulty is that there are many possibilities of causing this.
- Local GPO “Specify intranet Microsoft update service location”. When using SCCM software updates, the client sets this local GPO on the client pointing to the WSUS location. In my case this wasn’t it.
- Windows Firewall blocking the ports used by WSUS, on either the client or server. In my case this wasn’t it.
- A proxy or bad winhttp settings redirecting the traffic incorrectly from client to server. In my case this wasn’t it.
- Various other things.
I believed that I had reached the end of the Internet at this point when finally I came across a posting on WindowsNoob that steered me in the right direction. To fix a different technical problem with WSUS conflicting with Symantec Endpoint Protection, I swapped the Software Updates Component from using ports 80/443 to using ports 8530/8531. I guess with this change, SCCM didn’t automagically configure the default website in IIS bindings to listen for requests on the newly defined port.
So to resolve the issue, I did the following:
- Open IIS Manager
- Right-click on the default website and select “Edit Bindings”
- Add port 8530 as an IIS binding….and voila it works.
VBScript to Run SCCM Software Updates Scan
A challenge with installing software updates during a task sequence is that it may occur where not all updates are applied on the first pass. The workaround is run software updates, run a VB Script or PowerShell script to force another scan, then run a software updates task again. Others have posted their scripts on this before, so it’s nothing new. However, I failed trying to quickly locate those scripts. So I’m just posting my own of what I use….
'========================================================================== ' AUTHOR: Nick Moseley , https://t3chn1ck.wordpress.com ' DATE : 7/30/2010 ' COMMENT: Initiates an SCCM client scan ' Script from http://msdn.microsoft.com/en-us/library/cc144313.aspx ' Updated 7/15/11 to include a sleep before exiting script '========================================================================== ' Set the required variables. actionNameToRun = "Updates Source Scan Cycle" ' Create a CPAppletMgr instance. Dim oCPAppletMgr Set oCPAppletMgr = CreateObject("CPApplet.CPAppletMgr") ' Get the available ClientActions object. Dim oClientActions Set oClientActions = oCPAppletMgr.GetClientActions() ' Loop through the available client actions. Run the matching client action when it is found. Dim oClientAction For Each oClientAction In oClientActions If oClientAction.Name = actionNameToRun Then oClientAction.PerformAction End If Next ' Wait for 3 minutes for scan completion before exiting script wscript.sleep(180000)
Workaround for Installing Office Updates During an Image Build
Ran into an interesting situation with an image build. I created a custom Office 2010 SP1 install using the OCT. During execution of my image build task sequence, Software Updates was not detecting any of the updates for Office. Further diagnosis revealed that the OCT-built install did not put its “hooks” into the Windows Update Agent, therefore neither the SUP or Microsoft Updates could detect for Office updates. (Side note: once the image was sysprepped, captured, and added into a deployment task sequence, the updates were suddenly available and installed.)
While the cause as to why an OCT-built Office 2010 SP1 install prohibits installation of updates has not been found yet, there is a workaround to run a script that forces Microsoft Update (e.g. WUA) to receive updates for “other products”. By executing the following VBScript after installing Office, SCCM Software Updates will then be able to install the updates during the image build task sequence. The original code is from a TechNet blog post, I just added some extra logging for troubleshooting. Also, if your TS advertisement is configured to “run from server”, then the script will cause the TS to fail. To get past this, simply copy the script locally first then execute it from that location.
Const ForAppending = 8 Set oFSO = CreateObject ("Scripting.FileSystemObject") Set oLogFile = oFSO.OpenTextFile ("C:\ConfigOfficeUpdates.txt", ForAppending, True) oLogFile.WriteLine "Starting execution of VBScript to configure Office to use Microsoft Updates" Set ServiceManager = CreateObject("Microsoft.Update.ServiceManager") ServiceManager.ClientApplicationID = "My App" ' add the Microsoft Update Service by GUID Set NewUpdateService = ServiceManager.AddService2("7971f918-a847-4430-9279-4a52d1efe18d",7,"") oLogFile.WriteLine "Script completed successfully" wscript.Quit(oLogFile.Close)
SUP Search Folder: All non-superseded updates for workstations
This is the search folder that I use to identify any and all security updates possibly available to Windows workstation OS computers. It includes other products too, not just Windows.
- Expression Media\Web
- MS Lync 2010
- MS StreamInsight
- MS Works
- Network Monitor
- Office 2003/2007/2010
- Report Viewer
- SQL Server
- Visual Studio
- Windows 7 Client
- Windows Defender
- Windows Vista
- Windows XP
- Works 6-9 Converter
- Writer Installation and Upgrades
- Update Classification:
- Critical Updates
- Security Updates
- Update Rollups
- Expired: No
- Superseded: No
- Malicious software removal tool
- Visual C++
Finally, select the option “Search all folders under this feature”
Web Report for Software Updates Compliance
SCCM doesn’t have a precreated report (that I can find) that quickly shows the patch compliance for a group of systems. So I created one for myself, that I thought I’d share with every one. To implement this, create a web report as you normally would; use the following SQL statement and remember to create a prompt with the information below that!
select distinct sys.Name0, ui.BulletinID as BulletinID, ui.ArticleID as ArticleID, ui.Title as Title from v_UpdateComplianceStatus css join v_UpdateInfo ui on ui.CI_ID=css.CI_ID join v_R_System sys on css.ResourceID=sys.ResourceID join v_ClientCollectionMembers ccm on ccm.ResourceID=sys.ResourceID where css.Status=2 and ccm.CollectionID=@CollID order by sys.Name0, ui.ArticleID
Prompt text: Collection ID
Provide a SQL statement:
begin if (@__filterwildcard = '') select CollectionID as CollectionID, Name as CollectionName from v_Collection order by Name else select CollectionID as CollectionID, Name as CollectionName from v_Collection WHERE CollectionID like @__filterwildcard or Name like @__filterwildcard order by Name end