Autoscaling Storage Account File Share Size

This autoscaling script can optimize size, performance, and costs for your Azure Storage Account File Shares that store Azure Virtual Desktop FSLogix profiles. Typically, you would run this with Function App, Azure Automation, or GitHub Actions on a daily or weekly schedule.

Define your subscription, storage account resource group, and file shares, and the script will maintain 20% capacity by increasing or decreasing the shares’ provisioned capacity.
# Variable Definitions
$subscription_id = "12345"
$resource_group = "SA"
$storage_account_name = "AVDFSLogix01"
$file_share_names = @("profiles01", "offiprofiles01")

# Connect to Azure and Import Az Module
# Connect-AzAccount
Import-Module -Name Az.Accounts
Import-Module -Name Az.Storage
Set-AzContext -SubscriptionId $subscription_id

# Get storage account SKU to Determine minimum size
$storageAccountType = (Get-AzStorageAccount -ResourceGroupName $resource_group -Name $storage_account_name).Sku.Name

foreach ($file_share_name in $file_share_names) {
    # Get storage account object
    $storageAccount = Get-AzStorageAccount -ResourceGroupName $resource_group -Name $storage_account_name
    
    # Get file share
    $StorageContext = New-AzStorageContext -StorageAccountName $storage_account_name -Anonymous
    $PFS = Get-AzRmStorageShare -ResourceGroupName $resource_group -StorageAccountName $storage_account_name -Name $file_share_name -GetShareUsage
    
    # Get provisioned capacity and used capacity
    $ProvisionedCapacity = $PFS.QuotaGiB
    $UsedCapacityBytes = $PFS.ShareUsageBytes
    # Convert used capacity to GB for easier comparison
    $UsedCapacityGB = [Math]::Round($UsedCapacityBytes / ([Math]::Pow(2, 30)), 2)
    
    Write-Host "Provisioned Capacity for ${file_share_name} (GiB):" $ProvisionedCapacity
    Write-Host "Share Usage for ${file_share_name} (GB):" $UsedCapacityGB
   
    #By changing the denominator in the formula from 0.8 (which represents 20% free space, as 100% - 20% = 80% or 0.8) to a value that reflects your desired threshold of free space, you can adjust the threshold. 
    #For 30% free space, the calculation should use 0.7 (since 100% - 30% = 70% or 0.7).
    # Calculate required capacity to maintain exactly 20% free space. Increases or Decreases based on used capacity.
    $RequiredCapacity = [Math]::Ceiling(($UsedCapacityBytes / ([Math]::Pow(2, 30))) / 0.8)

    # Adjust for minimum size based on SKU
    if ($storageAccountType.StartsWith("Premium")) {
        $RequiredCapacity = [Math]::Max($RequiredCapacity, 100)
    }
    elseif ($storageAccountType.StartsWith("Standard")) {
        $RequiredCapacity = [Math]::Max($RequiredCapacity, 1)
    }
    
    # Check if the current provisioned capacity is different from the required capacity
    if ($RequiredCapacity -ne $ProvisionedCapacity) {
        # Adjust the provisioned capacity
        Update-AzRmStorageShare -StorageAccount $storageAccount -Name $file_share_name -QuotaGiB $RequiredCapacity -Whatif
        Write-Host "Provisioned Capacity for ${file_share_name} adjusted to ${RequiredCapacity} GiB based on SKU requirements."
    }
    else {
        Write-Host "Provisioned Capacity for ${file_share_name} already meets 20% free space requirement and SKU requirements."
    }
}

How to set up Autoscaling Storage Account File Share Size with FunctionApp.

First you need to create a Function App. Additional information here: Create a function in Azure that runs on a schedule | Microsoft Learn Login to Azure Portal and go to Function App. Click Create.
Click on Create new or use existing Resource group selector.
Specify a unique name for your Function App. Then select PowerShell Core for Runtime stack, version 7.2, and a Region. Operating System is Windows, and Consumption Plan. Click Next to continue.
Create a new Storage Account or you can select an existing one from the drop down.
Networking: Enable Public Access Off.
Monitoring: Optional. Yes, if you want to be able to see insights.
Add Tags if needed. Then Review and Create.
After the Function App is created you still need to create the Function, add a schedule and the script. Open your new Function App and click create.
Select Timer trigger, then specify a name for the New Function and you can set the schedule now or leave it default and adjust later. Schedule information can be found here. https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=python-v2%2Cin-process%2Cnodejs-v4&pivots=programming-language-csharp#ncrontab-expressions Default is every 5 minutes. If your storage accounts are premium then you should set the timer to run only once a day because the provisioned capacity of a share can be decreased only once every 24 hours.
Click Code + Test.
Copy and paste the script, then adjust the variables for your Azure subscription, Resource Group, Storage Account Name and File Share or multiple shares. Shares are separated by comma. Click save when finished.
Adjust Timer/Schedule. Click on Integration.
Specify a different schedule since the default is every 5 minutes. Typically, once a day/every 24 hours should be good enough for AVD FSLogix storage. Other use cases you might need a different schedule.
Next you need to grant permissions for the Function App to increase quota automatically. Click on Identity.
Under Status, System Assigned, click on and then click Save. Then click Azure role assignments.
Click Add Role Assignment (Preview).
Change scope to Storage then choose the storage account and select contributor role. If you don’t want to use Contributor, then create a custom role and use that. Click save and wait a couple minutes for the roles to show up or try refreshing. Repeat steps if you are going to use this script for other storage accounts.
After your permissions are set you are all finished. You can test it or just wait for the schedule to run the function.
Share or Save this:
Share

One thought on “Autoscaling Storage Account File Share Size

  1. Pingback: AVD Community Newsletter – 4th April 2024 – AVD Community