Friday, June 28, 2019

ConfigMgr Clients are no longer receiving User Deployments

Removing the Application Catalog Role within ConfigMgr was not as straight forward as i was hoping !

Like many SCCM admins historically the Application Catalog Web service Point and Website point were installed in order to deploy applications to Users.  
However, this feature is now depreciated and User deployments can be deployed without this role as the client will query a management point instead for all deployments (user and device).

I decided that this role should be removed as we were on 1810 Hotfix2 and colleagues had stated the transition was near seamless (see below regarding a reported BUG and quick fix to modify any Client setting).

The procedure to remove the App Catalog role is straight forward:
1. Remove references to App Catalog website within Client Settings.
2. Remove the Roles within the SCCM console.

In our case the removal of the website within Client Settings and the system roles was straight forward however, we saw in a few cases Clients are no longer receiving User Deployments and I thought I would write this blog to share my experience and how to detect systems in a similar state.

Lets gather the logs!

SCClient_Domain@USERNAME_1.log
Using endpoint Url: https://AppCatalogSERVER:443/CMApplicationCatalog, Windows authentication (Microsoft.SoftwareCenter.Client.Data.ACDataSource+<>c at <RefreshLocalSettingsAsync>b__13_0)
The client is looking for User deployments using the AppCatalog server website however, this does not exist and it not referenced in Client Settings.

PolicyAgent.log

Raising event:
instance of CCM_PolicyAgent_PolicyDownloadSucceeded 
Failed to compile rule "{Rule_WRC10000}": 0x8000ffff
Raising event:
instance of CCM_PolicyAgent_PolicyCompileFailed 
We can see that Policy is downloaded however fails to compile.

The Image below details the "Actual" policy applied and as you can see 'Reserved1' details the AppCatalog Website which does not exist; however the client is told to use this address to find User deployments.  As the site does not exist policy cannot exist and Software Center does not show User deployed Applications.

The Image below details the "Requested" policy applicable via Client Settings. As you can see 'Reserved1' does not detail the AppCatalog Website; the client should understand that and receive User policy from the Management Points as intended.  If this was working the SCClient_Domain@USERNAME_1.log would show details for the Management Points instead.



While I cannot explain why the Client Settings are not compiling it did conclusively show that the Site Server was offering the right policy but the client was not applying it.  Various sites have stated this behavior is a known bug and that simply changing a Client Setting would re-engage the client and allow the desired policy to apply.

This client would not update which made me wonder how many systems in the estate have this exact issue?


Using PowerShell you can query the class CCM_ClientAgentConfig namespace and report a compliance metric; this is easily deployed via ConfigMgr Baselines..

$ClientConfig =Get-WmiObject -class CCM_ClientAgentConfig -namespace "root\ccm\policy\machine\actualconfig"
IF ($ClientConfig.Reserved1 -eq "https://AppCatalogSERVER:443/CMApplicationCatalog")
{Write-host "Non-Compliant"}
ELSE
{Write-host "Compliant"}


The hope at this point is that the Agent Config client settings compile issue is limited to a small number of systems. Once the exposure of non-compliant system is understood we can see if a Remediation Script needs to be added to the Baseline.

...........Watch this space for Remediation (28/06/19)




Key Search words, phrases

CCM_PolicyAgent_PolicyCompileFailed
Policy not compiling
Remove AppCatalog

Thursday, June 13, 2019

Windows 10 - Feature Upgrade using SCCM Servicing

Software Updates - Feature Upgrade - Windows 10

Software updates within an Enterprise organisation has been fairly straight forward until you attempt to use it for Feature Upgrades of Windows 10.  SCCM is very reliable at delivering the updates (Rollups, Updates, Upgrades) and as i have previously proved is UWF aware in Windows 10.
However, the Feature Upgrade does require a bit of prep work if you do not want the new Appx Applications installed as part of the Upgrade.


Moving between the 1507-1703 branches each Feature upgrade would reinstall the Appx Applications that you previously removed. Microsoft has addressed this in the 1703 - 1709 feature upgrade and if you removed an application it will not come back.  However, if the new branch has a new application this will get installed.

