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
}