SCCM 2012: Set Software Center Business Hours with a Compliance Configuration Item

There are basically two scenarios when business hours come in to effect in SCCM 2012:

1. A user selects to defer required application/software update installations and reboots to take place outside of business hours:


2. A user selects the option in the software center to have SCCM automatically install all required software and restart the computer outside of business hours:image

The default business hours are set to 05:00 – 22:00, Monday to Friday. The business hours can’t be configured through client settings, only by the user or by using the SDK or client WMI methods.

There could be several reasons why you want to change the default business hours. For example, the typical working hours of the majority of your users are different from the default settings and you have a power plan that puts machines in standby before the default business hours end, which would effectively close the window for maintenance outside business hours.

To set the business hours using Compliance settings in ConfigrMgr 2012, navigate to the Asset & Compliance Workspace, select Compliance Settings and create a new configuration item. In the Create Settings page, select a Script setting with a String data type:


Edit the Discovery Script and paste in the following Powershell code:

$cmClientUserSettings = [WmiClass]"\\.\ROOT\ccm\ClientSDK:CCM_ClientUXSettings"
$businessHours = $cmClientUserSettings.GetBusinessHours()
$businessHoursCI = [string]$businessHours.StartTime + "," + [string]$businessHours.EndTime + "," + [string]$businessHours.WorkingDays
Return $businessHoursCI

This will return the current business hours as a string in this format:


The first digit is the start time (7am), the second digit is the end time (7pm) and the third digit is the days of the week. The days of the week are calculated using the table below, so Monday – Friday is calculated as 2+4+8+16+32 = 62.

Sunday 1
Monday 2
Tuesday 4
Wednesday 8
Thursday 16
Friday 32
Saturday 64

Edit the Remediation Script and paste in the following code, setting the desired business hours in the variables $startTime, $endTime and $workingDays.

$startTime = 7
$endTime = 19
$workingDays = 62
$cmClientUserSettings = [WmiClass]"\\.\ROOT\ccm\ClientSDK:CCM_ClientUXSettings"
$businessHours = $cmClientUserSettings.PSBase.GetMethodParameters("SetBusinessHours")
$businessHours.StartTime = $StartTime
$businessHours.EndTime = $EndTime
$businessHours.WorkingDays = $WorkingDays

