Azure Automation runbooks are a great way to automate various aspects of your Azure environment. Probably the task it is used for the most (at least at the moment) is starting and stopping a virtual machine or a bunch of vms on a schedule. The runbook scripts take care of the “powering on” or “shutting down”. Adding a schedule to these scripts is a great way to save cost by only running virtual machines when they are required. Some might be required to run 24/7 but others might only be required to run on workdays e.g. from 7am to 7pm .

However the runbook scheduler is pretty limited in fine tuning the recurrence of a script. Currently you can choose from

  • One time
  • Daily
  • Hourly

But what if you want to run a VM only on weekdays and only on weekdays which are not public holidays. The latter was one of our customers requirement. I’m not going to add another start/stop script to this post but just the code snippets/logic you can use in your own script.

Weekdays

This is the “easy” bit.

[sourcecode language=”powershell”]
$Weekdays = @("Monday","Tuesday","Wednesday","Thursday","Friday")

# Check if day of the week is a working day (Monday – Friday). If not, exit.
If (-Not ($Weekdays -contains $CurrentDateTimeACDT.DayOfWeek))
{
return
}
[/sourcecode]


Public Holidays

When looking at ways to check for a public holiday I had a couple of options in mind on how to do this. Create an array in PowerShell with dates? Use a CSV to read from? As long as it not only contained the national as well as the state specific (in my case ‘SA’) holidays.
When looking at the CSV file option I ended at the federal government’s website “data.gov.au” and that’s where I noticed they offer this information in datasets which can be queried using RESTAPI calls. The good thing with being able to do that is that the information is always up to date and requires no human intervention to retrieve.

I have split up the URI to the dataset in a base part ($URI) and the actual resource part ($ResourceID). Next year, when the dataset for 2017-2018 is released this is the only bit which needs updating. Or could be passed on the runbook as a parameter.

[sourcecode language=”powershell”]
function GetPublicHolidays
{
# Get information regarding public holidays from the DATA.GOV.AU website using RESTAPI.
# Australian Public Holidays Dates Machine Readable Dataset
# https://data.gov.au/dataset/b1bc6077-dadd-4f61-9f8c-002ab2cdff10
$URI = "https://data.gov.au/datastore/odata3.0/"
$ResourceID = "a24ecaf2-044a-4e66-989c-eacc81ded62f" # 2016/2017 dataset

# Retrieve all national (NAT) and South Australian (SA) public holidays.
(Invoke-RestMethod -Uri "$($URI)$($ResourceID)?`$format=json" -Method Get).Value | `
Where-Object {($_.ApplicableTo -eq "NAT" -or $_.ApplicableTo -eq "SA")}
}
[/sourcecode]

Add the above function to the runbook and then from with the runbook call it:

[sourcecode language=”powershell”]
$PublicHolidays = GetPublicHolidays | GetPublicHolidays | Where-Object {$_.Date -eq ($CurrentDateTimeACDT.ToString("yyyyMMdd"))}
If (-Not ([string]::IsNullOrEmpty($PublicHolidays)))
{
Write-Output "Current day is a Public Holiday: [$($PublicHolidays.HolidayName)]. Script will not continue."
return
}
[/sourcecode]

 

When using time and dates in Azure Automation it is important to keep in mind that

a) Time and date entered through the portal when creating a schedule are entered in the timezone the webbrowser runs in. This information gets stored as UTC time and date in the background.

b) The runbook scripts use UTC time and date. So when using date and time functions in a runbook which also take information from other resources make sure that whatever is compared is in the same timezone.

[sourcecode language=”powershell”]
$CurrentDateTimeUTC = (Get-Date).ToUniversalTime()
$CurrentDateTimeACDT = (Get-Date).ToUniversalTime().AddHours(10.5)
[/sourcecode]

 

 

Category:
Azure Platform, PowerShell

Join the conversation! 1 Comment

  1. Thank you, Very much, that has really helped me.

Comments are closed.