Skip to content

Commit 24b19c6

Browse files
authored
Merge pull request #857 from anosov1960/master
Added sql-license-usage.ps1
2 parents 9f3fc0d + 4a991eb commit 24b19c6

File tree

2 files changed

+295
-4
lines changed

2 files changed

+295
-4
lines changed

samples/manage/azure-hybrid-benefit/README.md

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,63 @@
11
---
2-
services: azure automation
3-
platforms: azure
2+
services: Azure SQL
3+
platforms: Azure
44
author: anosov1960
5+
ms.author: sashan
6+
ms.date: 12/15/2020
57
---
68

7-
# Managing Azure Hybrid Benefit
9+
# Overview
10+
11+
This script is provided to help you manage the SQL Server licenses that are consumed by the SQL Servers deployed to Azure. The script's output is a `sql-license-usage.csv` file with the consolidated SQL Server license usage by all SQL resources in the specific subscriptions or the entire account. The usage is broken down into the following categories of licenses:
12+
13+
- AHB Standard vCores
14+
- AHB Enterprise vCores
15+
- PAYG Standard vCores
16+
- PAYG Enterprise vCores
17+
- HADR Standard vCores
18+
- HADR Enterprise vCores
19+
- Developer vCores
20+
- Express vCores
21+
22+
>[!NOTE]
23+
> - The usage data is a snapshot at the time of the script execution based on the size of the deployed SQL resources in vCores.
24+
> - For IaaS workloads, such as SQL Server in Virtual Machines or SSIS integration runtimes, each vCPU is counted as one vCore.
25+
> - For PaaS workloads, each vCore of Business Critical service tier is counted as one Enterprise vCore and each vCore of General Purpose service tier is counted as one Standard vCore.
26+
27+
28+
# Running the script using Cloud Shell
29+
30+
Use the following steps to calculate the SQL Server license usage:
31+
32+
1. Launch the [Cloud Shell](https://shell.azure.com/). For details, [read more about PowerShell in Cloud Shell](https://aka.ms/pscloudshell/docs).
33+
34+
2. Upload the script to the shell using the following command:
35+
36+
```console
37+
curl https://raw.githubusercontent.com/microsoft/sql-server-samples/master/samples/manage/azure-hybrid-benefit/sql-license-usage.ps1 -o sql-license-usage.ps1
38+
```
39+
40+
3. Run the script in interactive mode. The script will prompt for a subscriptions ID or `*`. The latter will automatically scan all the subscriptions in you account.
41+
42+
```console
43+
./sql-license-usage.ps1
44+
```
45+
46+
If you need to scan a subset of the subscriptions, use the following steps:
47+
48+
1. Create a `.csv` with the list off all subscriptions in your account using the following command. You can edit the file to remove the subscriptions you don't want to scan.
49+
50+
```console
51+
Get-AzSubscription | Export-Csv .\mysubscriptions.csv -NoTypeInformation
52+
```
53+
54+
2. Run the script and specify the `.csv` file as a parameter.
55+
```console
56+
./sql-license-usage.ps1 .\mysubscriptions.csv
57+
```
58+
59+
> [!NOTE]
60+
> - To paste the commands into the shell, use `Ctrl-Shift-V` on Windows or `Cmd-v` on MacOS.
61+
> - The script will be uploaded directly to the home folder associated with your Cloud Shell session.
62+
> - The script will prompt for the resource group name and print a message when migration is completed.
863

9-
Provides the scripts to help you manage the [Azure Hybrid Benefit](https://azure.microsoft.com/pricing/hybrid-benefit/).
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
# ----------------------------------------------------------------------------------
2+
#
3+
# Copyright Microsoft Corporation
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
# ---------------------------------------------------------------------------------
14+
#
15+
# Sample script to calculate the consolidated SQL Server license usage by all of the SQL resources in a specific subscription or the entire the account.
16+
#
17+
# This script accepts a .csv file as a parameter, which provides a list of subscriptions to be scanned for the license usage. You can create
18+
# such a file by the following command and then edit to remove the subscriptions you don't want to scan:
19+
# > Get-AzSubscription | Export-Csv .\mysubscriptions.csv -NoTypeInformation
20+
#
21+
# If no file is provided, the script will prompt for a subscriptiobn ID or `*`. The latter will automatically scan all the subscriptions you account
22+
# has access to.
23+
#
24+
#
25+
# NOTE: The script does not calculate usage for Azure SQL resources that use the DTU-based purchasing model
26+
#
27+
28+
# Import the subscription info
29+
30+
if ($args[0] -ne $null) {
31+
# Read subscription list from the .csv file
32+
$subscriptions = Import-Csv $args[0]
33+
} else {
34+
# Promt for the subscription
35+
$Id = read-host -Prompt "Enter Subscription ID"
36+
if ($Id -eq "*") {
37+
$subscriptions = Get-AzSubscription
38+
} else {
39+
$subscriptions = [PSCustomObject]@{SubscriptionId = $Id} | Get-AzSubscription
40+
}
41+
}
42+
43+
[System.Collections.ArrayList]$usage = @()
44+
$usage += ,(@("Subscription Name", "Subscription ID", "AHB Std vCores", "AHB Ent vCores", "PAYG Std vCores", "PAYG Ent vCores", "HADR Std vCores", "HADR Ent vCores", "Developer vCores", "Express vCores"))
45+
46+
#Save the VM SKU table
47+
$VM_SKUs = Get-AzComputeResourceSku
48+
49+
Write-Host ([Environment]::NewLine + "-- Scanning subscriptions...")
50+
51+
# Calculate usage for each subscription
52+
foreach ($sub in $subscriptions){
53+
54+
if ($sub.State -ne "Enabled") {continue}
55+
56+
try {
57+
Set-AzContext -SubscriptionId $sub.Id
58+
}catch {
59+
write-host "Invalid subscription: " $sub.Id
60+
{continue}
61+
}
62+
63+
# Total counts of different license types
64+
$total = [pscustomobject]@{ahb_std=0; ahb_ent=0; payg_std=0; payg_ent=0; hadr_std=0; hadr_ent=0; developer=0; express=0}
65+
66+
#Get all logical servers
67+
$servers = Get-AzSqlServer
68+
69+
#Get all SQL databadse resources in the subscription
70+
$databases = $servers | Get-AzSqlDatabase
71+
72+
# Get the databases with License Included and add to VCore count
73+
foreach ($db in $databases ){
74+
if ($db.SkuName -eq "ElasticPool") {continue}
75+
76+
if ($db.LicenseType -eq "LicenseIncluded") {
77+
if ($db.Edition -eq "BusinessCritical") {
78+
$total.ahb_ent += $db.Capacity
79+
} elseif ($db.Edition -eq "GeneralPurpose") {
80+
$total.ahb_std += $db.Capacity
81+
}
82+
}else{
83+
if ($db.Edition -eq "BusinessCritical") {
84+
$total.payg_ent += $db.Capacity
85+
} elseif ($db.Edition -eq "GeneralPurpose") {
86+
$total.payg_std += $db.Capacity
87+
}$table
88+
}
89+
}
90+
91+
#Get all SQL elastic pool resources in the subscription
92+
$pools = $servers | Get-AzSqlElasticPool
93+
94+
# Get the elastic pools with License Included and and add to VCore count
95+
foreach ($pool in $pools){
96+
if ($pool.LicenseType -eq "LicenseIncluded") {
97+
if ($pool.Edition -eq "BusinessCritical") {
98+
$total.ahb_ent += $pool.Capacity
99+
} elseif ($pool.Edition -eq "GeneralPurpose") {
100+
$total.ahb_std += $pool.Capacity
101+
}
102+
}else{
103+
if ($pool.Edition -eq "BusinessCritical") {
104+
$total.payg_ent += $pool.Capacity
105+
} elseif ($pool.Edition -eq "GeneralPurpose") {
106+
$total.payg_std += $pool.Capacity
107+
}
108+
}
109+
}
110+
111+
#Get all SQL managed instance resources in the subscription
112+
$instances = Get-AzSqlInstance
113+
114+
# Get the SQL managed instances with License Included and add to VCore count
115+
foreach ($ins in $instances){
116+
if ($ins.InstancePoolName -eq $null){
117+
if ($ins.LicenseType -eq "LicenseIncluded") {
118+
if ($ins.Sku.Tier -eq "BusinessCritical") {
119+
$total.ahb_ent += $ins.VCores
120+
} elseif ($ins.Sku.Tier -eq "GeneralPurpose") {
121+
$total.ahb_std += $ins.VCores
122+
}
123+
}else{
124+
if ($ins.Edition -eq "BusinessCritical") {
125+
$total.payg_ent += $pool.Capacity
126+
} elseif ($ins.Edition -eq "GeneralPurpose") {
127+
$total.payg_std += $ins.Capacity
128+
}
129+
}
130+
}
131+
}
132+
133+
#Get all instance pool resources in the subscription
134+
$ipools = Get-AzSqlInstancePool
135+
136+
# Get the instance pools with License Included and add to VCore count
137+
foreach ($ip in $ipools){
138+
if ($ip.LicenseType -eq "LicenseIncluded") {
139+
if ($ip.Edition -eq "BusinessCritical") {
140+
$total.ahb_ent += $ip.VCores
141+
} elseif ($ip.Edition -eq "GeneralPurpose") {
142+
$total.ahb_std += $ip.VCores
143+
}
144+
}else{
145+
if ($ip.Edition -eq "BusinessCritical") {
146+
$total.payg_ent += $ip.Capacity
147+
} elseif ($ip.Edition -eq "GeneralPurpose") {
148+
$total.payg_std += $ip.Capacity
149+
}
150+
}
151+
}
152+
153+
154+
#Get all SSIS imtegration runtime resources in the subscription
155+
$ssis_irs = Get-AzResourceGroup | Get-AzDataFactoryV2 | Get-AzDataFactoryV2IntegrationRuntime
156+
157+
# Get the VM size, match it with the corresponding VCPU count and add to VCore count
158+
foreach ($ssis_ir in $ssis_irs){
159+
# Select first size and get the VCPus available
160+
$size_info = $VM_SKUs | where { $_.Name -like $ssis_ir.NodeSize} | Select-Object -First 1
161+
162+
# Save the VCPU count
163+
$vcpu= $size_info.Capabilities | Where-Object {$_.name -eq "vCPUsAvailable"}
164+
165+
if ($ssis_ir.State -eq "Started"){
166+
if ($ssis_ir.LicenseType -like "LicenseIncluded"){
167+
if ($ssis_ir.Edition -like "Enterprise"){
168+
$total.ahb_ent += $vcpu.value
169+
}elseif ($ssis_ir.Edition -like "Standard"){
170+
$total.ahb_std += $vcpu.value
171+
}
172+
}elseif ($data.license -like "BasePrice"){
173+
if ($ssis_ir.Edition -like "Enterprise"){
174+
$total.payg_ent += $vcpu.value
175+
}elseif ($ssis_ir.Edition -like "Standard"){
176+
$total.payg_std += $vcpu.value
177+
}elseif ($ssis_ir.Edition -like "Developer"){
178+
$total.developer += $vcpu.value
179+
}elseif ($ssis_ir.Edition -like "Express"){
180+
$total.express += $vcpu.value
181+
}
182+
}
183+
}
184+
}
185+
186+
187+
#Get All SQL VMs resources in the subscription
188+
$sql_vms = Get-AzSqlVM
189+
190+
# Get the VM size, match it with the corresponding VCPU count and add to VCore count
191+
foreach ($sql_vm in $sql_vms){
192+
$vm = Get-AzVm -Name $sql_vm.Name -ResourceGroupName $sql_vm.ResourceGroupName
193+
$vm_size = $vm.HardwareProfile.VmSize
194+
# Select first size and get the VCPus available
195+
$size_info = $VM_SKUs | where {$_.ResourceType.Contains('virtualMachines') -and $_.Name -like $vm_size} | Select-Object -First 1
196+
# Save the VCPU count
197+
$vcpu= $size_info.Capabilities | Where-Object {$_.name -eq "vCPUsAvailable"}
198+
199+
if ($vcpu){
200+
$data = [pscustomobject]@{vm_resource_uri=$vm.Id;sku=$sql_vm.Sku;license=$sql_vm.LicenseType;size=$vm_size;vcpus=$vcpu.value}
201+
202+
if ($data.license -like "DR"){
203+
if ($data.sku -like "Enterprise"){
204+
$total.hadr_ent += $data.vcpus
205+
}elseif ($data.sku -like "Standard"){
206+
$total.hadr_std += $data.vcpus
207+
}
208+
}elseif ($data.license -like "AHUB"){
209+
if ($data.sku -like "Enterprise"){
210+
$total.ahb_ent += $data.vcpus
211+
}elseif ($data.sku -like "Standard"){
212+
$total.ahb_std += $data.vcpus
213+
}
214+
}elseif ($data.license -like "PAYG"){
215+
if ($data.sku -like "Enterprise"){
216+
$total.payg_ent += $data.vcpus
217+
}elseif ($data.sku -like "Standard"){
218+
$total.payg_std += $data.vcpus
219+
}elseif ($data.sku -like "Developer"){
220+
$total.developer += $data.vcpus
221+
}elseif ($data.sku -like "Express"){
222+
$total.express += $data.vcpus
223+
}
224+
}
225+
}
226+
}
227+
228+
229+
$usage += ,(@($sub.Name, $sub.Id, $total.ahb_std, $total.ahb_ent, $total.payg_std, $total.payg_ent, $total.hadr_std, $total.hadr_ent, $total.developer, $total.express))
230+
231+
}
232+
233+
$table = ConvertFrom-Csv ($usage | %{ $_ -join ','} )
234+
$table | Format-table
235+
$table | Export-Csv .\sql-license-usage.csv -NoTypeInformation
236+
237+
Write-Host ([Environment]::NewLine + "-- The usage data is saved to .\sql-license-usage.csv")

0 commit comments

Comments
 (0)