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.