1+ #
2+ # This script provides a scaleable solution to set or change the license type on all Azure-connected SQL Servers
3+ # in a specific subscription, a list of subscruiptions or the entire account. By default, it sets the new license
4+ # type value only on the servers where it is undefined.
5+ #
6+ # You can specfy a single subscription to scan, or provide subscriptions as a .CSV file with the list of IDs.
7+ # If not specified, all subscriptions your role has access to are scanned.
8+ #
9+ # The script accepts the following command line parameters:
10+ #
11+ # -SubId [subscription_id] | [csv_file_name] (Accepts a .csv file with the list of subscriptions)
12+ # -LicenceType [license_type_value] (Specific LT value)
13+ # -All (Optional. Set the new license type value only if undefined)
14+ #
15+
16+ param (
17+ [Parameter (Mandatory = $false )]
18+ [string ] $SubId ,
19+ [Parameter (Mandatory = $false )]
20+ [string ] $LicenseType = " Paid" ,
21+ [Parameter (Mandatory = $false )]
22+ [string ] $SkipServers ,
23+ [Parameter (Mandatory = $false )]
24+ [boolean ] $All = $false
25+ )
26+
27+ function CheckModule ($m ) {
28+
29+ # This function ensures that the specified module is imported into the session
30+ # If module is already imported - do nothing
31+
32+ if (! (Get-Module | Where-Object {$_.Name -eq $m })) {
33+ # If module is not imported, but available on disk then import
34+ if (Get-Module - ListAvailable | Where-Object {$_.Name -eq $m }) {
35+ Import-Module $m
36+ }
37+ else {
38+
39+ # If module is not imported, not available on disk, but is in online gallery then install and import
40+ if (Find-Module - Name $m | Where-Object {$_.Name -eq $m }) {
41+ Install-Module - Name $m - Force - Verbose - Scope CurrentUser
42+ Import-Module $m
43+ }
44+ else {
45+
46+ # If module is not imported, not available and not in online gallery then abort
47+ write-host " Module $m not imported, not available and not in online gallery, exiting."
48+ EXIT 1
49+ }
50+ }
51+ }
52+ }
53+
54+
55+ #
56+ # Suppress warnings
57+ #
58+ Update-AzConfig - DisplayBreakingChangeWarning $false
59+
60+ # Load required modules
61+ $requiredModules = @ (
62+ " Az.Accounts" ,
63+ " Az.ConnectedMachine" ,
64+ " Az.ResourceGraph"
65+ )
66+ $requiredModules | Foreach-Object {CheckModule $_ }
67+
68+ # Subscriptions to scan
69+
70+ if ($SubId -like " *.csv" ) {
71+ $subscriptions = Import-Csv $SubId
72+ }elseif ($SubId -ne $null ){
73+ $subscriptions = [PSCustomObject ]@ {SubscriptionId = $SubId } | Get-AzSubscription
74+ }else {
75+ $subscriptions = Get-AzSubscription
76+ }
77+
78+
79+ Write-Host ([Environment ]::NewLine + " -- Scanning subscriptions --" )
80+
81+ # Scan arc-enabled servers in each subscription
82+
83+ foreach ($sub in $subscriptions ){
84+
85+ if ($sub.State -ne " Enabled" ) {continue }
86+
87+ try {
88+ Set-AzContext - SubscriptionId $sub.Id
89+ }catch {
90+ write-host " Invalid subscription: " $sub.Id
91+ {continue }
92+ }
93+
94+ $query = "
95+ resources
96+ | where type =~ 'microsoft.hybridcompute/machines/extensions'
97+ | extend extensionPublisher = tostring(properties.publisher), extensionType = tostring(properties.type)
98+ | where extensionPublisher =~ 'Microsoft.AzureData'
99+ | parse id with * '/providers/Microsoft.HybridCompute/machines/' machineName '/extensions/' *
100+ | project machineName, extensionName = name, resourceGroup, location, subscriptionId, extensionPublisher, extensionType, properties
101+ "
102+
103+ Search-AzGraph - Query $query | ForEach-Object {
104+
105+ $setID = @ {
106+ MachineName = $_.MachineName
107+ Name = $_.extensionName
108+ ResourceGroup = $_.resourceGroup
109+ Location = $_.location
110+ SubscriptionId = $_.subscriptionId
111+ Publisher = $_.extensionPublisher
112+ ExtensionType = $_.extensionType
113+ }
114+ $getID = @ {
115+ Name = $_.extensionName
116+ MachineName = $_.MachineName
117+ ResourceGroup = $_.resourceGroup
118+ SubscriptionId = $_.subscriptionId
119+ }
120+ $old = Get-AzConnectedMachineExtension @getID
121+ $settings = @ {}
122+ foreach ( $property in $_.properties.settings.psobject.properties.name ){ $settings [$property ] = $_.properties.settings .$property }
123+ if (-not $all ) {
124+ if (-not $settings.ContainsKey (" LicenseType" )) { $settings [" LicenseType" ] = $LicenseType }
125+ } else {
126+ $settings [" LicenseType" ] = $LicenseType
127+ }
128+ if ($_.properties.provisioningState -ne " Succeeded" ) {
129+ Write-Warning " Skipping extension on server $ ( $_.machineName ) because it's state is $ ( $_.properties.provisioningState ) " ;
130+ } else {
131+ Set-AzConnectedMachineExtension @setId - Settings $settings - NoWait
132+ $new = Get-AzConnectedMachineExtension @getID
133+ }
134+ }
135+ }
136+
137+
0 commit comments