MSI Upgrade Mechanism


In windows Installer technology there is also support for upgrading applications (MSI). Upgrading an application means removal of old application from the target machine and installation of the new application. the upgrade is performed by enforcing several rules at Component level.

Package Attributes use to determine types of Upgrade
  • Package Code
  • Product Version
  • Product Code
Upgrade Types

All updates require changing of the Package Code.

Small Update


A small update is typically a small number of files; a small update cannot rearrange the feature component structure.

Minor Update


A minor update can add files and features however cannot manipulate the current feature/component structure. A minor update also requires the Product Version property to be changed. Minor updates can be shipped as full product installers or MSP patch files.

Major Update


A major update can add files / features and also manipulate the feature component tree. The major upgrade requires that new ProductCode, PackageCode, and ProductVersion’s are set.

The following table summarizes the changes required for each update type.

Update Type   Package Code       Product Version     Product Code

  Small              Change
  Minor             Change                    Change
  Major             Change                    Change                   Change

The different upgrade types are controlled by below Windows Installer Standard actions.

FindRelatedProducts Action

The FindRelatedProducts action runs through each record of the Upgrade table in sequence and compares the upgrade code, product version, and language in each row to products installed on the system. When FindRelatedProducts detects a correspondence between the upgrade information and an installed product, it appends the product code to the property specified in the ActionProperty column of the UpgradeTable.

The FindRelatedProducts action only runs the first time the product is installed. The FindRelatedProducts action does not run during maintenance mode or uninstallation.

This action queries the following table Upgrade Table.

The FindRelatedProducts action uses the UpgradeCode property and the version and language information authored into the Upgrade table to detect installed products affected by the pending upgrade. It appends the product code of detected products to the property in the ActionProperty column of the UpgradeTable.

FindRelatedProducts only recognizes existing products that have been installed using the Windows Installer with an .msi that defines an UpgradeCode property, a ProductVersion property, and a value for the ProductLanguage property that is one of the languages listed in the Template Summary Property.

Sequence Restrictions:
The FindRelatedProducts action must come before the MigrateFeatureStates action and the RemoveExistingProducts action.

MigrateFeatureStates Action

The MigrateFeatureStates action is used during upgrading and when installing a new application over a related application. MigrateFeatureStates reads the feature states in the existing application and then sets these feature states in the pending installation. The method is only useful when the new feature tree has not greatly changed from the original.

The MigrateFeatureStates action only runs the first time the product is installed. The MigrateFeatureStates action does not run during maintenance mode or uninstallation.

MigrateFeatureStates action runs through each record of the Upgrade table in sequence and compares the upgrade code, product version, and language in each row to all products installed on the system. If MigrateFeatureStates action detects a correspondence, and if the msidbUpgradeAttributesMigrateFeatures bit flag is set in the Attributes column of the Upgrade table, the installer queries the existing feature states for the product and sets these states for the same features in the new application. The action only migrates the feature states if the Preselected property is not set.

Sequence Restrictions:
The MigrateFeatureStates action should come immediately after the CostFinalize action. MigrateFeatureStates must be sequenced in both the InstallUISequence table and the InstallExecuteSequence table.
The installer prevents MigrateFeatureStates from running in InstallExecuteSequence if the action has already run in InstallUISequence.
RemoveExistingProducts Action

The RemoveExistingProducts action goes through the product codes listed in the ActionProperty column of the Upgrade table and removes the products in sequence by invoking concurrent installations. For each concurrent installation the installer sets the ProductCode property to the product code and sets the REMOVE property to the value in the Remove field of the Upgrade table. If the Remove field is blank, its value defaults to ALL and the installer removes the entire product.

The installer only runs the RemoveExistingProducts action the first time it installs a product. It does not run the action during a maintenance installation or uninstallation.

