Thursday, February 23, 2017

Powershell Function - Get Occurance of Days of the Week

If you are like me, you keep running into people asking you to set their maintenance windows to the 3rd Saturday of the month or to the 2nd & 4th Friday of each month.  To help make it a little easier I've created this function that will return what the 3rd Saturday or the 4th Friday is.  Use this to help automate creation of those Maintenance Windows that don't easily fall into SCCM's normal parameters from the console.  Enjoy!


<#
.Synopsis
    Get-OccuranceOfDayOfWeek returns a specific occurance of a day of the week such as 3rd Saturday

.DESCRIPTION

   Get-OccuranceOfDayOfWeek returns a specific occurance of a day of the week
   such as the 3rd Saturday or the 1st Friday.  Useful for dealing with
   maintenance windows that occur on specific occurances of days of the week.
   The function only returns occurances within the current month, you will
   need to modify it if you need to project further into the future.

   It is possible that the 4th or 5th occurance may return a date in the
   following month.  This is not uncommon with the 5th occurance.

.EXAMPLE
   Get-OccuranceOfDayOfWeek -DayOfWeek Tuesday -Occurance 4
   Returns: Tuesday, February 28, 2017 11:28:54 PM

.EXAMPLE
   Get-OccuranceOfDayOfWeek -DayOfWeek Saturday -Occurance 2
   Returns: Saturday, February 11, 2017 11:39:37 PM

.INPUTS
   String  - Full name of a day of the week (Monday, Tuesday, etc)
   Integer - Which occurance to return (1-4)

.OUTPUTS
   DateTime - The date of the specified occurance within the current month

.NOTES
    # Script by Mark Randol
    # randoltech.blogspot.com
#>
function Get-OccuranceOfDayOfWeek{
    [CmdletBinding(DefaultParameterSetName='OccuranceOfDayOfWeek',
                  SupportsShouldProcess=$true,
                  PositionalBinding=$false)]
    [OutputType([DateTime])]
    Param(
        # Day of the Week
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ValueFromRemainingArguments=$false,
                   Position=0,
                   ParameterSetName='OccuranceOfDayOfWeek')]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [ValidateLength(0,15)]
        [ValidateSet("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")]
        [Alias("day","dayname","dow")]
        [String]
        $DayOfWeek,

        # Occurance
        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   ValueFromRemainingArguments=$false,
                   Position=1,
                   ParameterSetName='OccuranceOfDayOfWeek')]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [ValidateSet(1,2,3,4)]
        [Alias("occ")]
        [Int]
        $Occurance
    )
    Begin{
    }
    Process{
        [Int]$TestDayNum = 0
        [Arr]$OccuranceDates = @()
        do
        {
            $TestDayNum = $TestDayNum + 1
            $TestDayName = (Get-Date -Day $TestDayNum).DayOfWeek
        }
        until ($TestDayName -eq $DayOfWeek)
        $OccuranceDate = $TestDayNum
        do{
            $OccuranceDates += @($OccuranceDate)
            $OccuranceDate = $OccuranceDate + 7
        }
        while ($OccuranceDate -lt 32)
    }
    End{
        [Int]$OutputInt = $Occurance - 1
        [DateTime]$MyOutput = (Get-Date -Year (Get-Date).Year -Month (Get-Date).Month -Day $OccuranceDates[$OutputInt]).Date
        Return $MyOutput
    }
}

[DateTime]$MyDate = (Get-OccuranceOfDayOfWeek -DayOfWeek Saturday -Occurance 2)
Write-Output $MyDate

No comments:

Post a Comment