Tuesday, July 3, 2018

Creating Global Conditions in System Center Configuration Manager for Office 365 deployments

Creating Global Conditions in System Center configuration Manager for Office 365 deployments

Firstly I would recommend reading the Microsoft docs article below.

Software Library > Application Management > Global Conditions.

Scenario: I have an AD group "SD-LSG-Comp-Microsoft Project ClickToRun" with computer objects that should install Office 365 - ProjectProXVolume edition. I wanted to create one application with multiple deployment types depending on their AD membership.

For example if the computer is only a members of the "SD-LSG-Comp-Microsoft Project ClickToRun" AD group then the deployment should only run the deployment Type "Office 365 Default Deployment Type-Install_InstallProject.cmd".  

This deplyoment Type calls the Office 365 setup.exe with a configuration xml detailing the <Product ID="ProjectProXVolume">.

(For a detailed understanding of how to package Office 365 see here. This blog will be updated to reflect the latest setup.exe and the switch <RemoveMSI All="True" />)


<Add OfficeClientEdition="32" Channel="Monthly" OfficeMgmtCOM="True" AllowCdnFallback="True">
<Product ID="ProjectProXVolume">
<Language ID="en-us" />
<Updates Enabled="TRUE" />
<Display Level="none" AcceptEULA="TRUE" />
<Logging Path="%Windir%\Temp\" />
<Property Name="AUTOACTIVATE" Value="1" />

For the deployment to choose  "Office 365 Default Deployment Type-Install_InstallProject.cmd" we need to create a global condition that will issue a $True value if the computer is a member of the AD group "SD-LSG-Comp-Microsoft Project ClickToRun".

The global condition created below, will run a Powershell script on the local computer listing all the groups the computer is a member of and if one of the groups found matches the AD group "SD-LSG-Comp-Microsoft Project ClickToRun" issue a $true value and stop the script. 

#Get groups of local computer
$Group = "AD Group Name"
$ComputerMembership = ([adsisearcher]"(&(objectCategory=computer)(cn=$env:COMPUTERNAME))").FindOne().Properties.memberof -replace '^CN=([^,]+).+$','$1' | % {If ($_ -ieq $Group) {$true;break;} }

For the deployment to be linked to the AD group  the deployment type "Office 365 Default Deployment Type-Install_InstallProject.cmd" must have a "Requirement type" set.

We now simply set a the global condition created to equal True. 

In my screen shot i have multiple deployment types for several scenarios i.e. Visio and Project, Visio, Project, Office365, Office 365 during a Task Sequence.

See Global Condition details below.

 #Get groups of local computer
$Group = "AD Group Name" #The AD group name to be filtered.
$ComputerMembership = ([adsisearcher]"(&(objectCategory=computer)(cn=$env:COMPUTERNAME))").FindOne().Properties.memberof -replace '^CN=([^,]+).+$','$1' | % {If ($_ -ieq $Group) {$true;break;} }

#Get process TSManager; will issue true if within a Task Sequence
[bool] (Get-Process TSmanager -ea 0)

Wednesday, June 6, 2018

Office 365 Activation Troubleshooter SCCM Application

Scenario: I wanted to package the Office 365 Activation Troubleshooter (Officeact.diagcab) for Office 365 users with activation issues. I needed to find out the commands to use as well as the appropriate Detection Method.

1. Download: Officeact.diagcab https://aka.ms/diag_officeact

2. Create a PowerShell (Diagnostics.Office365.ps1) script to call the officeact.diagcab file. See example below

3. Create an SCCM Script application calling the Diagnostics.Office365.ps1 script

powershell -ExecutionPolicy Bypass .\Diagnostics.Office365.ps1

Select the Detection Method tab and select radial next to "Use a custom script to detect the presence of the this deployment type".

Select the Edit option on the right and set the script type to PowerShell and the script content as appropriate to the application.

The script below will look at all running processes and filter out all processes that equal msdt; if a process matching this string is found the client will return an exit code of 0 (zero) indicating to SCCM that the application has been detected.

Once the process terminates at the end of the diagnostics process the SCCM Client Application deployment cycle action will rerun making the application available for installation again without issuing a failed message.

The User Experience Tab should be set to "Install for User" as this diagcab must be run interactive in order to process the diagnostics.  The installation program visibility should be set to Hidden otherwise the initial PowerShell script will be displayed detailing the Transcript etc.

Friday, May 18, 2018

SCCM Server Groups

What Are Server Groups?

