diff --git a/samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-arc-sql-license-type.ps1 b/samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-arc-sql-license-type.ps1 index e181686a..98635a86 100644 --- a/samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-arc-sql-license-type.ps1 +++ b/samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-arc-sql-license-type.ps1 @@ -195,9 +195,9 @@ if ($SubId -like "*.csv") { $subscriptions = Import-Csv $SubId }elseif($SubId -ne "") { Write-Output "Passed Subscription $($SubId)" - $subscriptions = [PSCustomObject]@{SubscriptionId = $SubId} | Get-AzSubscription -TenantID $TenantId + $subscriptions = Get-AzSubscription -SubscriptionId $SubId }else { - $subscriptions = Get-AzSubscription -TenantID $TenantId + $subscriptions = Get-AzSubscription | Where-Object { $_.TenantId -eq $tenantId } } # Handle MachineName input (single or CSV) diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/modify-azure-sql-license-type.ps1 b/samples/manage/azure-hybrid-benefit/modify-license-type/modify-azure-sql-license-type.ps1 index 79cb71f4..20f815e9 100644 --- a/samples/manage/azure-hybrid-benefit/modify-license-type/modify-azure-sql-license-type.ps1 +++ b/samples/manage/azure-hybrid-benefit/modify-license-type/modify-azure-sql-license-type.ps1 @@ -169,23 +169,13 @@ $SqlVmLicenseType = if ($LicenseType -eq "LicenseIncluded") { "PAYG" } else { "A $modifiedResources = @() # Determine the subscriptions to process: CSV file, single subscription, or all accessible subscriptions. -try { - if ($SubId -and $SubId -like "*.csv") { - Write-Output "Gathering subscriptions from CSV file: $SubId" - $subscriptions = Import-Csv -Path $SubId - } - elseif (($null -ne $SubId) -and $SubId -ne "") { - Write-Output "Gathering subscription details for: $SubId" - $subscriptions = @(az account show --subscription $SubId --output json | ConvertFrom-Json) - } - else { - Write-Output "Gathering all accessible subscriptions..." - $subscriptions = az account list --output json | ConvertFrom-Json - } -} -catch { - Write-Error "Error determining subscriptions: $_" - exit 1 +if ($SubId -like "*.csv") { + $subscriptions = Import-Csv $SubId +}elseif($SubId -ne "") { + Write-Output "Passed Subscription $($SubId)" + $subscriptions = Get-AzSubscription -SubscriptionId $SubId +}else { + $subscriptions = Get-AzSubscription | Where-Object { $_.TenantId -eq $tenantId } } # Build resource group filter if specified. @@ -375,13 +365,13 @@ foreach ($sub in $subscriptions) { # Collect data before modification $modifiedResources += [PSCustomObject]@{ TenantID = $TenantId - SubID = $server.SubscriptionId + SubID = $db.SubscriptionId ResourceName = $db.name ResourceType = $db.ResourceType Status = $db.State OriginalLicenseType = $db.licenseType - ResourceGroup = $server.resourceGroup - Location = $server.location + ResourceGroup = $db.resourceGroup + Location = $db.location } if (-not $ReportOnly) { @@ -405,13 +395,13 @@ foreach ($sub in $subscriptions) { # Collect data before modification $modifiedResources += [PSCustomObject]@{ TenantID = $TenantId - SubID = $server.SubscriptionId + SubID = $pool.SubscriptionId ResourceName = $pool.name ResourceType = $pool.ResoureType Status = $pool.State OriginalLicenseType = $pool.licenseType - ResourceGroup = $server.resourceGroup - Location = $server.location + ResourceGroup = $pool.resourceGroup + Location = $pool.location } if (-not $ReportOnly) { diff --git a/samples/manage/azure-hybrid-benefit/modify-license-type/modify-license-type.ps1 b/samples/manage/azure-hybrid-benefit/modify-license-type/modify-license-type.ps1 deleted file mode 100644 index 4aa1c9e0..00000000 --- a/samples/manage/azure-hybrid-benefit/modify-license-type/modify-license-type.ps1 +++ /dev/null @@ -1,442 +0,0 @@ -<# -.SYNOPSIS - Updates the license type for Azure SQL resources (SQL DBs, Elastic Pools, Managed Instances, Instance Pools, SQL VMs) - to a specified model ("LicenseIncluded" or "BasePrice"). Optionally starts resources if needed. - -.DESCRIPTION - The script updates Azure SQL License types across subscriptions by modifying the license settings for a variety of SQL resources. It supports processing resources in one of the following ways: - -Single Subscription: -Run against a specified subscription ID. -CSV List of Subscriptions: -Process multiple subscriptions provided in a CSV file. -All Accessible Subscriptions: -Automatically detect and update all subscriptions that you have access to. -For specific resource types like SQL Virtual Machines and SQL Managed Instances, the script can optionally start the resource if it is in a stopped state (when the -ForceStartOnResources parameter is enabled) before applying the license update. - -The script processes several types of Azure SQL resources including: - -SQL Virtual Machines (SQL VMs) -SQL Managed Instances -SQL Databases -Elastic Pools -SQL Instance Pools -DataFactory SSIS Integration Runtimes -This automation helps ensure that your licensing configuration is consistent across your environment without manual intervention. - -.PARAMETER SubId - A single subscription ID or a CSV file name containing a list of subscriptions. - -.PARAMETER ResourceGroup - Optional. Limit the scope to a specific resource group. - -.PARAMETER LicenseType - Optional. License type to set. Allowed values: "LicenseIncluded" (default) or "BasePrice". - -.PARAMETER ForceStartOnResources - Optional. If true, starts SQL VMs and SQL Managed Instances before updating their license type. -#> - -param ( - [Parameter(Mandatory = $false)] - [string] $SubId, - - [Parameter(Mandatory = $false)] - [string] $ResourceGroup, - - [Parameter(Mandatory = $false)] - [ValidateSet("LicenseIncluded", "BasePrice", IgnoreCase = $false)] - [string] $LicenseType = "LicenseIncluded", - - [Parameter(Mandatory = $false)] - [bool] $ForceStartOnResources = $false -) - -# Suppress unnecessary logging output -$VerbosePreference = "SilentlyContinue" -$DebugPreference = "SilentlyContinue" -$ProgressPreference = "SilentlyContinue" -$InformationPreference = "SilentlyContinue" -$WarningPreference = "SilentlyContinue" -function Connect-Azure { - <# - .SYNOPSIS - Connects to Azure using either Managed Identity or interactive user login. - - .DESCRIPTION - This function first attempts to authenticate to Azure using a Managed Identity by calling - Connect-AzAccount with the -Identity switch. If the Managed Identity login is successful, - it then connects the Azure CLI using the --identity option. If any of the Managed Identity - login attempts fail, the function falls back to interactive (user) login for both Azure - PowerShell and the Azure CLI. - - .EXAMPLE - PS C:\> Connect-Azure - Attempts to connect using Managed Identity; if not available, it will prompt for interactive login. - #> - - # Variable to track if Managed Identity authentication was successful. - $ManagedIdentityLoginSuccessful = $false - - Write-Output "Attempting to connect using Managed Identity for Azure PowerShell..." - try { - Connect-AzAccount -Identity -ErrorAction Stop | Out-Null - Write-Output "Azure PowerShell connected using Managed Identity." - $ManagedIdentityLoginSuccessful = $true - } - catch { - Write-Output "Managed Identity login failed for Azure PowerShell. Falling back to interactive login..." - try { - Connect-AzAccount -ErrorAction Stop | Out-Null - Write-Output "Azure PowerShell connected using interactive login." - } - catch { - Write-Error "Failed to connect to Azure PowerShell: $_" - return - } - } - - # Attempt Azure CLI connection. - if ($ManagedIdentityLoginSuccessful) { - Write-Output "Attempting to connect Azure CLI using Managed Identity..." - try { - az login --identity --output none - Write-Output "Azure CLI connected using Managed Identity." - } - catch { - Write-Output "Managed Identity login failed for Azure CLI. Falling back to interactive login..." - try { - az login --output none - Write-Output "Azure CLI connected using interactive login." - } - catch { - Write-Error "Failed to connect to Azure CLI interactively: $_" - } - } - } - else { - Write-Output "Attempting to connect Azure CLI using interactive login..." - try { - az login --output none - Write-Output "Azure CLI connected using interactive login." - } - catch { - Write-Error "Failed to connect to Azure CLI interactively: $_" - } - } -} - -# Initialize final status and report counters. -$finalStatus = @() -$report = @{ - "SQLVMUpdated" = @() - "SQLMIUpdated" = @() - "SQLDBUpdated" = @() - "ElasticPoolUpdated" = @() - "InstancePoolUpdated" = @() - "ADFSSISUpdated" = @() -} - -# Ensure connection with both PowerShell and CLI. -Connect-Azure -$context = Get-AzContext -ErrorAction SilentlyContinue -Write-Output "Connected to Azure as: $($context.Account)" - -# Map License Types for SQL VMs: LicenseIncluded -> PAYG, BasePrice -> AHUB. -$SqlVmLicenseType = if ($LicenseType -eq "LicenseIncluded") { "PAYG" } else { "AHUB" } - -# Determine the subscriptions to process: CSV file, single subscription, or all accessible subscriptions. -try { - if ($SubId -and $SubId -like "*.csv") { - Write-Output "Gathering subscriptions from CSV file: $SubId" - $subscriptions = Import-Csv -Path $SubId - } - elseif ($SubId) { - Write-Output "Gathering subscription details for: $SubId" - $subscriptions = @(az account show --subscription $SubId --output json | ConvertFrom-Json) - } - else { - Write-Output "Gathering all accessible subscriptions..." - $subscriptions = az account list --output json | ConvertFrom-Json - } -} -catch { - Write-Error "Error determining subscriptions: $_" - exit 1 -} - -# Build resource group filter if specified. -$rgFilter = if ($ResourceGroup) { "resourceGroup=='$ResourceGroup'" } else { "" } -$scriptStartTime = Get-Date -Write-Output "Our adventure begins at: $scriptStartTime`n" - -# Process each subscription. -foreach ($sub in $subscriptions) { - try { - Write-Output "===== Entering the realm of Subscription: $($sub.name) =====" - Write-Output "Switching context to subscription: $($sub.name)" - az account set --subscription $sub.id - - # --- Section: Update SQL Virtual Machines --- - try { - Write-Output "Seeking SQL Virtual Machines that require a license update..." - $sqlVmQuery = if ($rgFilter) { - "[?sqlServerLicenseType!='${SqlVmLicenseType}' && $rgFilter]" - } - else { - "[?sqlServerLicenseType!='${SqlVmLicenseType}']" - } - $sqlVMs = az sql vm list --query $sqlVmQuery -o json | ConvertFrom-Json - $sqlVmsToUpdate = [System.Collections.ArrayList]::new() - - foreach ($sqlvm in $sqlVMs) { - $vmStatus = az vm get-instance-view --resource-group $sqlvm.resourceGroup --name $sqlvm.name --query "{Name:name, ResourceGroup:resourceGroup, PowerState:instanceView.statuses[?starts_with(code, 'PowerState/')].displayStatus | [0]}" -o json | ConvertFrom-Json - if ($vmStatus.PowerState -eq "VM running") { - Write-Output "Updating SQL VM '$($sqlvm.name)' in RG '$($sqlvm.resourceGroup)' to license type '$SqlVmLicenseType'..." - $result = az sql vm update -n $sqlvm.name -g $sqlvm.resourceGroup --license-type $SqlVmLicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["SQLVMUpdated"] += $sqlvm.name - } - else { - if ($ForceStartOnResources) { - Write-Output "SQL VM '$($sqlvm.name)' is not running. Forcing start to update license..." - az vm start --resource-group $sqlvm.resourceGroup --name $sqlvm.name --no-wait yes - $sqlVmsToUpdate.Add($sqlvm) | Out-Null - } - } - } - } - catch { - Write-Error "An error occurred while updating SQL VMs: $_" - } - - # --- Section: Update SQL Managed Instances (Stopped then Ready) --- - $sqlMIsToUpdate = [System.Collections.ArrayList]::new() - try { - if ($ForceStartOnResources) { - Write-Output "Seeking SQL Managed Instances that are stopped and require an update..." - $miQuery = if ($rgFilter) { - "[?licenseType!='${LicenseType}' && state!='Ready' && $rgFilter].{Name:name, State:state, ResourceGroup:resourceGroup}" - } - else { - "[?licenseType!='${LicenseType}' && state!='Ready'].{Name:name, State:state, ResourceGroup:resourceGroup}" - } - $offSQLMIs = az sql mi list --query $miQuery -o json | ConvertFrom-Json - foreach ($mi in $offSQLMIs) { - if ($mi.State -eq "Stopped") { - Write-Output "Starting SQL Managed Instance '$($mi.Name)' in RG '$($mi.ResourceGroup)'..." - az sql mi start --mi $mi.Name -g $mi.ResourceGroup --no-wait yes - } - $sqlMIsToUpdate.Add($mi) | Out-Null - } - } - - Write-Output "Processing SQL Managed Instances that are running..." - $miRunningQuery = if ($rgFilter) { - "[?licenseType!='${LicenseType}' && state=='Ready' && $rgFilter]" - } - else { - "[?licenseType!='${LicenseType}' && state=='Ready']" - } - $runningMIs = az sql mi list --query $miRunningQuery -o json | ConvertFrom-Json - foreach ($mi in $runningMIs) { - Write-Output "Updating SQL Managed Instance '$($mi.name)' in RG '$($mi.resourceGroup)' to license type '$LicenseType'..." - $result = az sql mi update --name $mi.name --resource-group $mi.resourceGroup --license-type $LicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["SQLMIUpdated"] += $mi.name - } - } - catch { - Write-Error "An error occurred while updating SQL Managed Instances: $_" - } - - # --- Section: Update SQL Databases and Elastic Pools --- - try { - Write-Output "Querying SQL Servers within this subscription..." - $serverQuery = if ($rgFilter) { "[?$rgFilter]" } else { "[]" } - $servers = az sql server list --query $serverQuery -o json | ConvertFrom-Json - - foreach ($server in $servers) { - # Update SQL Databases - Write-Output "Scanning SQL Databases on server '$($server.name)'..." - $dbs = az sql db list --resource-group $server.resourceGroup --server $server.name --query "[?licenseType!='$($LicenseType)' && licenseType!=null]" -o json | ConvertFrom-Json - foreach ($db in $dbs) { - Write-Output "Updating SQL Database '$($db.name)' on server '$($server.name)' to license type '$LicenseType'..." - $result = az sql db update --name $db.name --server $server.name --resource-group $server.resourceGroup --set licenseType=$LicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["SQLDBUpdated"] += $db.name - } - - # Update Elastic Pools - try { - Write-Output "Scanning Elastic Pools on server '$($server.name)'..." - $elasticPools = az sql elastic-pool list --resource-group $server.resourceGroup --server $server.name --query "[?licenseType!='$($LicenseType)' && licenseType!=null]" --only-show-errors -o json | ConvertFrom-Json - foreach ($pool in $elasticPools) { - Write-Output "Updating Elastic Pool '$($pool.name)' on server '$($server.name)' to license type '$LicenseType'..." - $result = az sql elastic-pool update --name $pool.name --server $server.name --resource-group $server.resourceGroup --set licenseType=$LicenseType --only-show-errors -o json | ConvertFrom-Json -ErrorAction SilentlyContinue - $finalStatus += $result - $report["ElasticPoolUpdated"] += $pool.name - } - } - catch { - Write-Output "Encountered an issue while updating Elastic Pools on server '$($server.name)'. Continuing..." - } - } - } - catch { - Write-Error "An error occurred while processing SQL Databases or Elastic Pools: $_" - } - - # --- Section: Update SQL Instance Pools --- - try { - Write-Output "Searching for SQL Instance Pools that require a license update..." - $instancePoolsQuery = if ($rgFilter) { "[?$rgFilter]" } else { "[]" } - $instancePools = az sql instance-pool list --query $instancePoolsQuery -o json | ConvertFrom-Json - $poolsToUpdate = $instancePools | Where-Object { $_.licenseType -ne $LicenseType } - foreach ($pool in $poolsToUpdate) { - Write-Output "Updating SQL Instance Pool '$($pool.name)' in RG '$($pool.resourceGroup)' to license type '$LicenseType'..." - $result = az sql instance-pool update --name $pool.name --resource-group $pool.resourceGroup --license-type $LicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["InstancePoolUpdated"] += $pool.name - } - } - catch { - Write-Error "An error occurred while updating SQL Instance Pools: $_" - } - - # --- Section: Update DataFactory SSIS Integration Runtimes --- - try { - Write-Output "Processing DataFactory SSIS Integration Runtime resources..." - Get-AzDataFactoryV2 | Where-Object { $_.ProvisioningState -eq "Succeeded" } | ForEach-Object { - Get-AzDataFactoryV2IntegrationRuntime -ResourceGroupName $_.ResourceGroupName -DataFactoryName $_.DataFactoryName | Where-Object { $_.Type -eq "Managed" -and $_.State -ne "Starting" } | ForEach-Object { - if ($_.LicenseType -ne $LicenseType) { - # Update the license type to $LicenseType. - $result = Set-AzDataFactoryV2IntegrationRuntime -ResourceGroupName $_.ResourceGroupName -DataFactoryName $_.DataFactoryName -Name $_.Name -LicenseType $LicenseType -Force - $finalStatus += $result - $report["ADFSSISUpdated"] += $_.Name - Write-Host ([Environment]::NewLine + "-- DataFactory '$($_.DataFactoryName)' integration runtime updated to license type $LicenseType") - } - } - } - } - catch { - Write-Error "An error occurred while updating DataFactory SSIS Integration Runtimes: $_" - } - - # --- Section: Finalize SQL VM updates for those that were started on-demand --- - $sqlvm = "" - try { - $updated = $true - while ($sqlVmsToUpdate.Count -gt 0) { - $sqlvm = $sqlVmsToUpdate[0] - $vmStatus = az vm get-instance-view --resource-group $sqlvm.resourceGroup --name $sqlvm.name --query "{PowerState:instanceView.statuses[?starts_with(code, 'PowerState/')].displayStatus | [0]}" -o json | ConvertFrom-Json - if ($vmStatus.PowerState -eq "VM running") { - Write-Output "Now updating SQL VM '$($sqlvm.name)' after forced start..." - $result = az sql vm update -n $sqlvm.name -g $sqlvm.resourceGroup --license-type $SqlVmLicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["SQLVMUpdated"] += $sqlvm.name - Write-Output "Deallocating SQL VM '$($sqlvm.name)' post-update..." - az vm deallocate --resource-group $sqlvm.resourceGroup --name $sqlvm.name --no-wait yes - $sqlVmsToUpdate.RemoveAt(0) - $updated = $true - } - else { - if ($updated) { - Write-Host "Waiting for SQL VM '$($sqlvm.name)' to start..." - $updated = $false - } - else { - Write-Host "." -NoNewline - } - Start-Sleep -Seconds 30 - } - } - } - catch { - Write-Error "An error occurred while finalizing SQL VM updates in subscription '$($sub.name)': $sqlvm" - } - - # --- Section: Finalize SQL Managed Instance updates for those that were forced-start --- - $mi = "" - try { - $updated = $true - while ($sqlMIsToUpdate.Count -gt 0) { - $mi = $sqlMIsToUpdate[0] - $miStatus = az sql mi show --resource-group $mi.ResourceGroup --name $mi.Name -o json | ConvertFrom-Json - if ($miStatus.state -eq "Ready") { - Write-Output "Updating SQL Managed Instance '$($mi.Name)' after forced start..." - $result = az sql mi update --name $mi.Name --resource-group $mi.ResourceGroup --license-type $LicenseType -o json | ConvertFrom-Json - $finalStatus += $result - $report["SQLMIUpdated"] += $mi.Name - Write-Output "Stopping SQL Managed Instance '$($mi.Name)' post-update..." - az sql mi stop --resource-group $mi.ResourceGroup --mi $mi.Name --no-wait yes - $sqlMIsToUpdate.RemoveAt(0) - $updated = $true - } - else { - if ($updated) { - Write-Host "Waiting for SQL Managed Instance '$($mi.Name)' to be ready..." - $updated = $false - } - else { - Write-Host "." -NoNewline - } - Start-Sleep -Seconds 30 - } - } - } - catch { - Write-Error "An error occurred while finalizing SQL Managed Instance updates in subscription '$($sub.name)': $mi" - } - - } - catch { - Write-Error "An error occurred while processing subscription '$($sub.name)': $_" - } -} - -$scriptEndTime = Get-Date -$totalDuration = $scriptEndTime - $scriptStartTime - -# --- Final Report --- -Write-Output "`n===== Final Report =====" -Write-Output "Script started at: $scriptStartTime" -Write-Output "Script ended at: $scriptEndTime" -Write-Output "Total duration: $($totalDuration.ToString())" -Write-Output "`nResources updated by category:" - -if ($report["SQLVMUpdated"].Count -gt 0) { - Write-Output "SQL VMs Updated: $($report["SQLVMUpdated"] -join ', ')" -} else { - Write-Output "SQL VMs Updated: None" -} - -if ($report["SQLMIUpdated"].Count -gt 0) { - Write-Output "SQL Managed Instances Updated: $($report["SQLMIUpdated"] -join ', ')" -} else { - Write-Output "SQL Managed Instances Updated: None" -} - -if ($report["SQLDBUpdated"].Count -gt 0) { - Write-Output "SQL Databases Updated: $($report["SQLDBUpdated"] -join ', ')" -} else { - Write-Output "SQL Databases Updated: None" -} - -if ($report["ElasticPoolUpdated"].Count -gt 0) { - Write-Output "Elastic Pools Updated: $($report["ElasticPoolUpdated"] -join ', ')" -} else { - Write-Output "Elastic Pools Updated: None" -} - -if ($report["InstancePoolUpdated"].Count -gt 0) { - Write-Output "SQL Instance Pools Updated: $($report["InstancePoolUpdated"] -join ', ')" -} else { - Write-Output "SQL Instance Pools Updated: None" -} - -if ($report["ADFSSISUpdated"].Count -gt 0) { - Write-Output "SQL ADF SSIS: $($report["ADFSSISUpdated"] -join ', ')" -} else { - Write-Output "SQL ADF SSIS Updated: None" -} \ No newline at end of file