Skip to content

Commit 062d005

Browse files
authored
Merge branch 'microsoft:master' into master
2 parents f2fdfa4 + 4962696 commit 062d005

File tree

2 files changed

+138
-70
lines changed

2 files changed

+138
-70
lines changed

samples/manage/azure-arc-enabled-sql-server/modify-license-type/README.md

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ services: Azure Arc-enabled SQL Server
33
platforms: Azure
44
author: anosov1960
55
ms.author: sashan
6-
ms.date: 6/4/2023
6+
ms.date: 7/5/2023
77
---
88

99

1010
# Overview
1111

12-
This script allows you to to set or change the license type on all Azure-connected SQL Servers
13-
on a specific resource, in a single resource group, a specific subscription, a list of subscriptions or all subscriptions to which you have access. By default, it sets the specified license type value on the servers where it is undefined. But you can request to set it on all servers in the selected scope.
12+
This script provides a scaleable solution to set or change the license type and/or enable or disable the ESU policy on all Azure-connected SQL Servers in a specified scope.
1413

1514
You can specify a single subscription to scan, or provide a list of subscriptions as a .CSV file.
1615
If not specified, all subscriptions your role has access to are scanned.
@@ -28,11 +27,12 @@ The script accepts the following command line parameters:
2827

2928
| **Parameter**                                         | **Value**                                                                       | **Description** |
3029
|:--|:--|:--|
31-
|-SubId|subscription_id *or* a file_name|Optional: subscription id or a .csv file with the list of subscriptions<sup>1</sup>. If not specified all subscriptions will be scanned|
32-
|-ResourceGroup |resource_group_name|Optional: Limit the scope to a specific resource group|
33-
|-MachineName |machine_name|Optional: Limit the scope to a specific machine|
34-
|-LicenceType | "Paid", "PAYG" or "LicenseOnly"| Required: Specifies the license type value |
35-
|-Force|\$True or \$False (default)|Optional. Set the new license type for all installed extensions. By default the value is set only if license type is undefined.|
30+
|-SubId|subscription_id *or* a file_name|Optional: Subscription id or a .csv file with the list of subscriptions<sup>1</sup>. If not specified all subscriptions will be scanned|
31+
|-ResourceGroup |resource_group_name|Optional: Limits the scope to a specific resource group|
32+
|-MachineName |machine_name|Optional: Limits the scope to a specific machine|
33+
|-LicenceType | "Paid", "PAYG" or "LicenseOnly"| Optional: Sets the license type to the specified value |
34+
|-EnableESU | "Yes", "No" | Optional. Enables the ESU policy the value is "Yrs" or disables it if the value is "No". To enable, the license type must be "Paid" or "PAYG"|
35+
|-Force| |Optional. Forces the change of the license type to the specified value on all installed extensions. If -Force is not specified, the -LicenseType value is set only if undefined. Ignored if -LicenseType is not specified|
3636

3737
<sup>1</sup>You can create a .csv file using the following command and then edit to remove the subscriptions you don't want to scan.
3838
```PowerShell
@@ -52,15 +52,31 @@ The following command will scan all the subscriptions to which the user has acce
5252
The following command will scan the subscription `<sub_id>` and set the license type value to "Paid" on all servers.
5353

5454
```PowerShell
55-
.\modify-license-type.ps1 -SubId <sub_id> -LicenseType Paid -Force $True
55+
.\modify-license-type.ps1 -SubId <sub_id> -LicenseType Paid -Force
5656
```
5757

5858
## Example 3
5959

60-
The following command will scan resource group <resource_group_name> in the subscription `<sub_id>` and set the license type value to "PAYG" on all servers.
60+
The following command will scan resource group `<resource_group_name>` in the subscription `<sub_id>` and set the license type value to "PAYG" on all servers.
6161

6262
```PowerShell
63-
.\modify-license-type.ps1 -SubId <sub_id> -ResourceGroup <resource_group_name> -LicenseType PAYG -Force $True
63+
.\modify-license-type.ps1 -SubId <sub_id> -ResourceGroup <resource_group_name> -LicenseType PAYG -Force
64+
```
65+
66+
## Example 4
67+
68+
The following command will set License Type to 'Paid" and enables ESU on all servers in the subscriptions `<sub_id>` and the resource group `<resource_group_name>`.
69+
70+
```console
71+
.\modify-license-type.ps1 -SubId <sub_id> -ResourceGroup <resource_group_name> -LicenseType Paid -EnableESU Yes -Force
72+
```
73+
74+
## Example 5
75+
76+
The following command will disable ESU on all servers in the subscriptions `<sub_id>`.
77+
78+
```console
79+
.\modify-license-type.ps1 -SubId <sub_id> -EnableESU No
6480
```
6581

6682
# Running the script using Cloud Shell
@@ -81,11 +97,7 @@ This option is recommended because Cloud shell has the Azure PowerShell modules
8197
curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-license-type.ps1 -o modify-license-type.ps1
8298
```
8399

