SCCM Software updates automation

Software Updates synchronize daily at 14:00

Software updates classifications:

  • Select the Classifications you want SCCM WSUS to synchronize
  • Select the Products you want SCCM WSUS to synchronize

 

  • Create collections for Software Updates
    • Device Collections > Workstation Clients > Software Updates

All collections are based off of the All Workstation Clients collection

  • Software Updates Workstation – Monday
    • SCCM Resource ID %0 or %1
      • Maintenance Window – Software Updates only – 19:00-07:00
  • Software Updates Workstation – Tuesday
    • SCCM Resource ID %2 or %3
      • Maintenance Window – Software Updates only – 19:00-07:00
  • Software Updates Workstation – Wednesday
    • SCCM Resource ID %4 or %5
      • Maintenance Window – Software Updates only – 19:00-07:00
  • Software Updates Workstation – Thursday
    • SCCM Resource ID %6 or %7
      • Maintenance Window – Software Updates only – 19:00-07:00
  • Software Updates Workstation – Friday
    • SCCM Resource ID %8 or %9
      • Maintenance Window – Software Updates only – 19:00-07:00

Created saved searches in the Software Updates > All Software Updates node

All saved searches have the following rules

  • Expired = No
  • Metadata Only = No
  • Superseded = No
  • Severity = Critical or Important
  • Update Classification = Critical or Security
  • Title = does not contain Itanium
    • 2000 – 2010 – Critical and Important
    • 2011 – Critical and Important
    • 2012 – Critical and Important
    • 2013 – Critical and Important
    • 2014 – Critical and Important
    • 2015 – Critical and Important

Created saved searches in the Software Updates > All Software Updates node

All saved searches have the following rules

  • Expired = No
  • Metadata Only = No
  • Superseded = No
  • Severity = Critical or Important
  • Update Classification = Critical or Security
  • Title = does not contain Itanium
  • Required >= 1
  • Deployed = NO
    • 2000 – 2010 – Critical and Important – Required Not Deployed
    • 2011 – Critical and Important – Required Not Deployed
    • 2012 – Critical and Important – Required Not Deployed
    • 2013 – Critical and Important – Required Not Deployed
    • 2014 – Critical and Important – Required Not Deployed
    • 2015 – Critical and Important – Required Not Deployed

Created saved search in Software updates > All Software updates node

Endpoint Protection

  • Expired = No
  • Metadata Only = No
  • Superseded = No
  • Product = Forefront Endpoint Protection 2010

Created Deployment Packages for Software Updates

  • 2000 – 2010 – Critical or Important
  • 2011 – Critical and Important
  • 2012 – Critical and Important
  • 2013 – Critical and Important
  • 2014 – Critical and Important
  • 2015 – Critical and Important

Created Automatic Update Rule

  • Workstations – 2015 – Critical or Important – ADR

This rule will create a new software update group each time it is run

At the end of 2015 there should be 12 software update groups for this rule

The rule once on the 2nd Tuesday of each month at 17:00

This rule targets the BETA workstations collection

  • Date released or revised = Last month
  • Severity = Critical or Important
  • Superseded = No
  • Update Classification = Critical or Security

Created Automatic Update Rule

  • Endpoint Protection – ADR

This rule will add to an existing software update group each time it is run

The rule runs after every Software Update Synchronization

  • Product = Forefront Endpoint Protection 2010
  • Superseded = no

Created Software Update Groups based on the above saved searches

  • 2000-2010 – Critical or Important
  • 2011 – Critical or Important
  • 2012 – Critical or Important
  • 2013 – Critical or Important
  • 2014 – Critical or Important
  • 2015 – Critical or Important 2015-01-13
  • 2015 – Critical or Important 2015-02-10

Created PowerShell script to automate software updates process

The process for Software Updates is as follows:

  • All Software Updates will be deployed to the Device Collection > Departments > All Workstation Clients – BETA
  • All Software Updates will be deployed to the Device Collection > Workstation Clients > All Workstation Clients collection for PRODUCTION pushes