Sequence Restrictions:
·        Between the InstallValidate action and the InstallInitialize action. In this case, the installer removes the old applications entirely before installing the new applications. This is an inefficient placement for the action because all reused files have to be recopied.
·        After the InstallInitialize action and before any actions that generate execution script.
·        Between the InstallExecute action, or the InstallExecuteAgain action, and the InstallFinalize action. Generally the last three actions are scheduled right after one another: InstallExecute, RemoveExistingProducts, and InstallFinalize. In this case the updated files are installed first and then the old files are removed. However, if the removal of the old application fails, then the installer rolls back both the removal of the old application and the install of the new application.



Windows Installer (MSI) Installation Mechanism



There are two phases to a successful installation process: acquisition and execution. If the installation is unsuccessful, a rollback phase may occur.

Acquisition
At the beginning of the acquisition phase, an application or a user instructs the installer to install a feature or an application.

The installer then progresses through the actions specified in the sequence tables of the installation database. These actions query the installation database and generate a script that gives a step-by-step procedure for performing the installation.

All actions from the UI sequence table and all actions from the beginning to the InstallFinalize action in the Execute sequence table are running during acquisition phase.  No changes to the system are done at this phase. 

Main tasks for acquisition phase are:

·        Installation is started up on the correct version of operating system, platform, etc (Launch Conditions).
·        Competitive upgrade is being installed on the system with competing product installed (Application Search).
·        License for licensed product is valid (Product Validation)
·        Selecting features to install (either through user interface or properties in the command line).
·        File Costing - making sure that target system has enough of available hard disk space to install the product.
·        Generating the installation script for the next phase.

Execution

During the execution phase, the installer passes the information to a process with elevated privileges and runs the script.

This process executes all actions from the script.  All changes to the system are done at this phase.  Depending on success or failure of the running installation script, the Execution phase will be completed by Rollback or Commit Phase.

When the Windows Installer processes the installation script for the installation of a product or application, it simultaneously generates a rollback script and saves a copy of every file deleted during the installation. These files are kept in a hidden system directory and are automatically deleted once the installation is successfully completed. If however the installation is unsuccessful, the installer automatically performs a rollback installation that returns the system to its original state.

Rollback

If an installation is unsuccessful, the installer restores the original state of the computer. When the installer processes the installation script it simultaneously generates a rollback script. In addition to the rollback script, the installer saves a copy of every file it deletes during the installation. These files are kept in a hidden, system directory. Once the installation is complete, the rollback script and the saved files are deleted.

Automatic rollback of an unsuccessful installation is the default behavior of the installer. To disable rollback during an installation use one of the following:
·        DISABLEROLLBACK Property
·        PROMPTROLLBACKCOST Property
·        DisableRollback Action
·        DisableRollback
·        EnableRollback ControlEvent
Whenever rollback is disabled, the installer sets the RollbackDisabled property.

Windows Installer accomplishes rollback by creating a rollback script. A rollback script is a file that contains a linear sequence of operations to perform, such as file and registry updates, configuration information updates, user interface notifications, and state information for other operations.

Each operation recorded in the rollback script is a direct response to an operation in the installation script.
Rollback scripts are stored in binary format. This improves efficiency, avoids the need for parsing the file, and discourages manual editing of the file.

Rollback script files (.RBS and .RBF) are backups of existing files. Files with an .RBS file extension are rollback script files, and files with an .RBF file extension are backups of existing files. Both are stored in hidden folders called Config.msi.

The Config.msi folders are created when the Msiexec.exe file starts copying from the installation point. The rollback script file (.RBS) is always stored in the Config.msi folder on the disk where the operating system is installed.

The .RBF files are stored in the Config.msi folder on the disk where the program that is being backed up currently resides. This is done so that there is no crossing of disks when the program files are being backed up. All rollback files and the Config.msi folders are deleted when the installation completes successfully.

Commit Phase
Commit Custom actions are executed upon successful completion of the installation script. If the InstallFinalize action is successful, the installer will then run any existing Commit Custom actions. The only mode parameter the installer sets in this case is MSIRUNMODE_COMMIT. 