84-
1. Run the script. The following command will set License Type to 'Paid" on all servers in all the subscriptions your role has access to.
85-
86-
```console
87-
.//modify-license-type.ps1 -LicenseType Paid -Force $true
88-
```
100+
1. Run the script.
89101

90102
> [!NOTE]
91103
> - To paste the commands into the shell, use `Ctrl-Shift-V` on Windows or `Cmd-v` on MacOS.
@@ -122,8 +134,4 @@ Use the following steps to run the script in a PowerShell session on your PC.
122134
Connect-AzAccount -TenantID (Get-AzureADTenantDetail).ObjectId
123135
```
124136

125-
1. Run the script using the desired scope. The following command will set License Type to 'Paid" on all servers in the specified subscription.
126-
127-
```console
128-
.//modify-license-type.ps1 -SubId <sub_id> -LicenseType Paid -Force $true
129-
```
137+
1. Run the script.

samples/manage/azure-arc-enabled-sql-server/modify-license-type/modify-license-type.ps1

Lines changed: 109 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
#
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.
2+
# This script provides a scaleable solution to set or change the license type and/or enable or disable the ESU policy
3+
# on all Azure-connected SQL Servers in a specified scope.
54
#
65
# You can specfy a single subscription to scan, or provide subscriptions as a .CSV file with the list of IDs.
76
# If not specified, all subscriptions your role has access to are scanned.
87
#
98
# The script accepts the following command line parameters:
109
#
11-
# -SubId [subscription_id] | [csv_file_name] (Limit scope to specific subscriptions. Accepts a .csv file with the list of subscriptions.
10+
# -SubId [subscription_id] | [csv_file_name] (Optional. Limits the scope to specific subscriptions. Accepts a .csv file with the list of subscriptions.
1211
# If not specified all subscriptions will be scanned)
13-
# -ResourceGroup [resource_goup] (Limit scope to a specific resoure group)
14-
# -MachineName [machine_name] (Limit scope to a specific machine)
15-
# -LicenseType [license_type_value] (Specific LT value)
16-
# -Force (Required. Set the new license type on all installed extensions.
17-
# By default the value is set only if license type is undefined undefined)
12+
# -ResourceGroup [resource_goup] (Optional. Limits the scope to a specific resoure group)
13+
# -MachineName [machine_name] (Optional. Limits the scope to a specific machine)
14+
# -LicenseType [license_type_value] (Optional. Sets the license type to the specified value)
15+
# -EnabelESU [Yes or No] (Optional. Enables the ESU policy the value is "Yes" or disables it if the value is "No"
16+
# To enable, the license type must be "Paid" or "PAYG"
17+
# -Force (Optional. Forces the chnahge of the license type to the specified value on all installed extensions.
18+
# If Force is not specified, the -LicenseType value is set only if undefined. Ignored if -LicenseType is not specified
1819
#
19-
# The script uses a function ConvertTo-HashTable that was created by Adam Bertram (@adam-bertram).
20+
# This script uses a function ConvertTo-HashTable that was created by Adam Bertram (@adam-bertram).
2021
# The function was originally published on https://4sysops.com/archives/convert-json-to-a-powershell-hash-table/
2122
# and is used here with the author's permission.
2223
#
@@ -28,40 +29,16 @@ param (
2829
[string] $ResourceGroup,
2930
[Parameter (Mandatory= $false)]
3031
[string] $MachineName,
31-
[Parameter (Mandatory= $true)]
32+
[Parameter (Mandatory= $false)]
3233
[ValidateSet("PAYG","Paid","LicenseOnly", IgnoreCase=$false)]
3334
[string] $LicenseType,
3435
[Parameter (Mandatory= $false)]
35-
[boolean] $Force=$false
36+
[ValidateSet("Yes","No", IgnoreCase=$false)]
37+
[string] $EnableESU,
38+
[Parameter (Mandatory= $false)]
39+
[switch] $Force
3640
)
3741

38-
function CheckModule ($m) {
39-
40-
# This function ensures that the specified module is imported into the session
41-
# If module is already imported - do nothing
42-
43-
if (!(Get-Module | Where-Object {$_.Name -eq $m})) {
44-
# If module is not imported, but available on disk then import
45-
if (Get-Module -ListAvailable | Where-Object {$_.Name -eq $m}) {
46-
Import-Module $m
47-
}
48-
else {
49-
50-
# If module is not imported, not available on disk, but is in online gallery then install and import
51-
if (Find-Module -Name $m | Where-Object {$_.Name -eq $m}) {
52-
Install-Module -Name $m -Force -Verbose -Scope CurrentUser
53-
Import-Module $m
54-
}
55-
else {
56-
57-
# If module is not imported, not available and not in online gallery then abort
58-
write-host "Module $m not imported, not available and not in online gallery, exiting."
59-
EXIT 1
60-
}
61-
}
62-
}
63-
}
64-
6542
function ConvertTo-Hashtable {
6643
[CmdletBinding()]
6744
[OutputType('hashtable')]
@@ -101,6 +78,60 @@ function ConvertTo-Hashtable {
10178
}
10279
}
10380

81+
# This function checks if the specified module is imported into the session and if not installes and/or imports it
82+
function LoadModule
83+
{
84+
param (
85+
[parameter(Mandatory = $true)][string] $name
86+
)
87+
88+
$retVal = $true
89+
90+
if (!(Get-Module -Name $name))
91+
{
92+
$retVal = Get-Module -ListAvailable | Where-Object {$_.Name -eq $name}
93+
94+
if ($retVal)
95+
{
96+
try
97+
{
98+
Import-Module $name -ErrorAction SilentlyContinue
99+
}
100+
catch
101+
{
102+
write-host "The request to lload module $($name) failed with the following error:"
103+
write-host $_.Exception.Message
104+
$retVal = $false
105+
}
106+
}
107+
else {
108+
109+
# If module is not imported, not available on disk, but is in online gallery then install and import
110+
if (Find-Module -Name $name) {
111+
Install-Module -Name $name -Force -Verbose -Scope CurrentUser
112+
try
113+
{
114+
Import-Module $name -ErrorAction SilentlyContinue
115+
}
116+
catch
117+
{
118+
write-host "The request to lload module $($name) failed with the following error:"
119+
write-host $_.Exception.Message
120+
$retVal = $false
121+
}
122+
}
123+
else {
124+
125+
# If module is not imported, not available and not in online gallery then abort
126+
write-host "Module $($name) not imported, not available and not in online gallery, exiting."
127+
EXIT 1
128+
}
129+
}
130+
}
131+
132+
return $retVal
133+
}
134+
104135
#
105136
# Suppress warnings
106137
#
@@ -113,7 +144,7 @@ $requiredModules = @(
113144
"Az.ConnectedMachine",
114145
"Az.ResourceGraph"
115146
)
116-
$requiredModules | Foreach-Object {CheckModule $_}
147+
$requiredModules | Foreach-Object {LoadModule $_}
117148

118149
# Subscriptions to scan
119150

@@ -178,21 +209,50 @@ foreach ($sub in $subscriptions){
178209
ExtensionType = $r.extensionType
179210
}
180211

212+
$WriteSettings = $false
181213
$settings = @{}
182214
$settings = $r.properties.settings | ConvertTo-Json | ConvertFrom-Json | ConvertTo-Hashtable
183215

184-
if ($settings.ContainsKey("LicenseType")) {
185-
if ($Force) {
186-
if ($settings["LicenseType"] -ne $LicenseType ) {
216+
# set the license type or update (if -Force). ESU must be disabled to set to LicenseOnly.
217+
$LO_Allowed = (!$settings["enableExtendedSecurityUpdates"] -and !$EnableESU) -or ($EnableESU -eq "No")
218+
219+
if ($LicenseType) {
220+
if (($LicenseType -eq "LicenseOnly") -and !$LO_Allowed) {
221+
write-host "ESU must be disabled before license type can be set to $($LicenseType)"
222+
} else {
223+
if ($settings.ContainsKey("LicenseType")) {
224+
if ($Force) {
225+
$settings["LicenseType"] = $LicenseType
226+
$WriteSettings = $true
227+
}
228+
} else {
187229
$settings["LicenseType"] = $LicenseType
188-
Write-Host "Resource group: [$($r.resourceGroup)] Connected machine: [$($r.MachineName)] : License type: [$($settings["LicenseType"])]"
189-
Set-AzConnectedMachineExtension @setId -Settings $settings -NoWait | Out-Null
230+
$WriteSettings = $true
190231
}
191232
}
192-
} else {
193-
$settings["LicenseType"] = $LicenseType
194-
Write-Host "Resource group: [$($r.resourceGroup)] Connected machine: [$($r.MachineName)] : License type: [$($settings["LicenseType"])]"
195-
Set-AzConnectedMachineExtension @setId -Settings $settings -NoWait | Out-Null
233+
234+
}
235+
236+
# Enable ESU for qualified license types or disable
237+
if ($EnableESU) {
238+
if (($settings["LicenseType"] | select-string "Paid","PAYG") -or ($EnableESU -eq "No")) {
239+
$settings["enableExtendedSecurityUpdates"] = ($EnableESU -eq "Yes")
240+
$settings["esuLastUpdatedTimestamp"] = [DateTime]::UtcNow.ToString('yyyy-MM-ddTHH:mm:ss.fffZ')
241+
$WriteSettings = $true
242+
} else {
243+
write-host "The configured license type does not support ESUs"
244+
}
245+
}
246+
247+
If ($WriteSettings) {
248+
Write-Host "Resource group: [$($r.resourceGroup)] Connected machine: [$($r.MachineName)] : License type: [$($settings["LicenseType"])] : Enable ESU: [$($settings["enableExtendedSecurityUpdates"])]"
249+
try {
250+
Set-AzConnectedMachineExtension @setId -Settings $settings -NoWait | Out-Null
251+
} catch {
252+
write-host "The request to modify the extenion object failed with the following error:"
253+
write-host $_.Exception.Message
254+
{continue}
255+
}
196256
}
197257
}
198258
}

0 commit comments

Comments
 (0)