Local Group Policies for WSUS and the Software Update Agent of ConfigMgr 2012

This blog post will describe a scenario that I ran into this week. Also, to be honest, I wasn’t aware of this exact behavior and, until this moment, I haven’t been able to find any documentation that describes this behavior.

Scenario

The scenario is that the customer wants to have the ConfigMgr client deployed on their server environment. This server environment is currently patched by using different methods and one of them is WSUS. So far, nothing weird, but the servers patched by WSUS are configured via local group policies.

Behavior

I think that by now everybody knows that the ConfigMgr client uses the local group policy Specify intranet Microsoft update service location to point to the WSUS server of the ConfigMgr environment, if, of course, Enable software updates on clients is set to Yes in the client settings. What I didn’t know is the behavior of the ConfigMgr client when Enable software updates on clients is set to No in the client settings. My understanding was that it would simply disable the Software Updates Agent and, if previously configured by the ConfigMgr client, it would remove the local group policy of Specify intranet Microsoft update service location. Sadly, I was wrong, big time! What actually happens is that the ConfigMgr client will always remove all WSUS related local group policies with the first policy that has Enable software updates on clients set to No in the client settings. This is even the case when Enable software updates on clients is set to No in the default client settings.

At the moment that the first policy arrives at the client with Enable software updates on clients set to No in the client settings the following information will show in the ScanAgent.log. LogFile_ScanAgent

Basically it’s stating that it’s disabling the Software Updates Agent and deleting a Windows Update policy. At this point I would still assume that the log file is referring to the local group policy Specify intranet Microsoft update service location, but, even if nothing is configured by the ConfigMgr client, it will delete all all WSUS related local group policies. Everything that’s configured in a local group policy located under Computer Configuration\Administrative Templates\Windows Components\Windows Update will be removed. This relates to the registry key’s located under HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate. Once a policy is applied with Enable software updates on clients set to No in the client settings the ConfigMgr client won’t touch these local group policies (and registry keys) again.

EventViewer_GPOThis behavior doesn’t cause any problems when domain group policies are used, because directly after deleting the WSUS related policies it triggers a domain group policy update to restore those settings (see event viewer message).

Funny note: When uninstalling the ConfigMgr client it only removes the Specify intranet Microsoft update service location local group policy. In that case it leaves every other WSUS related local group policy untouched.

Solution

Sadly, there is no real solution, as there is no way to prevent the ConfigMgr client from initially removing all WSUS related local group policies. In most situations this won’t be a huge problem. It will only be a problem when there are no domain group policies available, or when domain group policies are not used. The only solutions are actually workarounds. Simply accept this behavior and make sure there is something in place to cover this little gap. Three possible workarounds are:

  1. Use compliance settings to set the correct registry keys;
  2. Export the registry keys and deploy them via an old-school package (use regedit);
  3. Export the local group policy and deploy it via an old-school package (use secedit).

Publish Cumulative Updates of ConfigMgr via System Center Updates Publisher

There are a multiple methods to deploy the Cumulative Updates (CU) of ConfigMgr, to all the different components (console, client and server). The most common used method is the old-school packages that are created during the upgrade of a site server. This blog post will be about another less often, but definitely not less effective, method of deploying a CU is via System Center Updates Publisher (SCUP). In this post I will go through the steps required to deliver a CU, via SCUP, to ConfigMgr as a software update.

Prerequisites

Before I will go through the steps, it’s important to know that this post does not describe the installation of SCUP itself. In case SCUP is not yet installed, the following posts provide some good guidelines to set it up:

Step 1: Import the updates in SCUP

The first step is to import the (metadata of the) updates in SCUP. In case your not familiar with this, one of the things delivered during the installation of a CU, on the site server, is also a CAB file. This CAB file is located in the SCUP folder of the specific CU and contains the updates and their information in a form that SCUP can read. To import the CAB file in SCUP follow the next steps:

Step Action
1 Open the System Center Updates Publisher 2011 Console, navigate to the Updates workspace and select Import in the Home tab.
2 SCUP_ImportTypeOn the Import Type page, select Specify the path to the catalog to import, Browse to the CAB file and click Next.
3 SCUP_ManualImportOn the Summary page. click Next.
4 SCUP_SecurityWarningOn the Security Warning popup, click Accept.
5 SCUP_ConfirmationOn the Confirmation page, click Close.
6 To verify a successful import, either check the SCUP.log (located in the AppData of the user performing the action), or check the Updates node in the SCUP console that should now show the following updates. SCUP_CU2Updates