Remember:   Acquisition phase is also known as Immediate phase when it comes to custom actions.  All Immediate custom actions are running in the context of the user performing the installation.  Immediate custom actions must not change the system.  Execution phase is also known as Deferred phase when it comes to custom actions.  Deferred custom actions usually run with elevated privileges unless they are not impersonated.  Impersonated deferred custom actions are running in the context of the user performing the installation.

App-V Virtual Environment in SCCM

In a Microsoft Application Virtualization (App-V) virtual environment in System Center Configuration Manager (Configuration Manager), deployed virtual applications can share the same file system and registry on client Windows PCs. Unlike standard virtual applications, these applications can share data with each other. 

Virtual environments are created or modified on client PCs when the application is installed or when clients next evaluate their installed applications. You can order these applications so that when multiple applications try to modify a file system or registry value, the application with the highest order takes priority.

In the Configuration Manager console, choose Software Library > Application Management > App-V Virtual Environments.

On the Home tab, in the Create group, choose Create Virtual Environment.


In the Create Virtual Environment dialog box, enter the following information:
Name. Enter a unique name for the virtual environment (maximum 128 characters).
Description. (Optional) Enter a description for the virtual environment
To add a new deployment type to the virtual environment, choose Add. You must add at least one deployment type.
In the Add Applications dialog box, specify a Group name (maximum 128 characters). You'll use this name to refer to the group of applications that you add to the virtual environment.
Choose Add, select the App-V 5 applications and deployment types that you want to add to the group, and then choose OK.
In the Add Applications dialog box, you can select Increase Order or Decrease Order to set the application that takes priority if multiple applications attempt to modify file system or registry settings in the same virtual environment.
To return to the Create Virtual Environment dialog box, choose OK.

When you're done adding groups, choose OK to create the virtual environment. The new virtual environment is displayed in the App-V Virtual Environments node of the Configuration Manager console. You can monitor the status of your virtual environments by using the App-V Virtual Environment Status report.
[!NOTE]
The virtual environment is added or modified on client PCs when the application is installed or when the client next evaluates installed applications.

Application Dependencies in SCCM

A new feature in CM 2012 is the ability to set dependencies on applications. This is something that I have been waiting for and it works really well.
For example this is my deployment for AX 2012 Client.
In this scenario I needed to create 4 different dependencies that would all be installed, this is done by pressing “Add” and then adding a dependency, if you add 2 dependencies under the same group it will be “this OR that” but if you add them in different groups it will be “this AND that”.
You can for example have one group and add different versions of Visual C++ Redistributable if the application does not require the latest version it will check if any of those versions are installed, if any of those versions are installed it will skip it.
If you add 2 dependencies under the same group you can also set priority, if none of the dependencies are installed the application with the highest priority is the first one to be installed, the best way here is to only check “Auto Install” on the application you want to install if the device is not satisfying.
A dependency doesn’t have to be something that the application you are installing requires it can be anything.
I created a bunch of applications in a folder I call “Pre Reqs\Microsoft” with the most common pre requisites like SQL Native Client etc etc, stuff that I can use over and over again.
When you deploy an application that have dependencies linked to it the SCCM Client will check what decencies is already installed, if none are installed it will automatically download them and install.
This also works when doing it via task sequence.
If you check Software Center you will see the number of components it downloads if you have 4 dependencies and 1 is installed it will say downloading 4 components (3 dependencies and the program itself)
One thing to keep in mind is that if a dependency fails to install the whole deployment fails. You can see what dependency failed under deployment monitoring. I had one case where my C++ 2010 was an older version and the deployment failed because a newer version was already installed on the computer.

Windows Updates Scan Issue on Client machine

As most of administrator are suffering from the issue now to fix the WSUS scan error on the client machine, have created a powershell script to fix most of the error code from the client machine.

Below script will Fix below error code from the WUAHandler.log and Windowsupdate.log file form the client machine.