The following SQL Agent jobs need to be created

2nd Tuesday of the Month

        • 14:0
        • SQL Server Agent job “Set-CMSoftwareUpdatesDeploymnet -Beta -EnableMaintenanceWindows” runs as a domain account SQL server agent PowerShell proxie
          • This sets all of the Software Update Group deployments to the BETA collection and instructs the deployment to respect maintenance windows
        • 14:00
          • Software Update Point Synchronization runs (daily)
          • 14:00 + [however long it takes the synchronization process to run] – Automatic Deployment Rule “Workstations – 2015 – Critical or Important – ADR” runs
            • This will create a new Software Update Group deployed to the BETA collection that respect Maintenance Window

3rd Tuesday of the Month

      • 18:00
      • SQL Server Agent job “Set-CMSoftwareUpdatesDeploymnet -Production -EnableMaintenanceWindows” runs as a domain account SQL server agent PowerShell proxi
        • This sets all of the Software Updates Group deployments to “All Workstation Clients” collection and instructs to deployment to respect maintenance windows

1st Tuesday of the Month

    • 18:00
      • SQL Server Agent job “Set-CMSoftwareUpdatesDeploymnet -Production -DisableMaintenanceWindows” runs as a domain account SQL server agent PowerShell proxie
        • This sets all of the Software Updates Group deployments to “All Workstation Clients” collection and instructs to deployment to ignore maintenance windows

2nd Tuesday of the month

    • 17:00
      • SQL Server agent job “Start-CleanCMSoftwareUpdateGroup” runs as a domain account SQL server agent PowerShell proxie
      • This script calls scripts on the SQL server
        • This scripts cleans out Expired and Superseded updates from all Update Groups and Packages except for Endpoint protection update groups and packages.
          • NOTE: The script doesn’t work with Endpoint protection updates.

 