Step 2: Publish the updates to WSUS

The second step is to publish the (metadata of the) new updates to WSUS. To publish the (metadata of the) new updates to WSUS follow the next steps:

Step Action
1 Open the System Center Updates Publisher 2011 Console, navigate to the Updates workspace, select the new updates and select Publish in the Home tab.
2 SCUP_PublishOptionsOn the Publish Options page, select Full Content, select Sign all software updates with a new publishing certificate when published software updates have not changed but their certificate has changed and click Next.
3 SCUP_SummaryOn the Summary page, click Next.
4 SCUP_SecurityWarningCVOn the Security Warning popup, select Always accept content from “Microsoft Corporation” and click Accept.
5 SCUP_ConfirmationPOn the Confirmation page, click Close.
6 To verify a successful publish, either check the SCUP.log (located in the AppData of the user performing the action), or check the Updates node in the SCUP console that should now show a Date Published. SCUP_CU2UpdatesP

Step 3: Synchronize software updates

The third, and last, step is to synchronize (the metadata of) these updates now to ConfigMgr. To do this it is necessary to perform two synchronization actions. The first time is to synchronize the new product in to ConfigMgr and the second time is to synchronize (the metadata of) the updates to ConfigMgr. Simply do this all by performing the following steps:

Step Action
1 Open the System Center 2012 R2 Configuration Manager Console, navigate to Software Updates > All Software Updates in the Software Library workspace and select Synchronize Software Updates in the Home tab.
2 SCUP_SystemCenter2012R2ConfigurationManagerAfter the synchronization is done, navigate to Site Configuration > Sites in the Administration workspace and select Configure Site Components > Software Update Point.

In the Software Update Point Component Properties, in the Products tab select System Center 2012 R2 Configuration Manager (located under All Products > Microsoft – Local Publish) and click Ok.

3 Navigate back to Software Updates > All Software Updates in the Software Library workspace and select Synchronize Software Updates in the Home tab.
4 To verify a successful synchronization check the wsyncmgr.log.SCUP_WsyncMgr

Result

At the end it’s always nice to look at the results. Navigate to Software Updates > All Software Updates in the Software Library workspace and in the product filter it’s now possible to select the product System Center 2012 R2 Configuration Manager. By doing this the console will show the newly synchronized updates. After this the CU can be deployed as any other normal (security) update.SCUP_SoftwareUpdates

New tool: Show memberships of software updates to deployment packages and software update groups

Actually since the first release of ConfigMgr 2012, I’ve seen and got question about software updates. Besides, of course, questions about setting it up, these questions are mainly focused about the memberships of software updates. Simple questions like “In which software update group is this software update?” or “In which deployment packages are the updates of this software update group?” are not that simple to answer. This is all going to change, starting today!

I created this simple tool that can perform searches based on a specific software update, a software update group, or a deployment package. Simply specify the Name (in case the of a software update the article id), select the Type (software update, software update group, or deployment package) and click Execute.

>> Available via download here on the TechNet Galleries! <<

Basically this tool covers the following three scenario’s:

  1. Search on Software Update: Show the software update groups and deployment packages of which this update is a member;
  2. Search on Deployment Package: Show the software update groups of which the updates in the deployment package are a member;
  3. Search on Software Update Group: Show the deployment packages of which the updates in the software update group are a members.

Overview

The following table will provides an overview of what this tool exactly does and the information that it will show in every situation.

SUI_ErrorTo prevent weird errors from happening this script/ form does some basic error catching. The following errors can appear:

  • Please select a valid type;
  • Please provide a valid name;
  • Please provide a valid article id of a software update;
  • Please provide a valid name of a software update group;
  • Please provide a valid name of a deployment package
SUI_RunningTo show that the form/ script is still busy, the name and type field will be disabled. This can be very useful with overactive admins in combination with many updates in a deployment package or software update group. This will prevent them from trying a new query while the old one is still running, because it might take a while before all results are shown.
SUI_ResultsDPIn case the Deployment Package type is used in combination with a valid name, the result will look like this. To indicate that the Deployment Package type is used the name of the corresponding group box will change. The Software Update Group information will show per update in which Software Update Group it exists. For updates that are not within a Software Update Group it displays <NoSoftwareUpdateGroup>.
SUI_ResultsSUPIn case the Software Update Group type is used in combination with a valid name, the result will look like this. To indicate that the Software Update Group type is used the name of the corresponding group box will change. The Deployment Package  information will show per update in which Deployment Package it exists. For updates that are not within a Deployment Package it displays <NoDeploymentPackage>.
SUI_ResultsSUIn case the Software Update type is used in combination with a valid article id, the result will look like this. The Software Update Group information will show in which Software Update Group it exists and the Deployment Package information will show in which Deployment Package it exists. When it’s not within a Software Update Group it displays <NoSoftwareUpdateGroup> and when it’s not within a Deployment Package it displays <NoDeploymentPackage>.