SCCMReport Last scan error code   WUAHandler     Log error code   Error Description
-2147467259   0x80004005 E_Fail  
-2147467262 0x80004002 E_NOINTERFACE No such interface supported 
-2147024891 0x80070005 ERROR_ACCESS_DENIED or E_ACCESS_DENIED The authentication method is not supported. - CoCreateInstance(IBackgroundCopyManager) fails with E_ACCESSDENIED (0x80070005) in this condition 
-2147024883 0x8007000D The data is invalid.* The data is invalid.* 
-2147023838 0x80070422 ERROR_SERVICE_DISABLED The service cannot be started. If BITS service is disabled by the Administrator, then this error will be seen. 
-2147012894 0x80072EE2 ERROR_INTERNET_TIMEOUT The request has timed out.
-2145107961 0x80244007 WU_E_PT_SOAPCLIENT_SOAPFAULT error codes.Same as SOAPCLIENT_SOAPFAULT - SOAP client failed because there was a SOAP fault for reasons of WU_E_PT_SOAP_* 
-2145107952 0x80244010 WU_E_PT_EXCEEDED_MAX_SERVER_TRIPS The number of round trips to the server exceeded the maximum limit. 
Copy the below content to a file and name it as WSUS_Fix.ps1 and run it on the machine where your are facing the error.

$ErrorActionPreference = "SilentlyContinue"
[string] $systems= "Localhost"
If ($Error) {
$Error.Clear()
}

## Log Files location and write log function
$Logfile = "C:\Windows\Temp\$(gc env:computername).log"
Function LogWrite
{
   Param ([string]$logstring)
   Add-content $Logfile -value $logstring
}

## Stop WUAUSERV service
$ServStat = (Get-Service "WUAUSERV").Status
$Check = [String]::Compare($ServStat, "Running", $True)
If ($Check -EQ 0) {
LogWrite "`n"
LogWrite -ForegroundColor Yellow "`tStopping Automatic Update Service ..."
Stop-Service "WUAUSERV" | Out-Null
LogWrite -ForegroundColor Yellow "`tAutomatic Update Service Stopped"
}

## Delete the SUSClientID
$Res = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name SUSClientID).SUSClientID
LogWrite -ForegroundColor Yellow "tRe-Configuring Windows Update Settings ..."
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "SusClientID"

## Rename The SoftwareDistribution Folder

LogWrite "Starting to Rename The SoftwareDistribution Folder"
LogWrite "Checking if OLD_SoftwareDistribution folder exists if found will remove it.."
If (Test-Path "C:\Windows\OLD_SoftwareDistribution") {
LogWrite "OLD_SoftwareDistribution folder exists will start deleting the folder..."
Remove-Item -Path "C:\Windows\OLD_SoftwareDistribution" -Force -Recurse
LogWrite "OLD_SoftwareDistribution folder deleted successfully!"
}
If (Test-Path "C:\Windows\SoftwareDistribution") {
LogWrite "SoftwareDistribution folder exists will start deleting the folder..."
Rename-Item "C:\Windows\SoftwareDistribution" "OLD_SoftwareDistribution"
LogWrite "SoftwareDistribution folder deleted successfully!"
}

## Rename The Registry.Pol Files
If (Test-Path "C:\Windows\System32\GroupPolicy\Machine") {
LogWrite "Registry.pol file exists will start deleting the file..."
Remove-Item -Path "C:\Windows\System32\GroupPolicy\Machine\OLD_Registry.pol" -Force -Recurse
LogWrite "Registry.pol file deleted successfully!"
}
If (Test-Path "C:\Windows\System32\GroupPolicy\Machine") {
LogWrite "Registry.pol exists will start renaming the file..."
Rename-Item "C:\Windows\System32\GroupPolicy\Machine\Registry.pol" "OLD_Registry.pol"
LogWrite "Registry.pol Rename successfully!"
}