Within SCCM Assets and Compliance you can create a collection containing Server Client membership. Once the 'Server Group' feature is enabled the properties of the collection will contain an additional option to declare that all members of the collection are part of a server group.  This means SCCM knows that the servers within this collection must be treated with specific logic and settings.

In the example below the collection contains three nodes of a cluster and only one node may be Software Updated at a time.

Once policy is received for the Software Update Group deployment an election is held in which one of the nodes will engage a lock state forcing the other nodes to wait until it has been released.

The UpdatesDeployment.log details the 'Lock State'. Once the node has taken the lock (Lock State: 1) the server will then run the 'Node Drain Script' and continue if the script has an exit code of 0 zero or if the script times out (600 seconds default).

After the main deployment is complete the 'Node resume script' is run and the lock state is returned to 2.

'Node Drain Script' [Untested in Production]

'Node resume script'

Lock States
There are four lock states:

Waiting for Lock: 0
Have Lock: 1
Released Lock: 2
Node Script Failed: 3

The SQL script below will report on all Server Groups with Pre and Post Actions as well as current client Lock states.


Thursday, March 22, 2018

SCCM Software update Failure : CBS_E_STORE_CORRUPTION (KB3000850)

A two node cluster required new and old software updates to bring it up to compliance. The installation of KB3000850 was failing to install either manually or via SCCM deployment on one node  but not the other.

Installation job encountered some failures. Error = 0x80240022. Commit Result = 0x00000001

 Not able to add file to extract: update.ses [HRESULT = 0x80070002 - ERROR_FILE_NOT_FOUND]

CBS    Store corruption, manifest missing for package: Package_33_for_KB3081320~31bf3856ad364e35~amd64~~
CBS    Mark store corruption flag because of package: Package_33_for_KB3081320~31bf3856ad364e35~amd64~~ [HRESULT = 0x800f0831 - CBS_E_STORE_CORRUPTION]

 Failed to resolve package [HRESULT = 0x800f0831 - CBS_E_STORE_CORRUPTION]

WER: Generating failure report for package: Package_for_KB3000850~31bf3856ad364e35~amd64~~, status: 0x800f0831, failure source: Execute, start state: Staged, target state: Installed, client id: WindowsUpdateAgent

Common troubleshooting steps carried out without success:

net stop wuauserv
net stop cryptsvc
Ren %systemroot%\SoftwareDistribution SoftwareDistribution.bak
Ren %systemroot%\system32\catroot2 catroot2.bak
net start wuauserv
net start cryptsvc

SFC /Scannow
Dism /Online /Cleanup-Image /RestoreHealth /Source:wim:E:\sources\install.wim:1 /limitaccess


Note the KB detailed within the CBS log after "Store corruption, manifest missing for package:". In my case it was KB3081320. This KB was not installed on the failed node from within control panel or Powershell (get-hotfix | select hotfixid) however, the manifest file was present within the folder C:\Windows\servicing\Packages.

Download the KB MSU file from the Microsoft Update catalog  and extract the CAB file to a temp directory.

expand C:\temp\updates\windows8.1-kb3081320-x64_d6e34f82e20d9efa19ab0ae7a938f8d80c01416e.msu /f:* C:\temp\updates\kb3081320

Then remove the package using DISM; this will in affect remove the manifest file from C:\Windows\servicing\Packages

dism /online /remove-package:C:\Temp\Updates\kb3081320\Windows8.1-KB3081320-x64.cab

Finally after removing the corrupted manifest files /updates the intended update KB3000850 will install via DISM/SCCM successfully and the CBS log will not have any corruption errors.

Dism /online /add-package /packagepath:C:\Temp\Updates\kb3000850\Windows8.1-KB3000850-x64.cab

Thursday, January 18, 2018

How to Add a second ConfigMgr Software Update Point without ERROR 0x8024401c


The client has pretty standard ConfigMgr setup to manage there primary and dev systems. The clients communicate to Distribution and Management Points however, the PORT 8530 from the Software update Point (SRVSUP01) can not be opened to clients in the dev vlan.

Without getting into the technical architecture of the configured firewall rules a second Software update Point would be required to over come this architectural design. However, the Dev client would not switch over to the new SUP (SRVSUP02).

Upon opening a Browser window from a Dev client it was possible to navigate to the addresses below thus confirming the availability of the new SUP.


The WUAHandler.log was reporting a scan failure error code: 0x8024401c. Implying the Scan agent was not able to connect to SRVSUP01 (due to closed PORTS) however the client was not switching over to the SRVSUP02 as intended.

