Azure Automation RunBook Power BI Embedded Capacity
Azure VM Tags to use Runbook
Automation Powershell script (powershell version 7.1)
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process
$AzureContext = (Connect-AzAccount -Identity -Subscription "XXXXXXXX").context
$subscriptions = Get-AzSubscription | select-object Id -ExpandProperty Id
foreach ($subscription in $subscriptions) {
# Set and store context
Remove-AzContext -InputObject (Get-AzContext) -Force | Out-Null;
$AzureContext = (Connect-AzAccount -Identity -Subscription $subscription).context
#Get all PowerBIEmbeddedCapacitys that should be part of the Schedule:
$PowerBIEmbeddedCapacitys = Get-AzResource -ResourceType "Microsoft.PowerBIDedicated/capacities" -TagName "Operational-Schedule" -TagValue "Yes"
Write-Output "Processing Subscription $($subscription) and number of Capacities $($PowerBIEmbeddedCapacitys.length)..."
foreach ($PowerBIEmbeddedCapacity in $PowerBIEmbeddedCapacitys) {
Write-Output "Processing PowerBIEmbeddedCapacity $($PowerBIEmbeddedCapacity.Name)..."
$TimeZone = $($PowerBIEmbeddedCapacity.Tags)."Operational-Timezone"
Write-Output "PowerBIEmbeddedCapacity defined timezone is ($TimeZone), see for available timzones: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones?view=windows-11"
try{
$TimeZoneAdjusted = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]::Now,$TimeZone)
}catch{
Write-Output "Failed to set PowerBIEmbeddedCapacity timezone due to wrong timezone configured, Norway time defaults,, see for correct timzone: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones?view=windows-11"
$TimeZoneAdjusted = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([DateTime]::Now,"W. Europe Standard Time")
}
Write-Output "Current time of PowerBIEmbeddedCapacity after attepting adjusting the Time Zone to Operational-Timezone is: $TimeZoneAdjusted"
### Current Time associations
$Day = $TimeZoneAdjusted.DayOfWeek
If ($Day -like "S*") {
$TodayIsWeekend = $true
$TodayIsWeekday = $false
} else {
$TodayIsWeekend = $false
$TodayIsWeekday = $true
}
### Get Exclusions
$Exclude = $false
$Reason = ""
$Exclusions = $($PowerBIEmbeddedCapacity.Tags)."Operational-Exclusions"
$Exclusions = $Exclusions.Split(',')
foreach ($Exclusion in $Exclusions) {
#Check excluded actions:
If ($Exclusion.ToLower() -eq "stop") {$PowerBIEmbeddedCapacityActionExcluded = "Stop"}
If ($Exclusion.ToLower() -eq "start") {$PowerBIEmbeddedCapacityActionExcluded = "Start"}
#Check excluded days and compare with current day
If ($Exclusion.ToLower() -like "*day") {
if ($Exclusion -eq $Day) { $Exclude = $true; $Reason=$Day}
}
#Check excluded weekdays and copare with Today
If ($Exclusion.ToLower() -eq "weekdays") {
if ($TodayIsWeekday) {$Exclude = $true; $Reason="Weekday"}
}
#Check excluded weekends and compare with Today
If ($Exclusion.ToLower() -eq "weekends") {
if ($TodayIsWeekend) {$Exclude = $true; $Reason="Weekend"}
}
If ($Exclusion -eq (Get-Date -UFormat "%b %d")) {
$Exclude = $true; $Reason = "Date Excluded"
}
}
if (!$Exclude) {
#Get values from Tags and compare to the current time
if ($TodayIsWeekday) {
$ScheduledTime = $($PowerBIEmbeddedCapacity.Tags)."Operational-Weekdays"
Write-Output "PowerBIEmbeddedCapacity is scheduled to run between ($ScheduledTime) on Weekdays."
} elseif ($TodayIsWeekend) {
$ScheduledTime = $($PowerBIEmbeddedCapacity.Tags)."Operational-Weekends"
Write-Output "PowerBIEmbeddedCapacity is scheduled to run between ($ScheduledTime) on Weekends."
}
if ($ScheduledTime) {
$ScheduledTime = $ScheduledTime.Split("-")
$ScheduledStart = $ScheduledTime[0]
$ScheduledStop = $ScheduledTime[1]
$ScheduledStartTime = Get-Date $ScheduledStart
$ScheduledStopTime = Get-Date $ScheduledStop
If (($TimeZoneAdjusted -gt $ScheduledStartTime) -and ($TimeZoneAdjusted -lt $ScheduledStopTime)) {
#Current time is within the interval
Write-Output "PowerBIEmbeddedCapacity should be running now"
$PowerBIEmbeddedCapacityAction = "Start"
} else {
#Current time is outside of the operational interval
Write-Output "PowerBIEmbeddedCapacity should be stopped now"
$PowerBIEmbeddedCapacityAction = "Stop"
}
If ($PowerBIEmbeddedCapacityAction -notlike "$PowerBIEmbeddedCapacityActionExcluded") { #Make sure that action was not excluded
#Get PowerBIEmbeddedCapacity PowerState status
$PowerBIEmbeddedCapacityObject = Get-AzPowerBIEmbeddedCapacity -ResourceGroupName $PowerBIEmbeddedCapacity.ResourceGroupName -Name $PowerBIEmbeddedCapacity.Name
$PowerBIEmbeddedCapacitystate = $PowerBIEmbeddedCapacityObject.State
if (($PowerBIEmbeddedCapacityAction -eq "Start") -and ($PowerBIEmbeddedCapacitystate -notlike "Succeeded")) {
Write-Output "Starting $($PowerBIEmbeddedCapacity.Name)..."
Resume-AzPowerBIEmbeddedCapacity -ResourceGroupName $PowerBIEmbeddedCapacity.ResourceGroupName -Name $PowerBIEmbeddedCapacity.Name
} elseif (($PowerBIEmbeddedCapacityAction -eq "Stop") -and ($PowerBIEmbeddedCapacitystate -notlike "Paused")) {
Write-Output "Stopping $($PowerBIEmbeddedCapacity.Name)..."
Suspend-AzPowerBIEmbeddedCapacity -ResourceGroupName $PowerBIEmbeddedCapacity.ResourceGroupName -Name $PowerBIEmbeddedCapacity.Name
} else {
Write-Output "PowerBIEmbeddedCapacity $($PowerBIEmbeddedCapacity.Name) status is: $PowerBIEmbeddedCapacitystate . No action will be performed ..."
}
} else {
Write-Output "PowerBIEmbeddedCapacity $($PowerBIEmbeddedCapacity.Name) is Excluded from changes during this run because Operational-Exclusions Tag contains action $PowerBIEmbeddedCapacityAction."
}
} else {
Write-Output "Error: Scheduled Running Time for PowerBIEmbeddedCapacity was not detected. No action will be performed..."
}
} else {
Write-Output "PowerBIEmbeddedCapacity $($PowerBIEmbeddedCapacity.Name) is Excluded from changes during this run because Operational-Exclusions Tag contains exclusion $Reason."
}
}
}
Write-Output "Runbook completed."