Skip to content

Instantly share code, notes, and snippets.

@p0w3rsh3ll
Created June 12, 2017 11:55
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save p0w3rsh3ll/93026b43919550524ac645ce994a758e to your computer and use it in GitHub Desktop.
Function Get-DayInMonth {
[CmdletBinding()]
Param(
[parameter(ParameterSetName='ByDate',Mandatory,ValueFromPipeline)]
[System.DateTime]$Date,
[switch]$asDate,
[Parameter(Mandatory)]
[ValidateSet('First','Second','Third','Fourth','Last')]
[string]$Position
)
DynamicParam {
$Dictionary = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
#region helper function
Function New-ParameterAttributCollection {
[CmdletBinding()]
Param(
[Switch]$Mandatory,
[Switch]$ValueFromPipeline,
[Switch]$ValueFromPipelineByPropertyName,
[String]$ParameterSetName,
[Parameter()]
[ValidateSet(
'Arguments','Count','Drive','EnumeratedArguments','Length','NotNull',
'NotNullOrEmpty','Pattern','Range','Script','Set','UserDrive'
)][string]$ValidateType,
[Parameter()]
$ValidationContent
)
Begin {
}Process {
$c = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$a = New-Object System.Management.Automation.ParameterAttribute
if ($Mandatory) {
$a.Mandatory = $true
}
if ($ValueFromPipeline) {
$a.ValueFromPipeline = $true
}
if ($ValueFromPipelineByPropertyName) {
$a.ValueFromPipelineByPropertyName=$true
}
if ($ParameterSetName) {
$a.ParameterSetName = $ParameterSetName
}
$c.Add($a)
if ($ValidateType -and $ValidationContent) {
try {
$c.Add((New-Object "System.Management.Automation.Validate$($ValidateType)Attribute"(
$ValidationContent
)))
} catch {
Throw $_
}
}
$c
}
End {}
}
#endregion
#region param Day
$Dictionary.Add(
'Day',
(New-Object System.Management.Automation.RuntimeDefinedParameter(
'Day',
[string],
(New-ParameterAttributCollection -Mandatory -ValidateType Set -ValidationContent (
[System.Enum]::GetValues([System.DayOfWeek]) | ForEach-Object { $_.ToString() }
))
))
)
#endregion
#region param Month
$Dictionary.Add(
'Month',
(New-Object System.Management.Automation.RuntimeDefinedParameter(
'Month',
[int],
$(
$HT = @{
Mandatory = $true;
ValidateType = 'Range'
ParameterSetName = 'ByString'
ValueFromPipelineByPropertyName=$true
ValidationContent = (1,12)
}
;
New-ParameterAttributCollection @HT
)
))
)
#endregion
#region param Year
$Dictionary.Add(
'Year',
(New-Object System.Management.Automation.RuntimeDefinedParameter(
'Year',
[int],
$(
$HT = @{
Mandatory = $true;
ValidateType = 'Pattern'
ParameterSetName = 'ByString'
ValueFromPipelineByPropertyName=$true
ValidationContent = '^\d{4}$'
}
;
New-ParameterAttributCollection @HT
)
))
)
#endregion
$Dictionary
}
Begin {
$alldays = @()
Write-Verbose -Message "ParamSetName is $($PSCmdlet.ParameterSetName)"
}
Process {
# Validate the Day string passed as parameter by casting it into
if (-not([System.DayOfWeek]::$($PSBoundParameters['Day']) -in 0..6)) {
Write-Warning -Message 'Invalid string submitted as Day parameter'
return
} else {
$Day = $PSBoundParameters['Day']
}
Switch ($PSCmdlet.ParameterSetName) {
ByString {
$Month = $PSBoundParameters['Month']
$Year = $PSBoundParameters['Year']
break
}
ByDate {
$Month = $Date.Month
$Year = $Date.Year
break
}
default{}
}
Write-Verbose -Message "Day is $($Day)"
Write-Verbose -Message "Month is $($Month)"
# There aren't 32 days in any month so we make sure we iterate through all days in a month
0..31 | ForEach-Object -Process {
$evaldate = (Get-Date -Year $Year -Month $Month -Day 1).AddDays($_)
if ($evaldate.Month -eq $Month) {
if ($evaldate.DayOfWeek -eq $Day) {
$alldays += $evaldate.Day
}
}
}
# Output
Switch($Position) {
'First' { $p = 0 ; break }
'Second' { $p = 1 ; break }
'Third' { $p = 2 ; break }
'Fourth' { $p = 3 ; break }
'Last' { $p = -1 ; break }
default {}
}
if ($asDate) {
Get-Date -Year $Year -Month $Month -Day $alldays[$p]
} else {
$alldays[$p]
}
}
End {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment