Home > PowerShell, SCCM2012, WSUS > PoSH: Get-PatchDate for SCCM

PoSH: Get-PatchDate for SCCM

Anyone who knows me, knows that if I have to do something 3 times, I’m going to do two things:

1) Try to automate it

2) Get angry at you

Lucky for me, anger leads to productivity Smile

The PowerShell that follows allows me to get the dates for patching for a site I’m doing work for.  It would also work for at least two others that I’ve done similar work for, so it’ll definitely be of some broader use than just one site.

The general gist of the script is to find the dates for updating.  This site does their updates with the following schedule:

  • DEV1 group happens on the First Thursday of the month – this covers a middle of week testing during business hours
  • PROD1 group happens on the Second Saturday following the DEV1 group – 9 days later. This handles systems that can be updated in the evening on a weekend.
  • PROD2 group happens on the Sunday following PROD1 – this handles systems that can be done on a weekend, but might be doing some manner of processing at night – batch updates, backup servers, etc.
  • PROD3 group happens on the Monday following PROD2 – this handles systems that could not  be updated at night or during the weekend.

The problem is that the 9 days after DEV is not always “2nd Saturday”, sometimes it is “3rd Saturday” – if the first of the month occurs on a Fri/Sat/Sun.  Equally, #nd Saturday may be #nd+1 Sunday.  So to try to figure this out, I found a script that gets “WeekDayInMonth”.  That got me the basics, but then I still needed to get MY dates from it.

# Created By: Avram Woroch
# Purpose: 
#   To obtain the dates in the month for performing Windows Updates.
#   Currently assumes "First Thursday" for DEV, then PROD1 occurs the second Saturday following
#   Followed by PROD2 the next Sunday and PROD3 the next Monday.  
#   We aren't trying to figure out which Sat/Sun/Mon of the month it is, as we can count forward 
#   from the DEV date.
# Usage:
#    Get-PatchDates.ps1 
#       Loads the script
#    Get-PatchDate <optional MONTH in ##> <optional YEAR in ####>
#      If not MM YYYY are provided, the script will assume CurrentMonth and CurrentYear
#      eg: Get-PatchDate 12 2014 - will find Dec 2014
#          Get-PatchDate - will find Nov 2014 (when the script was written)
# 4 Variables are populated, to be leveraged by SCCM scripts
# Get-WeekDayInMonth portion borrowed from 
# http://blog.tyang.org/2012/09/03/powershell-function-get-weekdayinmonth/

Function Get-WeekDayInMonth ([int]$Month, [int]$year, [int]$WeekNumber, [int]$WeekDay)
    $FirstDayOfMonth = Get-Date -Year $year -Month $Month -Day 1 -Hour 0 -Minute 0 -Second 0
    #First week day of the month (i.e. first monday of the month)
    [int]$FirstDayofMonthDay = $FirstDayOfMonth.DayOfWeek
    $Difference = $WeekDay - $FirstDayofMonthDay
    If ($Difference -lt 0)
        $DaysToAdd = 7 - ($FirstDayofMonthDay - $WeekDay)
    } elseif ($difference -eq 0 )
        $DaysToAdd = 0
    }else {
        $DaysToAdd = $Difference
    $FirstWeekDayofMonth = $FirstDayOfMonth.AddDays($DaysToAdd)
    Remove-Variable DaysToAdd
    #Add Weeks
    $DaysToAdd = ($WeekNumber -1)*7
    $TheDay = $FirstWeekDayofMonth.AddDays($DaysToAdd)
    If (!($TheDay.Month -eq $Month -and $TheDay.Year -eq $Year))
        $TheDay = $null

Function Get-PatchDate ([int]$Month, [int]$Year)
  $DayMonth = $Month
  $DayYear = $Year
  If ($Month -eq "")
  If ($Year -eq "")
$PatchDay=(Get-WeekDayInMonth -month $DayMonth -year $DayYear -weeknumber 1 -weekday 4)
$PatchDayDEV1 = (Get-Date $PatchDay).AddDays(+0)
$PatchDayPROD1 = (Get-Date $PatchDay).AddDays(+9)
$PatchDayPROD2 = (Get-Date $PatchDay).AddDays(+10)
$PatchDayPROD3 = (Get-Date $PatchDay).AddDays(+11)

Write-Host ""
Write-Host "In the year"$DayYear" and the month of "$DayMonth":"
Write-Host "  Group DEV1 will be patched on: "$PatchDayDEV1 
Write-Host "  Group PROD1 will be patched on:"$PatchDayPROD1 "- 9 days later"
Write-Host "  Group PROD2 will be patched on:"$PatchDayPROD2 "- 10 days later"
Write-Host "  Group PROD3 will be patched on:"$PatchDayPROD3 "- 11 days later"

I’m still working on how to make this “Better”, and I’ll likely seek input from my resident PowerShell guru (http://pleasework.robbievance.net/) but until then I’m trying it on my own.  The usage is:

“Get-PatchDates.ps1” to load the module

“Get-PatchDate” with no parameters to get the dates for the current month.  Or we can specify the MM YYYY on the command line to override.  But this way allows me to set the script up to run on the first of the month, and get the dates for that month.

So what we end up with is output of:

PS C:\WINDOWS\system32> Get-PatchDate 

In the year 2014 and the month of 11:
  Group DEV1 will be patched on:  11/6/2014 12:00:00 AM
  Group PROD1 will be patched on: 11/15/2014 12:00:00 AM - 9 days later
  Group PROD2 will be patched on: 11/16/2014 12:00:00 AM - 10 days later
  Group PROD3 will be patched on: 11/17/2014 12:00:00 AM - 11 days later

I’m going to have a bunch of posts coming up for some SCCM 2012 Windows Server Windows Updates scripting, that I hope will help someone avoid having to deal with a situation where you hear “So every month, we do this process, and it’s currently manual….”

These would also be able to be workable with some WSUS general scripting, as long as modified GPO’s accordingly in a script and/or reconfigured groups of servers WSUS registry settings.

Here’s hoping this all works…


I came back realizing I was going to probably want to store the various dates as variables in memory to call in later scripts or functions in this process.  Turns out, I thought of that (or perhaps, just got lucky…) when I used the variable names $PatchDayXXXXXX – which does exactly that.  Later on, I’m going to use the PatchGroup Descriptions to designate a delimited Start and Stop time, so I can use those variables in my maintenance window and deadline designations. 

Categories: PowerShell, SCCM2012, WSUS
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: