Private/Get-VmPowerScheduleUpWindow.ps1
|
function Get-VmPowerScheduleUpWindow { <# .SYNOPSIS The shortest stretch a schedule wants its machines up for, in minutes. .DESCRIPTION A schedule is sampled, not obeyed. The controller wakes on a timer and asks what each schedule wants at that moment, so a window narrower than the gap between two wakes is one the controller can walk straight past: it is closed again by the time anybody looks. The machine is never started, every run reports MatchesSchedule, and nothing anywhere says why. Measured rather than derived from the action list, because a Start and the Deallocate that ends it can sit on different weekdays, and an exception date can remove either of them. Occurrences over a fortnight are paired up - each Start with the Deallocate that follows it - and the shortest pair is the answer. Returns nothing for a schedule that only ever starts machines. A window with no end is not a short one. .PARAMETER Schedule An expanded schedule, as Expand-VmPowerSchedule returns it. .PARAMETER FromUtc Where to start looking. Defaults to now. #> [CmdletBinding()] [OutputType([int])] param( [Parameter(Mandatory)] $Schedule, [Parameter()] [datetime]$FromUtc = [datetime]::UtcNow ) $occurrences = @(Get-VmPowerScheduleOccurrence -Schedule $Schedule -FromUtc $FromUtc -Days 14 | Where-Object { $_.Action -in $script:ScheduleActions }) $shortest = $null $openedAt = $null foreach ($occurrence in $occurrences) { if ($occurrence.Action -eq 'Start') { # A second Start without a Deallocate between them is not a shorter window, it is the # same one being reaffirmed. Keep the earliest. if ($null -eq $openedAt) { $openedAt = $occurrence.Utc } continue } if ($null -eq $openedAt) { continue } $minutes = [int]([math]::Round(($occurrence.Utc - $openedAt).TotalMinutes)) if ($null -eq $shortest -or $minutes -lt $shortest) { $shortest = $minutes } $openedAt = $null } if ($null -ne $shortest) { $shortest } } |