[CmdletBinding()]
Param
    (
    [Switch]$Beta, # This switch will target the software updates to the Beta collection,
    [Switch]$Production, #This switch will target the software updates to the Production collection
    [Switch]$EnableMaintenanceWindows, #This switch will cause the deployment to respect a clients maintenance windows
    [Switch]$DisableMaintenanceWindows, #This switch will cause the deployment to over-ride a clients maintenance windows
    [Parameter(Mandatory=$True, Position=1)]
        [string]$SCCM_Server #This parameter is the NETBios or FQDN of the SCCM Site Server
    )
    
    $BetaCollectionName = "BETA"
    $ProductionCollectionName = "All Workstation Clients"

    #$BetaCollectionName = "Beta"
    #$ProductionCollectionName = "Production"

    $PSVersion = $host.Version.Major
    Write-Verbose "PowerShell version is : $PSVersion"

    Write-Verbose "Determining SiteCode for Site Server: '$($SCCM_Server)'"

    If ($PSVersion -ge 3)
        {
        $SCCM_CimSession = New-CimSession -ComputerName $SCCM_Server
        $SiteCodeObjects = Get-CimInstance -CimSession $SCCM_CimSession -Namespace "root\SMS" -Class SMS_ProviderLocation -ErrorAction Stop
        }
    Else
        {
        $SiteCodeObjects = Get-WmiObject -ComputerName $SCCM_Server -Namespace "root\SMS" -Class SMS_ProviderLocation -ErrorAction Stop
        }

    foreach ($SiteCodeObject in $SiteCodeObjects) 
        {
        if ($SiteCodeObject.ProviderForLocalSite -eq $true) 
            {
            $SCCM_SiteCode = $SiteCodeObject.SiteCode
            Write-Verbose "SiteCode: $($SCCM_SiteCode)"
            }
        }

    If ($EnableMaintenanceWindows)
        {
        $RebootOutsideOfServiceWindows = $FALSE
        $OverrideServiceWindows = $FALSE
        Write-Verbose "RebootOutsideOfServiceWindows = $RebootOutsideOfServiceWindows"
        Write-Verbose "OverrideServiceWindows = $OverrideServiceWindows"
        }
    If ($DisableMaintenanceWindows)
        {
        $RebootOutsideOfServiceWindows = $TRUE
        $OverrideServiceWindows = $TRUE
        Write-Verbose "RebootOutsideOfServiceWindows = $RebootOutsideOfServiceWindows"
        Write-Verbose "OverrideServiceWindows = $OverrideServiceWindows"
        }
    If ($Beta)
        {
        If ($PSVersion -ge 3)
            {
            $BetaCollectionID = Get-CimInstance -CimSession $SCCM_CimSession -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_Collection where name = '$($BetaCollectionName)'"
            }
        else
            {
            $BetaCollectionID = Get-WmiObject -computername $SCCM_Server -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_Collection where name = '$($BetaCollectionName)'"
            }
        $TargetCollectionID = $BetaCollectionID.CollectionID
        Write-Verbose "Beta collection name = $($BetaCollectionID.name) and collectionID = $($BetaCollectionID.CollectionID)"
        Write-Verbose "TargetCollectionID = $TargetCollectionID"
        }
    If ($Production)
        {
        If ($PSVersion -ge 3)
            {
            $ProductionCollectionID = Get-CimInstance -CimSession $SCCM_CimSession -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_Collection where name = '$($ProductionCollectionName)'"
            }
        Else
            {
            $ProductionCollectionID = Get-WmiObject -computername $SCCM_Server -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_Collection where name = '$($ProductionCollectionName)'"
            }
        $TargetCollectionID = $ProductionCollectionID.CollectionID
        Write-Verbose "Production collection name = $($ProductionCollectionID.name)  and collectionID = $($ProductionCollectionID.CollectionID)"
        Write-Verbose "TargetCollectionID = $TargetCollectionID"
        }    
    
    If ($PSVersion -ge 3)
        {
        $SMS_UpdateGroupAssignment = Get-CimInstance -CimSession $SCCM_CimSession -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_UpdateGroupAssignment"
        }
    Else
        {
        $SMS_UpdateGroupAssignment = Get-WmiObject -ComputerName $SCCM_Server -Namespace "ROOT\SMS\Site_$($SCCM_SiteCode)" -Query "Select * from SMS_UpdateGroupAssignment"
        }
    $SoftwareUpdateDeployents = $SMS_UpdateGroupAssignment | where {$_.AssignmentName -notlike "*Endpoint*" -and $_.AssignmentName -like "*Workstation*"}
    Foreach ($Deployment in $SoftwareUpdateDeployents)
        {
        Write-Verbose $Deployment.AssignmentName
        If ($RebootOutsideOfServiceWindows -ne $NULL -and  $OverrideServiceWindows -ne $NULL)
            {
            $Deployment.RebootOutsideOfServiceWindows = $RebootOutsideOfServiceWindows
            $Deployment.OverrideServiceWindows = $OverrideServiceWindows

            If ($PSVersion -ge 3)
                {
                Set-CimInstance -CimSession $SCCM_CimSession -CimInstance $Deployment -OperationTimeoutSec 60
                }
            Else
                {                      
                $Deployment.put()
                }
            Write-Verbose "$($Deployment.AssignmentName) RebootOutsideOfServiceWindows is set to $($Deployment.RebootOutsideOfServiceWindows)"
            Write-Verbose "$($Deployment.AssignmentName) OverrideServiceWindows is set to $($Deployment.OverrideServiceWindows)"
            }
        If ($ProductionCollectionID -or $BetaCollectionID)
           {
           $Deployment.TargetCollectionID = $TargetCollectionID
           If ($PSVersion -ge 3)
               {
               Set-CimInstance -CimSession $SCCM_CimSession -CimInstance $Deployment -OperationTimeoutSec 60
               }
            Else
                {
                $Deployment.put()
                }
            Write-Verbose "$($Deployment.AssignmentName) target collectionID is set to $($Deployment.TargetCollectionID)"
            }
        }