Checking School Term Time with Powershell
I had a client who had a requirement to only run an automated task within the school term dates.
Previously, our team was unscoping or disabling the scheduled tasks for every client when term break was starting, and re-enabling this at the beginning of each term. This was inefficient and could often lead to a school or two being missed and having to reactively reschedule or disable the task after it being reported as an issue.
I decided to write a solution in PowerShell to check if the date at the time of running the script ($Today) was a day during the school term. The WA Department of Education posts the school term dates here in a handy html table that I was able to scrape.
By writing it in a function wrapper, I am able to call the function through If Then Else statements throughout the code prior to running any tasks that we only want to run during school time.
#It is term time, we can continue on with the required tasks.
} else {
#It is either a school break, or the weekend.
}
I scrape the DoE website by parsing the HTML content into a PowerShell variable, and then looking for any matches using regex to scrape out the HTML table fields that we care about.
Once scraped, I store the term dates in an PowerShell array which is then passed through an For Each loop to split the date string into a $start and $end date type for each term.
$Today is then compared with an If statement to check if $Today is between the $start and $end date of any term, thus making it during a school term
If $Today is within a school term period, I then check to ensure it's not a weekend (Saturday or Sunday) before returning the function as true, allowing the script calling this function to either continue it's process, or end as in my case, I didn't want to make changes to Students on the weekend or term break.
Complete Function
$Today = Get-Date
$HTML = Invoke-RestMethod 'https://www.education.wa.edu.au/future-term-dates/'
$Pattern = '<div class="eds-c-content-view"> <h4>' + $(Get-Date).Year + ' Term dates<\/h4> <table class="eds-c-table--term-dates eds-o-table"> <thead> <tr> <th colspan="2">Semester 1<\/th> <\/tr> <\/thead> <tbody> <tr class="odd"> <td>Term 1<\/td> <td>(?<term1>.*)<\/td> <\/tr> <tr> <td>Break<\/td> <td>Sat 9 April - Mon 25 April<\/td> <\/tr> <tr class="odd"> <td>Term 2<\/td> <td>(?<term2>.*)<\/td> <\/tr> <tr> <td>Break<\/td> <td>Sat 2 July - Sun 17 July<\/td> <\/tr> <\/tbody> <\/table> <table class="eds-c-table--term-dates eds-o-table"> <thead> <tr> <th colspan="2">Semester 2<\/th> <\/tr> <\/thead> <tbody> <tr class="odd"> <td>Term 3<\/td> <td>(?<term3>.*)<\/td> <\/tr> <tr> <td>Break<\/td> <td>Sat 24 September - Sun 9 October<\/td> <\/tr> <tr class="odd"> <td>Term 4<\/td> <td>(?<term4>.*)<\/td>'
$AllMatches = ($HTML | Select-String $Pattern -AllMatches).Matches
$AllMatches = ([regex]$Pattern).Matches($HTML)
$TermList = @()
$TermOne = ($AllMatches.Groups.Where{$_.Name -like 'term1'}).Value.Split('<')[0]
$TermTwo = ($AllMatches.Groups.Where{$_.Name -like 'term2'}).Value.Split('<')[0]
$TermThree = ($AllMatches.Groups.Where{$_.Name -like 'term3'}).Value.Split('<')[0]
$TermFour = ($AllMatches.Groups.Where{$_.Name -like 'term4'}).Value.Split('<')[0]
$TermList = $TermOne, $TermTwo, $TermThree, $TermFour
foreach ($Term in $TermList) {
$start = [Datetime]::ParseExact(($Term.Split('-')[0].Trim() + " " + $(Get-Date).Year), 'ddd d MMMM yyyy', $null)
$end = [Datetime]::ParseExact(($Term.Split('-')[-1].Trim() + " " + $(Get-Date).Year), 'ddd d MMMM yyyy', $null)
if (($Today -ge $start) -and ($Today -le $end)) {
#It is within term time, check for weekends.
if (([String]$Today.DayOfWeek -ne "Saturday") -and ([String]$Today.DayOfWeek -ne "Sunday")) {
return $True #It is a weekday
} else {
return $False #It is the weekend
}
} else {
return $False #It is a school break
}
}
}