Uninstalled in-box apps no longer automatically reinstall
Starting with Windows 10, version 1703, in-box apps that were uninstalled by the user won't automatically reinstall as part of the feature update installation process.
Additionally, apps de-provisioned by admins on Windows 10, version 1703 machines will stay de-provisioned after future feature update installations. This will not apply to the update from Windows 10, version 1607 (or earlier) to version 1703.
https://docs.microsoft.com/en-gb/windows/whats-new/whats-new-windows-10-version-1703

 By using the SetupConfig.ini file for an OOBE after the Feature upgrade, you will be able to ensure unwanted Appx applications are not provisioned and made available to the user; in addition to any other post action script you need to run.

Location of the SetupConfig.ini
Before the Feature Upgrade is deployed/installed via Software Center the SetupConfig.ini must be created and place locally on the system. Place the SetupConfig.ini file in the WSUS directory below; the WSUS folder does not exist by default. The Feature upgrade via SCCM will look in the WSUS folder and read the SetupConfig.ini

%systemdrive%\Users\Default\AppData\Local\Microsoft\Windows\WSUS\SetupConfig.ini


Content of the SetupConfig.ini
In the ini file i have referenced the location of a file called "SetupComplete.cmd" that will be copied from this location to the hidden Feature Upgrade folder on the root of the C drive.  c:\$WINDOWS.~BT\Sources\Scripts\SetupComplete.cmd 

[SetupConfig]
Priority=High
PostOOBE=C:\ProgramData\OSConfig\setupcomplete.cmd


Within the Setupact.log you will see the /PostOOBE switch detailed with the contents of the SetupConfig.ini file appended to the Feature Upgrade Command Line used to run the Software update.

SCCM Software Update / Feature Upgrade Command Line 

[/PreDownload /Update /Quiet  /progressCLSID 71212340-ea4e-4e40-a0ee-a26312345baf /ReportId {A81239C5-8127-4352-1234-6CE01234531F}.200 "/ClientId" "fed1234-612d-40dd-123a-cd1234ee12d" "/CorrelationVector" "/oCGdL3nj012344.7.2"   /PostOOBE C:\ProgramData\OSConfig\setupcomplete.cmd]



Content of the SetupComplete.cmd
This command file calls several command lines for post Upgrade customization.

powershell.exe -executionpolicy bypass -file C:\ProgramData\OSConfig\Start\Set-StartLayout.ps1
powershell.exe -executionpolicy bypass -file C:\ProgramData\OSConfig\Background\Set-Background.ps1
MsiExec.exe /X {F14000BE-0001-6400-0000-074957833700} /qn


Here is the cool bit.  

The script below will create the SetupConfig.ini and SetupComplete.cmd files for you dynamically.  I use this in an SCCM Baseline to create and ensure they are upto date with my modifications.


In addition to the post custom scripts to set Background wallpapers and Start menu layouts I use the baseline to set 'Deprovisioned' regsitry keys so the Appx Applications are not provisioned for new users.

Example PowerShell command to create key. See Microsoft for additional details https://docs.microsoft.com/en-us/windows/application-management/remove-provisioned-apps-during-update

New-Item 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deprovisioned\Microsoft.Messaging_8wekyb3d8bbwe' -Force

I have scripted the process to create the keys using the PackageFamilyName. Remember do not Deprovision SystemApps otherwise you may experience issues with Applications you do want to use i.e. Photos.  See Microsoft for the different categories https://docs.microsoft.com/en-us/windows/application-management/apps-in-windows-10 .  Makes reference to this in his blog (Thanks).



Next Line


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.
https://docs.microsoft.com/en-us/sccm/apps/deploy-use/create-global-conditions

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" />)


<Configuration>

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

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'
Resume-ClusterNode

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.

gg

Thursday, March 22, 2018

SCCM Software update Failure : CBS_E_STORE_CORRUPTION (KB3000850)

Scenario:
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.

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

CBS.log
 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~~6.3.1.1
CBS    Mark store corruption flag because of package: Package_33_for_KB3081320~31bf3856ad364e35~amd64~~6.3.1.1. [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~~6.3.1.8, 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


Resolution:

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

Scenario:

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.

http://SRVSUP02.Contoso.local:8530/SimpleAuthWebService/SimpleAuth.asmx
 http://SRVSUP02.Contoso.local:8530/ClientWebService/wusserverversion.xml
 http://SRVSUP02.Contoso.local:8530/Selfupdate/wuident.cab

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.


Resolution:
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.