## Register all the DLL files of WUSU.
LogWrite "Started to Register all the DLL files of WUSU..."
regsvr32.exe /s "c:\Windows\system32\Actxprxy.dll"
regsvr32.exe /s "c:\Windows\system32\Atl.dll"
regsvr32.exe /s "c:\Windows\system32\Browseui.dll"
regsvr32.exe /s "c:\Windows\system32\cryptdlg.dll"
regsvr32.exe /s "c:\Windows\system32\dssenh.dll"
regsvr32.exe /s "c:\Windows\system32\gpkcsp.dll"
regsvr32.exe /s "c:\Windows\system32\initpki.dll"
regsvr32.exe /s "c:\Windows\system32\jscript.dll"
regsvr32.exe /s "c:\Windows\system32\Mshtml.dll"
regsvr32.exe /s "c:\Windows\system32\Msjava.dll"
regsvr32.exe /s "c:\Windows\system32\Mssip32.dll"
regsvr32.exe /s "c:\Windows\system32\msxml.dll"
regsvr32.exe /s "c:\Windows\system32\msxml2.dll"
regsvr32.exe /s "c:\Windows\system32\Msxml3.dll"
regsvr32.exe /s "c:\Windows\system32\Oleaut32.dll"
regsvr32.exe /s "c:\Windows\system32\rsaenh.dll"
regsvr32.exe /s "c:\Windows\system32\sccbase.dll"
regsvr32.exe /s "c:\Windows\system32\shdocvw.dll"
regsvr32.exe /s "c:\Windows\system32\shell32.dll"
regsvr32.exe /s "c:\Windows\system32\slbcsp.dll"
regsvr32.exe /s "c:\Windows\system32\softpub.dll"
regsvr32.exe /s "c:\Windows\system32\Urlmon.dll"
regsvr32.exe /s "c:\Windows\system32\vbscript.dll"
regsvr32.exe /s "c:\Windows\system32\wintrust.dll"
regsvr32.exe /s "c:\Windows\system32\wuapi.dll"
regsvr32.exe /s "c:\Windows\system32\wuaueng.dll"
regsvr32.exe /s "c:\Windows\system32\wuaueng1.dll"
regsvr32.exe /s "c:\Windows\system32\wucltui.dll"
regsvr32.exe /s "c:\Windows\system32\wups.dll"
regsvr32.exe /s "c:\Windows\system32\wups2.dll"
regsvr32.exe /s "c:\Windows\system32\wuweb.dll"
LogWrite "DLL registration completed successfully!"

## Start WUAUSERV service
Start-Service "WUAUSERV"
Invoke-Command -Script {wuauclt /resetauthorization /detectnow} | Out-Null
Invoke-Command -Script {wuauclt /reportnow} | Out-Null
LogWrite -ForegroundColor Yellow "`tExecution Complete."
LogWrite "`n"

#Group Policy Update
LogWrite "Requesting for Policy Changes..."
gpupdate /Force

## Add UseWUServer DWord Value to 1

$RegKey = “HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU”
if (-Not(Test-Path “$RegKey”)) {
LogWrite "checking if UseWUServer Registry key exists if not will write the registry value...."
New-Item -Path “$($RegKey.TrimEnd($RegKey.Split(‘\’)[-1]))” -Name “$($RegKey.Split(‘\’)[-1])” -Force | Out-Null
}
Set-ItemProperty -Path “$RegKey” -Name “UseWUServer” -Type Dword -Value “1”
LogWrite "Adding UseWUServer Registry key value completed successfully!"

$RegKey = “HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate”
if (-Not(Test-Path “$RegKey”)) {
LogWrite "checking if UseWUServer Registry key exists if not will write the registry value...."
New-Item -Path “$($RegKey.TrimEnd($RegKey.Split(‘\’)[-1]))” -Name “$($RegKey.Split(‘\’)[-1])” -Force | Out-Null
}
Set-ItemProperty -Path “$RegKey” -Name “WUServer” -Type String -Value “http://<WSUS.SERVER>:8530”
Set-ItemProperty -Path “$RegKey” -Name “WUStatusServer” -Type String -Value “http://<WSUS.SERVER>:8530”
LogWrite "Adding WUServer and WUStatusServer Registry value completed successfully!"

