Scale-AnalysisService.ps1
<#
.SYNOPSIS Vertically scale up and down or pause/resume an Azure Analysis Services server according to a schedule using Azure Automation. .DESCRIPTION This Azure Automation runbook enables vertically scaling or pausing of an Azure Analysis Services server according to a schedule. Autoscaling based on a schedule allows you to scale your solution according to predictable resource demand. For example you could require a high capacity (e.g. S1) on monday during peak hours, while the rest of the week the traffic is decreased allowing you to scale down (e.g. S0). Outside business hours and during weekends you could then pause the server so no charges will be applied. This runbook can be scheduled to run hourly. The code checks the scalingSchedule parameter to decide if scaling needs to be executed, or if the server is in the desired state already and no work needs to be done. The script is time zone aware. .PARAMETER environmentName Name of Azure Cloud environment. Default is AzureCloud, only change when on Azure Government Cloud, for example AzureUSGovernment. .PARAMETER resourceGroupName Name of the resource group to which the server is assigned. .PARAMETER AzureRunAsConnection Azure Automation Run As account name. Needs to be able to access the $Name. .PARAMETER Name Azure Analysis Services server name. .PARAMETER SKU Server Scaling SKU. .PARAMETER scalingScheduleTimeZone Time Zone of time slots in $scalingSchedule. Available time zones: [System.TimeZoneInfo]::GetSystemTimeZones(). .EXAMPLE <SubscriptionId>,<ResourceGroupName>,Microsoft.AnalysisServices,<ServerName>,<SKU_Current>,,<SKU_Expected>,,-ScaleUp -Start, <SubscriptionId>,<ResourceGroupName>,Microsoft.AnalysisServices,<ServerName>,<SKU>,,<SKU>,,-ScaleDown -Stop, .NOTES Author: Aamir Mirza Last Update: Oct 2023 #> Function Scale-AnalysisService{ param( [string] $AzureRunAsConnection, [string] $resourceGroupName, [string] $Name, [string] $Sku, [string] $Start, [string] $Stop # [parameter(Mandatory=$false)] # [string] $scalingScheduleTimeZone = "W. Europe Standard Time" ) filter timestamp { "[$(Get-Date -Format G)]: $_" } Write-Output 'Script started.' | timestamp # Connect using a Managed Service Identity try { $AzureContext = (Connect-AzAccount -Identity).context Write-Output 'Authenticated with MI.' | timestamp } catch { Write-Output 'There is no system-assigned user identity. Aborting. Setup the same or try using RunAs account automation method.'; } Write-Output ('AzureRunAsConnection: {0} ResourceGroupName: {1} Name: {2} SKU: {3} Start: {4} Stop: {5}' -F $AzureRunAsConnection, $ResourceGroupName, $Name, $Sku, $Start, $Stop) # Get the server object $asSrv = Get-AzAnalysisServicesServer -ResourceGroupName $resourceGroupName -Name $Name Write-Output "AAS server name: $($asSrv.Name)" | timestamp Write-Output "Current server status: $($asSrv.State), sku: $($asSrv.Sku.Name)" | timestamp # Analysis Service Server Pause & Resume logic if (($asSrv.State -eq 'Paused') -and ($Start)) { Write-Output 'Server was paused. Resuming Now !' | timestamp $asSrv | Resume-AzAnalysisServicesServer Write-Output 'Server resumed.' | timestamp } elseif (($asSrv.State -ne 'Paused') -and ($Start)) { Write-Output 'Server already running.' | timestamp } elseif (($asSrv.State -ne 'Paused') -and ($Stop)) { Write-Output 'Server not paused. Pausing Now !' | timestamp $asSrv | Suspend-AzAnalysisServicesServer } else { Write-Output 'Server already Paused!' | timestamp } # Analysis Service Server Scaling schedule if ($asSrv.Sku.Name -ne $Sku) { Write-Output "Server is not in the sku of the scaling schedule. Changing to $($Sku)!" | timestamp $asSrv = Set-AzAnalysisServicesServer -Name $asSrv.Name -ResourceGroupName $resourceGroupName -Sku $Sku Write-Output 'Change to edition/tier as specified in scaling schedule initiated...' | timestamp $asSrv = Get-AzAnalysisServicesServer -ResourceGroupName $resourceGroupName -Name $Name Write-Output "Current server state: $($asSrv.State), sku: $($asSrv.Sku.Name)" | timestamp } else { Write-Output 'Current server sku matches the scaling schedule already. Exiting...' | timestamp } Write-Output 'Script finished.' | timestamp } |