Skip to content

Commit 8d98882

Browse files
authored
Merge pull request #1399 from anosov1960/PAYG-transition
Fixed RG filter for SQL DB
2 parents ce7b4b7 + bc8bede commit 8d98882

3 files changed

Lines changed: 180 additions & 0 deletions

File tree

samples/manage/azure-hybrid-benefit/modify-license-type/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ ms.date: 06/21/2025
2020

2121
05/30/2025 - Added transcript support
2222

23+
06/10/2025 - Fixed a RG filter for SQL DB
24+
2325

2426
# Overview
2527

samples/manage/azure-hybrid-benefit/modify-license-type/modify-azure-sql-license-type.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1.0.0 - Initial version.
1919
1.0.2 - Modified to fix errors and to remove the auto-start of the offline resources.
2020
1.0.3 - Added transcript.
21+
1.0.4 - Fixed RG filter for SQL DB
2122
2223
.PARAMETER SubId
2324
A single subscription ID or a CSV file name containing a list of subscriptions.
@@ -487,6 +488,9 @@ foreach ($sub in $subscriptions) {
487488
if ($tagsFilter) {
488489
$dbQuery += "$tagsFilter"
489490
}
491+
if ($rgFilter) {
492+
$dbQuery += " && $rgFilter"
493+
}
490494

491495
$dbQuery += "].{name:name, licenseType:licenseType, location:location, resourceGroup:resourceGroup, id:id, ResourceType:type, State:status}"
492496

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#
2+
# This script provides a scalable method to switch the license type to pay-as-you-go (aka LicenseIncluded) for all SQL resources in a specific subscription or the entire tenant. By default, the script scans
3+
# all subscriptions the user account has access. Alternatively, you can specify a single subscription or a .CSV file
4+
# with a list of subscription. The usage report includes the list of resources that have been affected by the change.
5+
#
6+
# The following resources are in scope for the license utilization analysis:
7+
# - Azure SQL databases (vCore-based purchasing model only)
8+
# - Azure SQL elastic pools (vCore-based purchasing model only)
9+
# - Azure SQL managed instances
10+
# - Azure SQL instance pools
11+
# - Azure Data Factory SSIS integration runtimes
12+
# - SQL Servers in Azure virtual machines
13+
#
14+
# The script accepts the following command line parameters:
15+
#
16+
# -SubId [subscription_id] | [csv_file_name] (Accepts a .csv file with the list of subscriptions)
17+
# -Cred [credential_object] (Required to save data to the database)
18+
# -FilePath [csv_file_name] (Required to save data in a .csv format. Ignored if database parameters are specified)
19+
#
20+
21+
param (
22+
[Parameter (Mandatory= $false)]
23+
[string] $SubId,
24+
[Parameter (Mandatory= $false)]
25+
[PSCredential] $Cred,
26+
[Parameter (Mandatory= $false)]
27+
[string] $FilePath
28+
)
29+
30+
function CheckModule ($m) {
31+
32+
# This function ensures that the specified module is imported into the session
33+
# If module is already imported - do nothing
34+
35+
if (!(Get-Module | Where-Object {$_.Name -eq $m})) {
36+
# If module is not imported, but available on disk then import
37+
if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) {
38+
Import-Module $m
39+
}
40+
else {
41+
42+
# If module is not imported, not available on disk, but is in online gallery then install and import
43+
if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) {
44+
Install-Module -Name $m -Force -Verbose -Scope CurrentUser
45+
Import-Module $m
46+
}
47+
else {
48+
49+
# If module is not imported, not available and not in online gallery then abort
50+
write-host "Module $m not imported, not available and not in online gallery, exiting."
51+
EXIT 1
52+
}
53+
}
54+
}
55+
}
56+
57+
#
58+
# Suppress warnings
59+
#
60+
Update-AzConfig -DisplayBreakingChangeWarning $false
61+
62+
$requiredModules = @(
63+
"Az.Accounts",
64+
"Az.Compute",
65+
"Az.DataFactory",
66+
"Az.Resources",
67+
"Az.Sql",
68+
"Az.SqlVirtualMachine"
69+
)
70+
$requiredModules | Foreach-Object {CheckModule $_}
71+
72+
# Subscriptions to scan
73+
74+
if ($SubId -like "*.csv") {
75+
$subscriptions = Import-Csv $SubId
76+
}elseif($SubId -ne $null){
77+
$subscriptions = [PSCustomObject]@{SubscriptionId = $SubId} | Get-AzSubscription
78+
}else{
79+
$subscriptions = Get-AzSubscription
80+
}
81+
82+
#Log file setup
83+
if (!$PSBoundParameters.ContainsKey("FilePath")) {
84+
$FilePath = '.\sql-change-log.csv'
85+
}
86+
87+
Write-Host ([Environment]::NewLine + "-- Scanning subscriptions --")
88+
89+
# Calculate usage for each subscription
90+
91+
foreach ($sub in $subscriptions){
92+
93+
if ($sub.State -ne "Enabled") {continue}
94+
95+
try {
96+
Set-AzContext -SubscriptionId $sub.Id
97+
}catch {
98+
write-host "Invalid subscription: " $sub.Id
99+
{continue}
100+
}
101+
102+
# Get all resource groups in the subscription
103+
$rgs = Get-AzResourceGroup
104+
105+
# Get all logical servers
106+
$servers = Get-AzSqlServer
107+
108+
# Scan all vCore-based SQL database resources in the subscription
109+
$servers | Get-AzSqlDatabase | Where-Object { $_.SkuName -ne "ElasticPool" -and $_.Edition -in @("GeneralPurpose", "BusinessCritical", "Hyperscale") } | ForEach-Object {
110+
if ($_.LicenseType -ne "LicenseIncluded") {
111+
Set-AzSqlDatabase -ResourceGroupName $_.ResourceGroupName -ServerName $_.ServerName -DatabaseName $_.DatabaseName -LicenseType "LicenseIncluded"
112+
Write-Host ([Environment]::NewLine + "-- Database $_.DatabaseName is set to \"LicenseIncluded\"")
113+
}
114+
}
115+
[system.gc]::Collect()
116+
117+
# Scan all vCore-based SQL elastic pool resources in the subscription
118+
$servers | Get-AzSqlElasticPool | Where-Object { $_.Edition -in @("GeneralPurpose", "BusinessCritical", "Hyperscale") } | ForEach-Object {
119+
if ($_.LicenseType -ne "LicenseIncluded") {
120+
Set-AzSqlElasticPool -ResourceGroupName $_.ResourceGroupName -ServerName $_.ServerName -ElasticPoolName $_.ElasticPoolName -LicenseType "LicenseIncluded"
121+
Write-Host ([Environment]::NewLine + "-- ElasticPool $_.ElasticPoolName is set to \"LicenseIncluded\"")
122+
}
123+
}
124+
[system.gc]::Collect()
125+
126+
# Scan all SQL managed instance resources in the subscription
127+
Get-AzSqlInstance | Where-Object { $_.InstancePoolName -eq $null } | ForEach-Object {
128+
if ($_.LicenseType -ne "LicenseIncluded") {
129+
Set-AzSqlInstance -ResourceGroupName $_.ResourceGroupName -ServerName $_.ServerName -InstanceName $_.InstanceName -LicenseType "LicenseIncluded"
130+
Write-Host ([Environment]::NewLine + "-- ElasticPool $_.ElasticPoolName is set to \"LicenseIncluded\"")
131+
}
132+
}
133+
[system.gc]::Collect()
134+
135+
# Scan all instance pool resources in the subscription
136+
Get-AzSqlInstancePool | Foreach-Object {
137+
if ($_.LicenseType -ne "LicenseIncluded") {
138+
Set-AzSqlInstancePool -ResourceGroupName $_.ResourceGroupName -ServerName $_.ServerName -InstanceName $_.InstanceName -LicenseType "LicenseIncluded"
139+
Write-Host ([Environment]::NewLine + "-- InstancePool $_.InstanceName is set to \"LicenseIncluded\"")
140+
}
141+
}
142+
[system.gc]::Collect()
143+
144+
# Scan all SSIS imtegration runtime resources in the subscription
145+
$rgs | Get-AzDataFactoryV2 | Get-AzDataFactoryV2IntegrationRuntime | Where-Object { $_.State -eq "Started" -and $_.NodeSize -ne $null } | ForEach-Object {
146+
if ($_.LicenseType -ne "LicenseIncluded") {
147+
# Set the license type to "LicenseIncluded"
148+
Set-AzDataFactoryV2IntegrationRuntime -ResourceGroupName $_.ResourceGroupName -DataFactoryName $_.DataFactoryName -Name $_.Name -LicenseType "LicenseIncluded"
149+
Write-Host ([Environment]::NewLine + "-- DataFactory $_.DataFactoryName is set to \"LicenseIncluded\"")
150+
}
151+
}
152+
[system.gc]::Collect()
153+
154+
# Scan all SQL VMs in the subscription
155+
$rgs | Get-AzVM | Where-Object { $_.StorageProfile.ImageReference.Offer -like "*sql*" -and $_.ProvisioningState -eq "Succeeded" } | ForEach-Object {
156+
$vmName = $_.Name
157+
$resourceGroupName = $_.ResourceGroupName
158+
159+
# Get the SQL configuration for the VM
160+
$sqlConfig = Get-AzVMExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name "SqlIaaSAgent"
161+
162+
if ($sqlConfig -ne $null) {
163+
$licenseType = $sqlConfig.Settings.LicenseType
164+
165+
if ($licenseType -ne "LicenseIncluded") {
166+
# Set the license type to "LicenseIncluded"
167+
Set-AzVMExtension -ResourceGroupName $resourceGroupName -VMName $vmName -Name "SqlIaaSAgent" -Publisher "Microsoft.SqlServer.Management" -ExtensionType "SqlIaaSAgent" -TypeHandlerVersion "1.5" -Settings @{ "LicenseType" = "LicenseIncluded" }
168+
Write-Host ([Environment]::NewLine + "-- SQL VM $vmName is set to \"LicenseIncluded\"")
169+
}
170+
171+
}
172+
}
173+
[system.gc]::Collect()
174+
}

0 commit comments

Comments
 (0)