## Start Machine Policy Retrivel and Evaluation Cycle
LogWrite "Start Machine Policy Retrivel and Evaluation Cycle..."
Invoke-WmiMethod -ComputerName $systems -Namespace root\ccm -Class sms_client -Name TriggerSchedule -ArgumentList '{00000000-0000-0000-0000-000000000021}' -ErrorAction Stop
LogWrite "Sleeping for 150 Seconds..."
Start-Sleep -Seconds 150

## Start Software Update Scan Cycle
LogWrite "Start Software Update Scan Cycle..."
Invoke-WmiMethod -ComputerName $systems -Namespace root\ccm -Class sms_client -Name TriggerSchedule -ArgumentList '{00000000-0000-0000-0000-000000000113}' -ErrorAction Stop
LogWrite "Sleeping for 150 Seconds..."
Start-Sleep -Seconds 150

## Start Software Update Deployment Evaluation Cycle
LogWrite "Start Software Update Deployment Evaluation Cycle..."
Invoke-WmiMethod -ComputerName $systems -Namespace root\ccm -Class sms_client -Name TriggerSchedule -ArgumentList '{00000000-0000-0000-0000-000000000108}' -ErrorAction Stop
LogWrite "Sleeping for 150 Seconds..."
Start-Sleep -Seconds 150

If ($Error) {
$Error.Clear()
}

WSUS Installation Error Code with Solution

Below are some of the error code with the solution to fix them to make sure our machines are getting patched, will keep updating the error with solution.

Update install error - 0x80070308:-
Solution:-
1. Connect to remote computer CMD
"C:\My Documents\SCCM Tools\PSTools\PsExec.exe" \\MachineName cmd
2. run below commands
REG LOAD HKLM\COMPONENTS C:\Windows\System32\config\COMPONENTS
REG DELETE HKLM\COMPONENTS /V PendingRequired /f
3. Run the scan cycles.
_________________________________________________

Get list of Patches installed on remote Computer using Powershell:-
Get-Hotfix -computername MachineName | Select HotfixID, Description, InstalledOn | Sort-Object InstalledOn
__________________________________________________
Update install error - 0X80070543

Solution:-
1) Click Start, click Run, type dcomcnfg.exe, and then click OK.
2) Click OK if you receive the UAC prompt.
3) In the console tree, expand Component Services, and then expand Computers.
4) Right-click My Computer, then click Properties.
5) Click the Default Properties tab.
6) Select Connect in the Default Authentication Level set to Connect.
7) Select Indentify in the Default Impersonation Level list.
8) Click OK, and then click Yes to confirm the selection.
9) Close Component Services console."
or
Add the below registry remotely on the machine.
REG ADD HKLM\SOFTWARE\Microsoft\Ole /v LegacyAuthenticationLevel /t REG_DWORD /d 2 /f
___________________________________________________

When you find WSUS Server is set to NULL in Windowsupdate.log File perform the below steps to fix the issue
WSUS Server :<NULL>
Solution Add below registry by connecting to registry remotely or with Pxeexec.
REG ADD HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate /v WUServer /t REG_SZ /d http://SUPSERVERNAME:8530 /f
REG ADD HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate /v WUStatusServer /t REG_SZ /d http://SUPSERVERNAME:8530 /f
REG ADD HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU /v UseWUServer /t REG_DWORD /d 1 /f

Create configuration Item for Software Update installation

