How to Automate Patching with SCCM

Patching is a pain in the a, I mean, neck. SCCM has improved it somewhat but it still requires human intervention. I have finally worked out how to completely automate my patching, And it even scales.

Set up SCCM with a Software Update Point.

  • This will require WSUS installed in your environment.

  • Configure SUP to synchronize with WSUS on a schedule of your choosing.
    • Since we wanted to patch weekly, we chose to sync once every Wednesday.
  • Create an ADR (Automatic Deployment Rule)
    • This selects, downloads and deploys(to nothing) the updates you want.
    • All patches for the past 30 days
    • Download and add to Patches deployment package
    • Really this should be named after the year. So each year it would get renamed
    • ADR is scheduled for 3 pm each Tuesday
  • Powershell scheduled task to move updates to current year’s update group and deploy
    • The following runs as a sched task every Tuesday at 5 pm.
    • It copies all patches from the ADR Deployment group to the yearly patching group.
    • And deploys
   
<#
    .Description
        copies the patches downloaded via ADR to yearly software update group.  Then deploys the update group.

    .Note
        Author: Jeff Buenting
        Date: 28 Jul 2015
#>

$Year = Get-Date -UFormat %Y

$SoftwareUpdateGroup = "$Year - Patches"
$Collection = "Deploy Patches"

import-module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')

set-location RWV:
        
# ----- "If Software Update Group does not exist, Create it.  This is needed for year changes."
if ( (Get-CMSoftwareUpdateGroup -Name $SoftwareUpdateGroup) -eq $Null ) {
    New-CMSoftwareUpdateGroup -Name $SoftwareUpdateGroup -UpdateId (Get-CMSoftwareUpdate -UpdateGroupName 'Patches').CI_ID
}

# ----- Copy patches from ADR SUG to Year SUG
Get-CMSoftwareUpdate -UpdateGroupName 'Patches' | Add-CMSoftwareUpdateToGroup -softwareUpdateGroupName $SoftwareUpdateGroup

# ----- This check is required as deploying with same name will have duplicate deployments
$ExistingDeployment = Get-CMDeployment -CollectionName $Collection | where SoftwareName -eq $SoftwareUpdateGroup
$ExistingDeployment

if ( $ExistingDeployment ) {
    # ----- Write-Verbose "Deployment $($ExistingDeployment.SoftwareName) Found for collection $Collection"
    $ExistingDeployment | Remove-CMDeployment -Force
}

# ----- Deploy Software update
Start-CMSoftwareUpdateDeployment -SoftwareUpdateGroupName $SoftwareUpdateGroup -CollectionName $Collection -DeploymentName "Patching" -DeploymentType Required -EnforcementDeadlineDay (get-date -UFormat '%Y/%m/%d')
  • Create Patching Collections.
    • Sub collections are part of the master Patching collection. This allows you to deploy to only one collection and have different maintenance windows on each sub collection

Optional SCVMM Hyper-v Servers

  • Setup Client on Hyper-V hosts. Exclude them from patching. This is strictly for reporting
  • Powershell Scheduled task to migrate updates from SCCM Current year softwear update group to SCVMM.
   
Import-Module C:\Scripts\scvmm\SCVMM_Module.psm1 -force

$Year = Get-Date -UFormat %Y

Get-CMSoftwareUpdate -UpdateGroupName "$Year - Patches" | Select-Object -ExpandProperty ArticleID | Get-SCVMMUpdate  -Products 'Windows Server 2012 R2','Microsoft Azure Site Recovery Provider' | Add-SCVMMUpdateToBaseline -BaselineName "$Year - Patches" -Verbose 
  • SCVMM setup schedule to execute consistency check and remediate if needed.