WUAHandler.log Extract
Its a WSUS Update Source type ({3BBB5556-AB2C-4D8E-9F11-741GE69677H2}), adding it.
OS Version is 6.3.9600
Existing WUA Managed server was already set ( http://SRVSUP01.CONTOSO.LOCAL:8530), skipping
Group Policy registration. Added Update Source ({3BBB5556-AB2C-4D8E-9F11-741GE69677H2}) of content type: 2 Scan results will include all superseded updates. 
Search Criteria is (DeploymentAction=* AND Type='Software') OR (DeploymentAction=* AND Type='Driver') Async searching of updates using WUAgent started.
Async searching completed. 
OnSearchComplete - Failed to end search job. Error = 0x8024401c. 
Scan failed with error = 0x8024401c.

The Boundary groups were incorrectly configure and did not include the IP address range of the Dev clients.  The client therefore fell back to the Default Bound Group which only included SRVSUP01 as an available SUP; therefore preventing the clients from switching over.  Once the Boundary groups were resolved clients received new policy and switched over.
Its a WSUS Update Source type (3BBB5556-AB2C-4D8E-9F11-741GE69677H2}), adding it.
Enabling WUA Managed server policy to use server: http://SRVSUP02.CONTOSO.LOCAL:8530 
Waiting for 2 mins for Group Policy to notify of WUA policy change... Waiting for 30 secs for policy to take effect on WU Agent.
Added Update Source ({3AAB6A76-CE2D-4E8A-9F11-741AE69677A2}) of content type: 2 Scan results will include all superseded updates.
Search Criteria is (DeploymentAction=* AND Type='Software') OR (DeploymentAction=* AND Type='Driver') Async searching of updates using WUAgent started.
Async searching completed.
Successfully completed scan.
Its a WSUS Update Source type ({3BBB5556-AB2C-4D8E-9F11-741GE69677H2}), adding it.
OS Version is 6.3.9600
Existing WUA Managed server was already set (http://SRVSUP02.CONTOSO.LOCAL:8530), skipping Group Policy registration.
Added Update Source ({3BBB5556-AB2C-4D8E-9F11-741GE69677H2}) of content type: 2 Scan results will include all superseded updates.
Search Criteria is (DeploymentAction=* AND Type='Software') OR (DeploymentAction=* AND Type='Driver') Async searching of updates using WUAgent started.
Async searching completed.
Successfully completed scan.

Wednesday, December 6, 2017

SCCM Software Update - Job error 0x80004005 Failed to Add Update Source for WUAgent

SCCM Software Updates - Failed to Add Update Source for WUAgent 

Today I have been looking at a range of servers (Server 2008 /R2 2012 /R2) that were failing to communicate with the Software Update Point (SUP) in SCCM and retrieve deployment policy.

The UpdateDeployment.log was reporting the Job error 0x80004005
Job error (0x80004005) received for assignment ({af7a48e6-d550-4070-dd9b-ecc234567584}) action UpdatesDeploymentAgent 12/6/2017 10:32:27 AM 2096 (0x0830)

The WUAHandler.log  was reporting "Unable to read existing WUA Group Policy object" and "Failed to Add Update Source for WUAgent "

Unable to read existing WUA Group Policy object. Error = 0x80004005. WUAHandler 12/6/2017 3:41:00 AM 2828 (0x0B0C)Failed to Add Update Source for WUAgent of type (2) and id ({3AAB6A76-CE2D-4E8A-9F11-123AE69612A1}). Error = 0x80004005. WUAHandler 12/6/2017 11:03:31 AM 2276 (0x08E4)

Until the agent can report back to the SUP, SCCM will not be able to summarize Software Update status and offer the appropriate updates via Software Center. 

The resolution was to stop the "Windows update" service and remove the Registry.pol file and the comment.cmtx file if present as well as the SoftwareDistribution folder.

After restarting the "Windows update" service the SoftwareDistribution folder is created.
After the next SCCM "Update Deployment Cycle" the Registry.pol is created.

The WUAHandler.log will now state the scan completed successfully.

Waiting for 2 mins for Group Policy to notify of WUA policy change...Waiting for 30 secs for policy to take effect on WU Agent.
Added Update Source ({abc123abc123abc123abc123}) of content type: 2
Async searching of updates using WUAgent started.
Async searching completed.
Successfully completed scan
I have scripted the process to help others deploy a solution. If you think there is a better way to address this problem please leave a comment.

Friday, November 17, 2017

Windows 10 - UE-V Deployment Guide

Windows 10 - UE-V Deployment Guide

UE-V in Windows 10 is setup pretty quickly but the documentation for Group Policy and expected outcomes is all over the place.  In order to help other IT Pro's navigate their UE-V implementation I have documented my configuration with observations.

Folder and Executable Reference Table
Templates folder                    = C:\ProgramData\Microsoft\UEV\Templates
InboxTemplates folder           = C:\ProgramData\Microsoft\UEV\InboxTemplates
Scripts Folder                         = C:\ProgramData\Microsoft\UEV\Scripts
SettingsStoragePath                = Central UNC Share i.e \\ServerName\UEVData\%UserName%
SettingsTemplateCatalogPath = Central UNC Share i.e \\ServerName\UEVCatalogPath

UEVAppMonitor.exe                        = Scheduled Task "Monitor Application Settings"
ApplySettingsTemplateCatalog.exe = Scheduled Task "Template Auto Update"
Microsoft.Uev.SyncController.exe   = Scheduled Task "Sync Controller Application"

The UEV Templates folder is located within ProgramData folder and contains various sub-folders  containing scripts, Templates and compiled Templates (depending on the Windows 10 branch).

In 1607 there are two folders (InboxTemplates and Templates).  The InboxTemplates contains the standard Templates used to capture user configurations such as Themes, desktop settings, and MS applications.  The Template folder contains the Compiled settings files that
UEVAppMonitor.exe will monitor and Sync to the "SettingsStoragePath".

These Standard Templates can be registered individually or all at the same time via PowerShell. In 1709 there is the additional folder called "Scripts" containing the script RegisterInboxTemplates.ps1. See below for contents of script to register all Templates within the folder InboxTemplates.

# Enumerate the Inbox UE-V Templates and register those templates
$inboxTemplates= Get-ChildItem -Path $env:PROGRAMDATA\Microsoft\UEV\InboxTemplates -Filter *.xml
for ($count = 0; $count -lt $inboxTemplates.Count; $count++) {
    Register-UevTemplate -Path $inboxTemplates[$count].FullName -ErrorAction SilentlyContinue

Within the latest Group Policy templates (Administrative Templates (.admx) for Windows 10 Fall Creators Update (1709) ) There is the option to Enable UE-V and Auto-Register InboxTemplates. This led me to believe the Register-UEVTemplates script was not necessary and Group Policy would automatically register these InboxTemplates.  During testing this action was not occurring and I started to think there was a problem within my environment.  However, this options appears to be only available if you exclusively run domain controllers 2012/R2 and above. See Documentation here.

"Group Policy ADMX templates configure the synchronization settings for the UE-V service and enable the central management of common UE-V service configuration settings by using an existing Group Policy infrastructure.
Supported operating systems for the domain controller that deploys the Group Policy Objects include:
Windows Server 2012 and Windows Server 2012 R2"

If your environment is like mine with Domain Controller Functional Level 2008, there are several ways in which you can register these Templates automatically. An SCCM Baseline can be used to check for the compiled file/s and if non-compliant be resolved by remediation, i.e. Register-UevTemplate '\\SERVER\SHARE\UEV\Templates\*.xml'.

Alternatively you can copy all the InboxTemplates (C:\ProgramData\Microsoft\UEV\InboxTemplates) over to the UNC Share "SettingsTemplateCatalogPath"; then within group policy you can specify the Template Catalog path and tick the box to "Replace the Default Microsoft Templates". This will copy all the InboxTemplates (and Custom Templates) over to the Computer and register within the "Templates" folder as originally intended.

Windows Components/Microsoft User Experience Virtualization\Settings template catalog path

Once the UEV Service has started (Enable-UEV) the SettingsTemplateCatalogPath value will be evaluated every 30 minutes. New templates discovered are registered and compiled.

Once the Template has been registered and compiled to the "Templates folder" will be read by the process UEVAppMonitor.exe and detect all defined configuration changes. These changes are then copied to the "SettingsStoragePath" as a central location.  The copy occurs every time a users logs out of a computer or every 5 minutes by default.

If the "SettingsStoragePath" is not defined in Group Policy or manually by PowerShell the UE-V agent will read your Active Directory Home Folder path and set as default. The value can be changed via PowerShell or defined specifically within Group Policy to another UNC share location i.e. \\ServerName\UEVData\%UserName%.


We had an extra registry setting for UEV that could not be removed by the ADMX templates; this settings was possibly left over from a previous revision of ADMX and had to be removed via PowerShell. Technet procedure documented here.

Remove-GPRegistryValue -Name "GPO Name" -key "HKLM\Software\Policies\Microsoft\Windows\UEV\Agent

To configure the UE-V Agent by using Windows PowerShell

Scheduled Tasks 
Runs daily and will sync the TemplateCatalog directoy specified.