Create configuration Item to resolve past due will be expired,Waiting for install and pending verification software update deployment issues.
Open SCCM console → Asset and compliance → Compliance settings→ right click on Configuration items and Create New configuration Item.
Capture1
Click Next and add supported platforms as per your requirements.
Capture2
Click Next → on settings page click on new to define a new setting.
Capture3
Capture4
Now Add Discovery script and remediation script.
Discovery script will provide return code 1 if there is any pending updates.
Remediation script will remediate if Discovery script returns 1.
Discovery Script:-
$wmicheck=$null
$wmicheck =Get-WmiObject -namespace root\cimv2 -Class Win32_BIOS -ErrorAction SilentlyContinue
if ($wmicheck)
{
# Get list of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK for missing updates
$TargetedUpdates= Get-WmiObject -Namespace root\CCM\ClientSDK -Class CCM_SoftwareUpdate -Filter ComplianceState=0
$approvedUpdates= ($TargetedUpdates |Measure-Object).count
$pendingpatches=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -ne 8} |Measure-Object).count
$rebootpending=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -eq 8} |Measure-Object).count
if ($pendingpatches -gt 0)
{
Return(1)
}
else {Return(0) }
}
Remediation Script:-
#Resolve past due expired and pending verification issue for software update deployment.#Resolve past due expired and pending verification issue for software update deployment.
$wmicheck=$null$wmicheck =Get-WmiObject  -namespace root\cimv2 -Class Win32_BIOS -ErrorAction SilentlyContinueNew-EventLog -LogName Application -Source SyncStateScript -ErrorAction SilentlyContinueif ($wmicheck){# Get list of all instances of CCM_SoftwareUpdate from root\CCM\ClientSDK for missing updates $TargetedUpdates= Get-WmiObject  -Namespace root\CCM\ClientSDK -Class CCM_SoftwareUpdate -Filter ComplianceState=0$approvedUpdates= ($TargetedUpdates |Measure-Object).count$pendingpatches=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -ne 8} |Measure-Object).count$rebootpending=($TargetedUpdates |Where-Object {$TargetedUpdates.EvaluationState -eq 8} |Measure-Object).countif ($pendingpatches -gt 0) {  try { $MissingUpdatesReformatted = @($TargetedUpdates | ForEach-Object {if($_.ComplianceState -eq 0){[WMI]$_.__PATH}})  # The following is the invoke of the CCM_SoftwareUpdatesManager.InstallUpdates with our found updates  $InstallReturn = Invoke-WmiMethod  -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$MissingUpdatesReformatted) -Namespace root\ccm\clientsdk     Write-EventLog -LogName Application -Source SyncStateScript -EventId 666 -EntryType Information -Message “Targeted Patches :$approvedUpdates,Pending patches:$pendingpatches,Reboot Pending patches :$rebootpending,initiated $pendingpatches patches for install”  } catch {Write-EventLog -LogName Application -Source SyncStateScript -EventId 667 -EntryType Information -Message “pending patches – $pendingpatches but unable to install them ,please check Further”  }}else {Write-EventLog -LogName Application -Source SyncStateScript -EventId 668 -EntryType Information -Message “Targeted Patches :$approvedUpdates,Pending patches:$pendingpatches,Reboot Pending patches :$rebootpending,Compliant”  }}
First add Discovery script as shown below.
Capture5
Click on Compliance rules and define new rule to fetch return code of the discovery script and remediate through remediation script according to the return code defined in the compliance rule.
Capture2


Add remediation script.
Capture8
Capture9
Click Ok and Then Next to finish the wizard.
Now Create a Confguration baseline and add the already created configuration item to it.
Capture9
Capture10
Capture11
Now click ok and complete baseline creation.
Right click on created baseline and select deploy.
Capture13
Capture15
It has been tested and working fine in my current organisation. If you have any doubt or need help then please comment.
If you don’t want to follow this process then there is an another method to achieve the compliance is to  deploying directly the attached remediation script to the affected machines.
Thanks for reading.

5 SCCM Tools

Client Center  Config uration  Manager Here is one of my favorite SCCM tool and probably the most useful I have ever seen!  Client Cent...