Add Update Content to a Deployment Package via PowerShell in ConfigMgr 2012

Last week I read a forum question about downloading updates in a software update group. I thought that I could create an easy example, but it wasn’t all as easy as I thought it would. As there is no cmdlet available that performs this specific action, I went back to WMI. In WMI there is a method AddUpdateContent in the SMS_SoftwareUpdatesPackage that should do the trick. After playing around with it for a while I noticed that this method is not as straight-forward as it looks.

The method

The main problem I had with this method, was the documentation, or better, the lack of documentation. The SDK only contains a very old example that also doesn’t seem to use the right order for the parameters. Let’s start with what the parameters should be and walkthrough them in the order that they should be used:

  • A boolean to indicate whether or not the content has to be replicated to the distribution points.
  • An array that contains the IDs of the content that has to be added to the deployment package.
  • An array that contains the source path where the content files are located.
    • Note: The content of the updates have to be downloaded to a local, or network path already.

With these three parameters, it is possible to invoke the AddUpdateContent method, of the SMS_SoftwareUpdatesPackage class on a specific PackageID. An easy way to do that would be invoking the method on the WMI object path to the specific deployment package. This makes the following example:

Invoke-WmiMethod -Path "\\$($SiteServer)\root\sms\site_$($SiteCode):` SMS_SoftwareUpdatesPackage.PackageID='$PackageID'" ` -Name AddUpdateContent ` -ArgumentList @($false,$UpdateContentIDs,$UpdateContentSourcePaths)

The usage

To use this method it’s necessary to fill those parameters and to do that it’s necessary to collect some information. As I don’t think it’s very user-friendly to supply a CI ID as a function parameter, I will first search the CI ID of the software update group based on its display name in the SMS_AuthorizationList class.

$UpdateGroupCIID = (Get-WmiObject -Namespace root/SMS/site_$($SiteCode)` -ComputerName $SiteServer -Query "SELECT * FROM SMS_AuthorizationList ` WHERE LocalizedDisplayName='$SoftwareUpdateGroup'").CI_ID

With that CI ID I can find the software updates that are a member of the software update group. The easiest way to do that is to “join” the SMS_CIRelation class with the SMS_SoftwareUpdate class. This will provide a list with all the software updates that are a member of the specific software update group (a big thanks here to the SMSProv.log for providing me with the main part of the query).

$Updates = Get-WmiObject -Namespace root/SMS/site_$($SiteCode) ` -ComputerName $SiteServer -Query "SELECT upd.* FROM SMS_SoftwareUpdate` upd, SMS_CIRelation cr WHERE cr.FromCIID='$UpdateGroupCIID' AND` cr.RelationType=1 AND upd.IsContentProvisioned=0 AND upd.CI_ID=cr.ToCIID"

After finding the updates we can use the CI ID of the updates to find the associated content information. To get this information the easiest and quickest way is to use a “join” again, but this time between the SMS_CIToContent class and the SMS_CIContentFiles class. This will provide a list with the source locations of the software updates.

$UpdateContent = Get-WmiObject -Namespace root/SMS/site_$($SiteCode) ` -ComputerName $SiteServer -Query "SELECT fil.* FROM SMS_CIToContent ` con, SMS_CIContentFiles fil WHERE con.CI_ID='$UpdateCIID' AND ` con.ContentID=fil.ContentID"

The content IDs can now be used to fill the first array of the AddUpdateContent method. The second array has to be filled with the location to were the content IDs are downloaded. The complete script including the missing, and not explained, little bits-and-pieces and including a download function is available via the TechNet Galleries.

>> The complete script is available via download here on the TechNet Galleries! <<

The result

Download the complete script and run it with a command line like .\Add-UpdateToPackage.ps1 <DeploymentPackage> <SoftwareUpdateGroup> <SiteCode> <SiteServer>. After the script starts the AddUpdateContent method the result can be followed in the SMSProv.log.

SMSProv.log