我需要创建一个 PowerShell 脚本,以便每分钟收集一些数据。但是,此脚本无法在计划在同一周的同一天和同一时间发生的“技术窗口”内运行。(例如,每周二 19:00 至 23:00)此计划信息在文件中声明(例如:.\Schedule.txt):
# SCHEDULE
#
# Periods when the script will not be executed: "Prohibited Period"
# Inform: <Begin_Week_Day>:<Begin_Hour>:<Begin_Minute>:<End_Week_Day>:<End_Hour>:<End_Minute>
#
# Example: Set the Prohibited Period of script execution, every Tuesday, from 8:00 pm to 10:00 pm:
# tue:20:00:tue:22:00
#
# ATTENTION: LIMITED SCHEDULE TO THE SAME DAY OF THE WEEK!
#
qua:10:30:qua:15:40
qui:13:30:qui:23:00
在此示例中,安排了两个技术窗口。
我在第一个版本中实现了这个,只要技术窗口在同一天:
$ScheduleFile=Get-Content -Path .\Schedule.txt
$NowDay=Get-Date -Format "ddd"
$NowHour=Get-Date -Format "HH"
$NowMinute=Get-Date -Format "mm"
$NowTime=[single]$NowHour+[single]$NowMinute/60
$PeriodoProibido = $false
Write-Host "========================================================================="
Write-Host "SCHEDULE ANALYSIS: Today is ${NowDay}, ${NowHour}:${NowMinute} (${NowTime})"
foreach ($line in $ScheduleFile){
if($line.Substring(0,1) -ne "#") {
Write-Host "-------------------------------------------------------------------------"
$LineArray = $line.Split(':')
<# Schedule: BEGIN of Prohibited Period: $LineArray[0] = Day $LineArray[1] = Hour $LineArray[2] = Minute
END of Prohibited Period: $LineArray[3] = Day $LineArray[4] = Hour $LineArray[5] = Minute
#>
# Convert HOUR to decimal format, include minutes.
$LineArray[1]=[single]$LineArray[1]+[single]$LineArray[2]/60
$LineArray[4]=[single]$LineArray[4]+[single]$LineArray[5]/60
Write-Host "Prohibited Period: From "$LineArray[0] $LineArray[1]" to " $LineArray[3] $LineArray[4]
<# Check if NOW is DAY of Prohibited Period
($NowDay -eq $LineArray[0]) > Check if is DAY do Período Proibido
($NowTime -gt $LineArray[1]) > Check if TIME is AFTER the BEGIN of Prohibited Period
($NowTime -lt $LineArray[4]) > Check if TIME is BEFORE the BEGIN of Prohibited Period
#>
if($NowDay -eq $LineArray[0] -AND $NowTime -gt $LineArray[1] -AND $NowTime -lt $LineArray[4]){
Write-Host "NOW IS A PROHIBITED PERIOD! DO NOT RUN THE SCRIPT."
$PeriodoProibido = $true
}
else {
Write-Host "The script can be executed."
}
}
}
Write-Host "-------------------------------------------------------------------------"
if ($PeriodoProibido) {
Write-Host "CONCLUSION: WE ARE IN THE PROHIBITED PERIOD. DO NOT RUN SCRIPT"
}
else {
Write-Host "CONCLUSION: You can run the script."
}
Write-Host "========================================================================="
输出类似于:
=========================================================================
SCHEDULE ANALYSIS: Today is qua, 14:42 (14.7)
-------------------------------------------------------------------------
Prohibited Period: From qua 10.5 to qua 15.6666666666667
NOW IS A PROHIBITED PERIOD! DO NOT RUN THE SCRIPT.
-------------------------------------------------------------------------
Prohibited Period: From qui 13.5 to qui 23
The script can be executed.
-------------------------------------------------------------------------
CONCLUSION: WE ARE IN THE PROHIBITED PERIOD. DO NOT RUN SCRIPT
=========================================================================
但是,如果技术窗口在一天内开始并在第二天结束,则此脚本将不起作用。我认为我是否应该使用像 Excel 或类似格式的日期格式,但我不确定。
有什么好主意可以让这个脚本变得更好吗?谢谢!
答案1
以下函数允许“技术窗口”定义为以小时为单位的时间间隔
- 在同一工作日,例如
Fri:10:30:Fri:15:40
,或 - 午夜重叠,例如
Fri:22:30:Sat:05:40
,或 - 涵盖更多天数,例如
Mon:22:30:Wed:05:40
(一个日历周内),甚至Fri:22:30:Mon:05:40
(交叉周末)。
基调(基本思想)在于使用和比较工作日数字而不是工作日名称缩写(由日期时间"ddd"
自定义格式说明符)。
该脚本适用于特定的(给定的),[cultureinfo]::CurrentCulture
但可以轻松本地化为.ToString
方法以及AbbreviatedDayNames
属性允许改变特定于文化的格式信息(通过[cultureinfo]
类)......
Function TestDayTimeInterval {
[CmdletBinding()]param(
[Parameter(ValueFromPipeline)]
[string]$FromTo = 'ne:00:00:ne:00:00', # ddd:HH:mm:ddd:HH:mm
[Parameter()]
[datetime]$Date = (Get-Date)
)
Write-Verbose "is $($Date.ToString("ddd HH:mm")) in $FromTo`?"
$fAbbrDayNames = ([System.Globalization.DateTimeFormatInfo]::
CurrentInfo.AbbreviatedDayNames).ForEach({$_.ToLower()})
# [System.Globalization.DateTimeFormatInfo]::InvariantInfo.AbbreviatedDayNames
# [cultureinfo]::GetCultureInfo('pt').DateTimeFormat.AbbreviatedDayNames
$fTestDay = $fAbbrDayNames.IndexOf( $Date.ToString('ddd').ToLower())
$fTestTime= [single]$Date.ToString("HH") +
[math]::Round($Date.ToString("mm")/60,2)
$aux = $FromTo -split ':'
$fFromDay = $fAbbrDayNames.IndexOf( $aux[0].ToLower())
$fFromTime= [single]$aux[1]+[math]::Round($aux[2]/60,2)
$fUptoDay = $fAbbrDayNames.IndexOf( $aux[3].ToLower())
$fUptoTime= [single]$aux[4]+[math]::Round($aux[5]/60,2)
if ( $fFromDay -lt 0 -or $fUptoDay -lt 0 ) {
Write-Warning "incorrect FromTo [$FromTo]"
return $false
}
if ( $fFromDay -eq $fUptoDay ) {
return $fTestDay -eq $fFromDay -and
$fTestTime -ge $fFromTime -and
$fTestTime -le $fUptoTime
} elseif ( $fFromDay -lt $fUptoDay ) {
return ($fTestDay -gt $fFromDay -and
$fTestDay -lt $fUpToDay) -or
($fTestDay -eq $fFromDay -and
$fTestTime -ge $fFromTime) -or
($fTestDay -eq $fUpToDay -and
$fTestTime -le $fUpToTime)
} else {
return ($fTestDay -gt $fFromDay ) -or
($fTestDay -lt $fUpToDay ) -or
($fTestDay -eq $fUpToDay -and
$fTestTime -le $fUpToTime) -or
($fTestDay -eq $fFromDay -and
$fTestTime -ge $fFromTime)
}
}