http://www.itninja.com/question/custom-schedule-for-every-2nd-friday-of-every-month
http://www.itninja.com/blog/view/how-to-schedule-patches-on-the-3rd-saturday-of-the-month
While nothing can be done about that except for an update to the K1000, I have come up with a way to work around this in scripting (see darkhawtman's answer in the first link above for a workaround with patching).
In my organization, we need to run a cleanup script on all of our virtual machines the Sunday before patch Tuesday. Due to the CRON limitations, I wrote a Powershell function (see below) that will return specified weekday sequences.
The function can be used in multiple scenarios and has a lot of options - see the help section for details and examples.
All I had to do was add the function and an if/else statement to my script and I'm in business.
In my situation, this is what I did:
1. Upload a ps1 (mine is named CheckDate.ps1) to the Kscript with the below code
2. Schedule the script to run every Sunday at 1:00 AM
3. In the Verify section do the following:
Launch a program
Directory:
$KACE_SYS_DIR
File:
powershell.exe
Parameters:
-NoProfile -ExecutionPolicy Bypass -File $(KACE_DEPENDENCY_DIR\CheckDate.ps1))
4. Put the cleanup script in the On Success section and a Date validation failed log message in the Remediation section.
Some explanations:
1. Why not just do the 2nd Sunday of the month?
The second Sunday of the month is not always the Sunday before the 2nd Tuesday of the month.
Ex. If the 2nd Tuesday of the month is the 8th, then the 2nd Sunday would be the week after that, not before (See August 2017)
2. Why is format D required for this?
The default format of a DateTime object (Get-Date) includes the time - we only need to validate the day - if the time is in the validation, then it would return false negatives.
Function Get-WeekdaySequence { <# .DESCRIPTION This function will return the nth weekday of the input month (default is current month). For example, it can return the 2nd Tuesday of the month (Patch Tuesday). There are several parameters to expand this functionality listed below. Built from C Ashish's post on TechNet: https://social.technet.microsoft.com/Forums/ie/en-US/7b8a6966-4ea8-4b0b-8ca6-c1c8545ecc54/find-date-on-second-tuesday-of-every-month?forum=dpmpowershell .PARAMETER WeekdaySequence Accepts values 1-5, determines which day of the month to return 1=1st weekday of the month, 2=2nd weekday of the month et cetera, will fail if there are not enough weekdays in the specified month i.e. Cannot cross months .PARAMETER Weekday Accepts weekday strings as values .PARAMETER Date Accepts DateTime objects (Get-Date returns a datetime object), defaults to the current date .PARAMETER OffsetDays Accepts integers between -6 and 6, will return the specified weekday sequence + or - the number of days specified, can cross months (see examples) .PARAMETER Format Accepts a string specifying the date format desired, defaults to 'F'. See https://technet.microsoft.com/en-us/library/ee692801.aspx?f=255&MSPPError=-2147217396 for Get-Date formats. .EXAMPLE Return the 2nd Tuesday of the month (Microsoft Patch Tuesday) Get-WeekdaySequence -WeekdaySequence 2 -Weekday Tuesday .EXAMPLE Return the 2nd Tuesday in the month of 12/2018 Get-WeekdaySequence -WeekdaySequence 2 -Weekday Tuesday -Date (Get-Date 12/2018) .EXAMPLE Return the Sunday before the 2nd Tuesday of the month Get-WeekdaySequence -WeekdaySequence 2 -Weekday Tuesday -OffsetDays -2 .EXAMPLE Return the Thursday after the 3rd Tuesday of the month Get-WeekdaySequence -WeekdaySequence 2 -Weekday Tuesday -OffsetDays 2 .Example Return the Sunday before the 2nd Thursday of 11/2030 in the LongDatePattern format Get-WeekdaySequence -WeekdaySequence 2 -Weekday Thursday -Date 11/2030 -OffsetDays -4 -Format D #> Param ( [Parameter(Mandatory=$true,HelpMessage="1 for 1st Weekday of the month, 2 for 2nd weekday of the month, etc.")] [ValidateSet(1,2,3,4,5)] [ValidateNotNullOrEmpty()] $WeekdaySequence, [parameter(Mandatory=$true)] [ValidateSet("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday")] [ValidateNotNullOrEmpty()] [String]$Weekday, [datetime]$Date=(Get-Date), [ValidateRange(-6,6)] [int]$OffsetDays, [Parameter(HelpMessage="Specify the Get-Date format desired")] [ValidateNotNullOrEmpty()] [String]$Format='F' ) [datetime]$MonthBegin=$Date.Month.ToString()+'/1/'+$Date.Year.ToString() while ($MonthBegin.DayofWeek -ine $WeekDay) { $MonthBegin = $MonthBegin.AddDays(1) } $ReturnDate = $MonthBegin.AddDays(7*($WeekdaySequence-1)) if ($ReturnDate.Month -ne $Date.Month) { return (Write-Error -Exception "Invalid Sequence Number" -Message "There are not $WeekdaySequence $($Weekday)s in $($Date.Month)\$($Date.Year)") } if (!$OffsetDays) { Return (Get-Date $ReturnDate -Format $Format) } else { Return (Get-Date ($ReturnDate.AddDays($OffsetDays)) -Format $Format) } } if ((Get-WeekdaySequence -WeekdaySequence 2 -Weekday Tuesday -OffsetDays -2 -Format D) -eq (Get-Date -Format D)) { Exit 0 } else { Exit 98 }
Comments