Azure Virtual Desktop Scaling Plan Check and Enable

Verify your scaling plans are enabled and haven’t been accidentally left disabled. If a scaling plan has been disabled for longer than 24 hours by checking lastmodified, then have the script automatically re-enable it. You could also add to the script to exclude specific scaling plans based on name or a tag if need.

# Authenticate to Azure if not already done (Ensuring authentication)
Connect-AzAccount

# Get all the resource groups in the subscription
$resourceGroups = Get-AzResourceGroup
#Specify Sub ID or just use subscription Id from when you connect-azaccount
#$subscriptionId = "SUBID123"
# Get the default subscription details
$subscription = Get-AzSubscription | Where-Object { $_.State -eq 'Enabled' } | Select-Object -First 1
# Use the subscription ID
$subscriptionId = $subscription.Id
# Prepare an array to hold the output data and a hashtable to track processed plans
$outputData = @()
$processedScalingPlans = @{}
# API version for the REST API call
$apiVersion = "2022-02-10-preview"

foreach ($rg in $resourceGroups) {
    # List all the scaling plans within the current resource group
    $scalingPlans = Get-AzWvdScalingPlan -ResourceGroupName $rg.ResourceGroupName
    
    foreach ($plan in $scalingPlans) {
        if ($plan.HostPoolReference) {
            foreach ($hostPoolRef in $plan.HostPoolReference) {
                $hostPoolName = $hostPoolRef.HostPoolArmPath -split '/' | Select-Object -Last 1
                
                # Create a unique identifier for each scaling plan
                $uniqueId = "$($rg.ResourceGroupName)-$($plan.Name)-$hostPoolName"
                
                if (-not $hostPoolRef.ScalingPlanEnabled) {
                    if (-not $processedScalingPlans.ContainsKey($uniqueId)) {
                        # Mark this scaling plan as processed
                        $processedScalingPlans[$uniqueId] = $true

                        # Retrieve the access token
                        $accessTokenInfo = Get-AzAccessToken -ResourceUrl "https://management.azure.com"
                        $accessToken = $accessTokenInfo.Token
                        
                        # Set the header with the access token
                        $headers = @{
                            'Authorization' = "Bearer $accessToken"
                            'Content-Type'  = 'application/json'
                        }
                        
                        # Define the URL with the correct api-version
                        $url = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$($rg.ResourceGroupName)/providers/Microsoft.DesktopVirtualization/scalingPlans/$($plan.Name)?api-version=$apiVersion"
                        
                        # Make the REST API call
                        $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get
                        
                        # Access the lastModifiedAt directly
                        $lastModifiedAt = $response.systemData.lastModifiedAt
                        $lastModifiedDate = [datetime]::Parse($lastModifiedAt)
                        $currentTimeUtc = (Get-Date).ToUniversalTime()
                        $timeDifference = $currentTimeUtc - $lastModifiedDate
                        
                        if ($timeDifference.TotalHours -gt 24) {
                            $outputObject = New-Object PSObject -Property @{
                                ResourceGroupName = $rg.ResourceGroupName
                                ScalingPlanName = $plan.Name
                                HostPoolName = $hostPoolName
                                ScalingPlanEnabled = $hostPoolRef.ScalingPlanEnabled
                                LastModifiedBy = $response.systemData.lastModifiedBy
                                LastModifiedAt = $lastModifiedAt
                            }
                            
                            # Adding the object to the output data array
                            $outputData += $outputObject
                        }
                    }
                }
            }
        }
    }
}

# Output the scaling plans that need to be updated
if ($outputData.Count -eq 0) {
    Write-Host "No updates are required."
} else {
	$outputData | Format-Table -Property ResourceGroupName, ScalingPlanName, HostPoolName, ScalingPlanEnabled, `
    @{Name='LastModifiedBy'; Expression={$_.LastModifiedBy.Substring(0, [System.Math]::Min(20, $_.LastModifiedBy.Length))}}, `
    @{Name='LastModifiedAt'; Expression={if ($_.LastModifiedAt -ne $null) {$_.LastModifiedAt.ToString("g")} else {"N/A"}}} -AutoSize
}
# Perform updates on the scaling plans ready for update
foreach ($planToUpdate in $outputData) {
    if (-not $planToUpdate.ScalingPlanEnabled) {
        try {
            $scalingPlanParams = @{
                ResourceGroupName = $planToUpdate.ResourceGroupName
                Name = $planToUpdate.ScalingPlanName
                HostPoolReference = @( @{ HostPoolArmPath = "$($planToUpdate.HostPoolName)"; ScalingPlanEnabled = $true } )
                # Include other necessary parameters as per your scaling plan requirements
            }

            # Uncomment the line below to perform the update. Ensure to review and test before uncommenting.
            Update-AzWvdScalingPlan @scalingPlanParams -whatif

            Write-Host "Updated scaling plan: $($planToUpdate.ScalingPlanName) in resource group: $($planToUpdate.ResourceGroupName)"
        } catch {
            Write-Host "Failed to update scaling plan: $($planToUpdate.ScalingPlanName) - Error: $_"
        }
    }
}

# Retrieve and display the updated list of scaling plans
$updatedOutputData = @()
foreach ($rg in $resourceGroups) {
    $scalingPlans = Get-AzWvdScalingPlan -ResourceGroupName $rg.ResourceGroupName
    foreach ($plan in $scalingPlans) {
        if ($plan.HostPoolReference) {
            foreach ($hostPoolRef in $plan.HostPoolReference) {
                $hostPoolName = $hostPoolRef.HostPoolArmPath -split '/' | Select-Object -Last 1

                # Retrieve the access token again to ensure it's still valid
                $accessTokenInfo = Get-AzAccessToken -ResourceUrl "https://management.azure.com"
                $accessToken = $accessTokenInfo.Token

                $headers = @{
                    'Authorization' = "Bearer $accessToken"
                    'Content-Type'  = 'application/json'
                }

                $url = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$($rg.ResourceGroupName)/providers/Microsoft.DesktopVirtualization/scalingPlans/$($plan.Name)?api-version=$apiVersion"

                $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get

                $lastModifiedAt = $response.systemData.lastModifiedAt
                $lastModifiedBy = $response.systemData.lastModifiedBy

                $updatedOutputObject = New-Object PSObject -Property @{
                    ResourceGroupName = $rg.ResourceGroupName
                    ScalingPlanName = $plan.Name
                    HostPoolName = $hostPoolName
                    ScalingPlanEnabled = $hostPoolRef.ScalingPlanEnabled
                    LastModifiedBy = $lastModifiedBy
                    LastModifiedAt = $lastModifiedAt
                }

                $updatedOutputData += $updatedOutputObject
            }
        }
    }
}

# Output the updated scaling plans details
$updatedOutputData | Format-Table -Property ResourceGroupName, ScalingPlanName, HostPoolName, ScalingPlanEnabled, `
    @{Name='LastModifiedBy'; Expression={$_.LastModifiedBy.Substring(0, [System.Math]::Min(20, $_.LastModifiedBy.Length))}}, `
    @{Name='LastModifiedAt'; Expression={$_.LastModifiedAt.ToString("g")}} -AutoSize


Share or Save this:
Share