Windows Scheduler每个月的第二个和第三个周末

是否可以使用Windows计划程序在每个月的第二个和第三个星期六的星期天运行任务?

长版本

我们有一些维护脚本,使我们的系统在星期六下午六点打补丁,星期天上午六点返回在线; 与维护(如Windows更新)发生在这些时间之间。 系统通常在每个月的第一个和最后一个周末都需要,所以我们只在每个月的第二个和第三个周末进行维护。

一个潜在的问题是,如果一个月在星期天开始,第三个星期六我们将系统离线,但星期天在线上的脚本将在一周前(即在本月的第三个星期日)运行。

这在脚本中很容易解决; 只是安排每周运行的任务,然后检查是否是第二或第三个星期六之后的星期天,以确定是继续运行还是终止。

然而; 有没有更好的办法?

2016年只有一个月受到影响(5月)。 为什么不从工作计划中排除May并手动运行脚本,或者为May创build单独的计划任务? 通过创build两个计划任务,您可以轻松地将其扩展到未来的几年。 按照预定义的时间表运行,但不包括那些在星期天开始的月份和仅包含星期天开始的月份的月份。

2016年有一个受影响的月份,接下来的四年里每两年一个,到2021年一个月。

注意:我最后只是在代码的开头添加一个脚本,以确定是否在窗口中,然后让调度程序每周运行代码。

param ( [string]$ScriptPath ,[int]$StartDay = 10 ,[int]$EndDay = 24 ) # # Only run the given script if the current date falls on a weekend between the start and end dates (is designed specifically to cope # with tasks initiated over weekends, so requires that both the saturday and sunday of the current date fall in this window) # function Test-DateIsInMaintenanceWindow { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)] [System.DateTime]$Date = (Get-Date) , [int]$StartDay = 10 , [int]$EndDay = 24 ) begin { if($StartDay -ge $EndDay) { throw "We expect the start date to be before the end date; logic for these dates being the same, or switched (ie to cover crossing a month boundary) are beyond the designed requirements" } $EndDayLocal = $EndDay - 1 #we only test the Sat / we want to ensure we account for the following Sun } process { [boolean]$IsWeekend = $true #assume it's the weekend; we confirm this later [DateTime]$Sat = $Date switch ($Date.DayOfWeek) { #we could use 6 and 0 instead of Sat and Sun to avoid language issues; but all our servers are US/UK, and the readability is clearer with week names 'Saturday' {$Sat = $Date} 'Sunday' {$Sat = $Date.AddDays(-1)} Default {$IsWeekend = $false} } write-output (new-object PSObject -prop @{ Date = $Date Day = $Date.DayOfWeek OK = $IsWeekend -and (($Sat.Day -ge $StartDay) -and ($Sat.Day -le $EndDayLocal)) }) } } if ((Test-DateIsInMaintenanceWindow).OK) { &$ScriptPath } else { throw 'Script should''t run today' } #Code to say which weekends fall in our maintenance window 1..4000 | %{(get-date).AddDays($_)} | ?{$_.DayOfWeek -like 'S*'} | Test-DateIsInMaintenanceWindow -StartDay 10 -EndDay 24 | ft -AutoSize