Try {
 $result = $cmClientUserSettings.PSBase.InvokeMethod("SetBusinessHours", $businessHours, $Null)
 If ($result.ReturnValue -eq 0 ) {
 Else {
 "Failed to set SCCM client business hours."
Catch {
 "Failed to set SCCM client business hours."

Add the following compliance rule, setting the value to your desired business hours and enabling the remediation script for noncompliant clients:


This rule will remediate noncompliant clients to the desired business hours.

Lastly, add the configuration item to a configuration baseline and deploy to your target collection.

Now we have centrally controlled business hours in ConfigMgr 2012:


Further Reference:

There’s a useful post on Technet that explains the concept of Business Hours vs. Maintenance Windows in System Center 2012 Configuration Manager.

Torsten Merringer has a post here that shows how to set the business hours using VBScript.


MDT UDI Task Sequence: Restore USMT migration using Computer Association Recovery Key

Problem: You need to restore user migration data from the State Migration Point to a computer other than the destination computer specified in the Computer Assocation in the SCCM database.

Some of the possible solutions to this are:

1. Use the Windows Easy Transfer Wizard to open the .Mig file, enter the the recovery key and restore the user data. This requires NTFS read permissions to the SMP share, administrator rights on the local machine and the Windows Easy Transfer Wizard (built in to Windows 7 and 8, separate install on XP).

2. Run the loadstate command with the appropriate parameters on the local machine to restore the data. This requires NTFS read permissions to the SMP share, administrator rights on the local machine, a copy of the USMT source files, and building a pretty long command line, which is not very practical.

Solution: The solution I used was to build an SCCM/MDT task sequence that uses the UDI Wizard to prompt the technician for the recovery information (state store location and state recovery key), authenticate to the SMP share with a service account and run the loadstate command to restore the data on to the machine. Some of the advantages of this method are:

  • A service account is used to access the SMP share, so you don’t have to grant permissions to technicians/users.
  • The task sequence is run in the system context, so local administrator rights are not needed on the client.
  • You can specify a consistent loadstate command with logging.
  • The process is overall more secure, robust, traceable and easy to use.

This solution uses the “Build Your Own Page” feature in the UDI Wizard included in MDT 2012 Update 1.

Step 1 – Create the Service Account

Create a domain account to be used as a service account by the task sequence to access the state migration point. Grant the account NTFS read permission to the SMP share on your SCCM server.

Step 2 – Create the UDI Wizard Page

Using the UDI Wizard Designer, create a new file. Select a StageGroup (I chose Refresh). Click on each page and select “Remove Item”. You can leave a Welcome page and a Summary page if desired.

Select “Add Page” > “Build Your Own Page”. Use the DisplayName “USMT Recovery Page” and the Page Name “USMTRecoveryPage”.

Create a Label: “Enter the user state store location:”
Create a Label: “Enter the user state recovery key:”

Create a TextBox with the variable name “StateStoreLocation” and friendly name “State Store Location”. Assign a “NonEmpty” validator and appropriate message:


Create a TextBox with the variable name “RecoveryKey” and friendly name “RecoveryKey”. Assign a “NonEmpty” validator and appropriate message:


You should now have only the USMT Recovery Page and an optional Welcome/Summary Page:


Save the Wizard page as “UDIWizard_Config_StateMigrationRecovery.xml”

Step 3 – Create the Task Sequence

From the SCCM console Task Sequences node, select “Create MDT Task Sequence”.

Select “Microsoft Deployment Custom Task Sequence”.

Follow the wizard and select the packages to use in the task sequence. We will discard most of the default steps to create a custom task sequence, so it’s not important what options you choose in the wizard.

When the wizard is complete, delete the steps except those you can use in the task sequence below.


The Toolkit Package should point to your MDT 2012 Update 1 folder with the custom UDI wizard page you created.

The Gather step should point to a customsettings.ini file. In your customsettings.ini file, make sure the deployment type matches the stage you used to create the Wizard page, e.g. “DeploymentType=Refresh”

Add a “Run Command Line” step with the name “UDI Wizard” and the following command line:

cscript.exe “%DeployRoot%\Scripts\UDIWizard.wsf” /definition:UDIWizard_Config_StateMigrationRecovery.xml

Add a “Run Command Line” step with the name “Connect to Network Folder”. Use the variable %StateStoreLocation% for the path and select the service account you created above.


Add a “Run Command Line” step with the name “Restore User Data”. Check the box to use the USMT package and enter the following command line (substitute your own loadstate options where applicable):

%PROCESSOR_ARCHITECTURE%\loadstate.exe %StateStoreLocation% /ue:*\* /ui:domain\* /v:5 /c /l:%logpath%\loadstate.log /progress:%logpath%\loadstateprogress.log /decrypt /key:”%RecoveryKey%” /i:”%PROCESSOR_ARCHITECTURE%\MigUser.xml” /i:”%PROCESSOR_ARCHITECTURE%\MigApp.xml” /config:”%PROCESSOR_ARCHITECTURE%\Config.xml”

The values of the %StateStoreLocation% and %RecoveryKey% variables are picked up from the fields you populate in the UDI wizard.

Step 4 – Deploy the Task Sequence to a collection

Deploy the task sequence to an appropriate collection. Use the task sequence to restore user migration data from an existing computer association to a different computer destination. When prompted by the UDI Wizard, copy and paste the recovery information from the computer association in the “User State Migration” node in SCCM.

Practical Note: Typing out the state store location and state recovery key is not an option – the state store location can be over 100 characters and the recovery key is 256 characters. The easiest and most appropriate ways to populate the fields in the UDI Wizard would probably be to use the ConfigMgr Remote Control Viewer and copy/paste, or to send an (encrypted) email to the user with the recovery data and copy/paste.

SCCM 2012: Execute task sequence with PowerShell

Here is a PowerShell script to initiate a task sequence with PowerShell. The script takes one argument – the name of the task sequence. The task sequence must be deployed/advertised to the machine already. It searches the deployed task sequences on the machine and if it finds a task sequence matching the one you specified, it will execute it.

Executing a task sequence this way bypasses the prompt to install a new operating system, which may be useful if you have a task sequence that just performs a user capture or restore, or if you use a task sequence for purposes other than OSD and you don’t want the “install a new operating system” warning dialog.

Install Operating System Warning Dialog

You could potentially use this script to deploy task sequences from the ConfigMgr 2012 Application Catalog. This would give you the benefits of the application model such as dependency and requirement rules as well as the benefits of the Application Catalog with its request/approval system. You could then use the Application Catalog as a request/approval portal for OSD refresh scenarios, something that usually requires a third party tool such as SCCM Expert.

In order to make this work, you would need to deploy an application that runs a script which does the following:

  1. Add the machine to a collection that has the task sequence deployed to it.
  2. Trigger a machine policy evaluation.
  3. Trigger the task sequence.

The application deployment type would need a detection rule to indicate that the task sequence has executed successfully so that the application installation doesn’t interfere with the task sequence. The detection rule could vary depending on what the task sequence does.

I haven’t tried the above and one of the potential issues would be granting the client/script permission to add a machine to a collection. Who knows, maybe Microsoft has plans to allow task sequences to be published to the Application Catalog in a future service pack for ConfigMgr 2012.

I have tested this script with ConfigMgr 2012, but it should with with ConfigMgr 2007 also.

Function Execute-TaskSequence {
    Param (
        [parameter(Mandatory = $true)]
    Try {
        Write-Host "Connecting to the SCCM client Software Center..."
        $softwareCenter = New-Object -ComObject "UIResource.UIResourceMgr"
    Catch {
        Throw "Could not connect to the client Software Center."
    If ($softwareCenter) {
        Write-Host "Searching for deployments for task sequence [$name]..."
        $taskSequence = $softwareCenter.GetAvailableApplications() | Where { $_.PackageName -eq "$Name" }
        If ($taskSequence) {
            $taskSequenceProgramID = $taskSequence.ID
            $taskSequencePackageID = $taskSequence.PackageID
            Write-Host "Found task sequence [$name] with package ID [$taskSequencePackageID]."
            # Execute the task sequence
            Try {
                Write-Host "Executing task sequence [$name]..."
                Write-Host "Task Sequence executed."
            Catch {
                Throw "Failed to execute the task sequence [$name]"

SCCM 2012: Target Software Update Deployments to user’s devices based on UDA

While SCCM 2012 provides user-centric application deployment, it is only possible to deploy software updates to a device or device collection.

Here’s a collection I built in SCCM 2012 to retrieve the primary device of a user who is a member of the “SCCM Software Updates Pilot User Group”. In this way, I can deploy software updates to a device collection based on an Active Directory user group. It’s kind of like user-centric software update deployment.

The query below should create a collection of devices where the device has a primary user that is a member of the AD group “SCCM Software Updates Pilot User Group”.

Select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client FROM SMS_R_System JOIN SMS_UserMachineRelationship ON SMS_R_System.Name=SMS_UserMachineRelationship.ResourceName JOIN SMS_R_User ON SMS_UserMachineRelationship.UniqueUserName=SMS_R_User.UniqueUserName WHERE SMS_UserMachineRelationship.Types=1 AND SMS_R_User.UserGroupName="DOMAIN\\SCCM Software Updates Pilot User Group"