In this blog post, you’ll discover how to utilize an Azure PowerShell script for removing an Extended Security License (ESU) by using the Azure Arc WS2012 ESU ARM APIs.
Currently, you can only provision and manage Windows Server 2012 and Windows Server 2012 R2 ESU lifecycle operations programmatically using Azure Arc WS2012 ESU ARM APIs. Therefore, at the moment, to delete a license, an API command must be used as well.
To simplify and automate this deletion process, I created the following Azure PowerShell script, which includes the following steps and configurations:
- Remove the breaking change warning messages.
- Change the current context to the specified subscription.
- Delete the ESU license.
To use the script, first make a copy and save it as “Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs.ps1” or you can download it directly from GitHub.
Before utilizing the script, adjust all variables according to your requirements (an example is provided below). Once adjusted, run the customized script using Windows Terminal, Visual Studio Code, or Windows PowerShell. Or you can simply run it from Cloud Shell.
If you are not running the script from Cloud Shell, don’t forget to sign in with the Connect-AzAccount cmdlet to connect your Azure account.
If you encounter an error with the code “InvalidApiVersionParameter” while executing the script, simply adjust the $apiVersion variable to a different version, such as 2022-07-01 or 2023-06-20-preview. In case you face an error when running the script from CloudShell, consider redeploying your CloudShell configuration and check if the issue persists.
You can then run the script with the required parameters:
.\Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs -SubscriptionName <"your Azure subscription name here"> -EsuLicenseName <"your ESU license name here">
<#
.SYNOPSIS
A script used to remove an ESU license by using the Azure Arc WS2012 ESU ARM APIs.
.DESCRIPTION
A script used to remove an ESU license by using the Azure Arc WS2012 ESU ARM APIs.
This script will do all of the following:
Remove the breaking change warning messages.
Change the current context to the specified Azure subscription.
Delete the ESU license.
.NOTES
Filename: Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs.ps1
Created: 18/10/2023
Last modified: 05/12/2023
Author: Wim Matthyssen
Version: 1.5
PowerShell: Azure PowerShell and Azure Cloud Shell
Requires: PowerShell Az (v10.4.1)
Action: Change variables were needed to fit your needs.
Disclaimer: This script is provided "as is" with no warranties.
.EXAMPLE
Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "<xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx>" (if not using the default tenant)
Set-AzContext -Subscription "<SubscriptionName>" (if not using the default subscription)
.\Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs -SubscriptionName <"your Azure subscription name here"> -EsuLicenseName <"your ESU license name here">
.LINK
https://wmatthyssen.com/2023/10/20/azure-arc-remove-an-extended-security-license-with-an-azure-powershell-script/
#>
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Parameters
param(
# $subscriptionName -> Name of the Azure Subscription
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $subscriptionName,
# $esuLicenseName -> Name of the ESU license
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $esuLicenseName
)
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
$region = #<your region here> The used Azure public region. Example: "westeurope"
$rgNameArcManagement = #<your Azure Arc management resource group name here> The name of the Azure resource group in which your Azure Arc managment resources are deployed. Example: "rg-prd-myh-arc-management-01"
$apiVersion = "?api-version=" + "2023-10-03-preview" #older versions 2022-07-01; 2023-06-20-preview
# Time, colors, and formatting
Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime = Get-Date -Format "dddd MM/dd/yyyy HH:mm"} | Out-Null
$foregroundColor1 = "Green"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Remove the breaking change warning messages
Set-Item -Path Env:\SuppressAzurePowerShellBreakingChangeWarnings -Value $true | Out-Null
Update-AzConfig -DisplayBreakingChangeWarning $false | Out-Null
$warningPreference = "SilentlyContinue"
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script started
Write-Host ($writeEmptyLine + "# Script started. Without errors, it can take up to 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Change the current context to the specified subscription
$subName = Get-AzSubscription | Where-Object {$_.Name -like $subscriptionName}
Set-AzContext -SubscriptionId $subName.SubscriptionId | Out-Null
Write-Host ($writeEmptyLine + "# Specified subscription in current tenant selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Delete the ESU license
# Construct the URI for the Azure resource to be deleted
$URI = "https://management.azure.com/subscriptions/" + $subName.SubscriptionId + "/resourceGroups/" + $rgNameArcManagement + "/providers/Microsoft.HybridCompute/licenses/" + $esuLicenseName + $apiVersion
# Get the Azure access token and store it in a variable
$accessToken = (Get-AzAccessToken -ResourceUrl https://management.azure.com).Token
# Prepare headers for the API request
$headers = [ordered]@{"Content-Type"="application/json"; "Authorization"="Bearer $accessToken"}
# Specify the HTTP method for the request (in this case, DELETE)
$method = "DELETE"
# Define the JSON body for the request (replace $region with the actual region value in the variables section)
$body = '{"location": $region}'
# Set the security protocol to TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Send the HTTP request to the specified URI with the provided method, headers, and body
Invoke-WebRequest -URI $URI -Method $method -Headers $headers -Body $body | Out-Null
Write-Host ($writeEmptyLine + "# ESU license $esuLicenseName deleted" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Conclusion
Currently, the only method to programmatically handle Windows Server 2012/2012 R2 ESU lifecycle operations is by using Azure Arc WS2012 ESU ARM APIs.
So, I hope that the Azure PowerShell script provided in this blog post will be useful for you, simplifying the process of deleting existing ESU licenses in your Azure environment.
If you have any questions or suggestions about this script, please don’t hesitate to contact me via my X handle (@wmatthyssen) or simply leave a comment, and I’ll be more than happy to assist.
Hi Wim
Just trying your script but I get the following error on line 86 when running via Cloud Shell.
PS /home/kevin> Set-AzContext -SubscriptionId $subName.SubscriptionId | Out-Null
Set-AzContext: Cannot validate argument on parameter ‘Subscription’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
I’m 100% sure I’ve set all the correct Variables.
Any help would be much appreciated.
Kind Regards
Kevin
LikeLike
Hi Kevin, did you upload the script to your cloud drive, or did you just copy and run it? I ask because when I upload it to my cloud drive and run it with parameters like this: .\Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs.ps1 -SubscriptionName sub-prd-myh-arc-01 -EsuLicenseName esu-st-vcore-license-05, it works perfectly fine.
LikeLike
Did you used the latest version of the script? https://github.com/wimmatthyssen/Azure-Arc/blob/1e81d1bb2984acdb3c00284f33fa49b3272355c9/Remove-ESU-license-using-Azure-Arc-WS2012-ESU-ARM-APIs.ps1
LikeLike
Hi Wim
Yes I used the GitHub version and tried both ways, uploading it to cloud drive and also tried just running it by adding the parameters for the subscription name and license name as variables. Both ways produced the same error unfortunately.
LikeLike
Hello Kevin, I just sent you an email to help you fix the problem you have with your customized script.
LikeLike
Subscription name corrected, script now works, thanks Wim.
LikeLike
I am having an issue with the API version, getting error:
Invoke-WebRequest : {“error”:{“code”:”InvalidApiVersionParameter”,”message”:”The api-version ‘2023-06-20-preview’ is invalid. The
supported versions are ‘2023-07-01,2023-07-01-preview,2023-03-01-preview,2022-12-01,2022-11-01-preview,2022-09-01,2022-06-01,2022-05-01,2
022-03-01-preview,2022-01-01,2021-04-01,2021-01-01,2020-10-01,2020-09-01,2020-08-01,2020-07-01,2020-06-01,2020-05-01,2020-01-01,2019-11-0
1,2019-10-01,2019-09-01,2019-08-01,2019-07-01,2019-06-01,2019-05-10,2019-05-01,2019-03-01,2018-11-01,2018-09-01,2018-08-01,2018-07-01,201
8-06-01,2018-05-01,2018-02-01,2018-01-01,2017-12-01,2017-08-01,2017-06-01,2017-05-10,2017-05-01,2017-03-01,2016-09-01,2016-07-01,2016-06-
01,2016-02-01,2015-11-01,2015-01-01,2014-04-01-preview,2014-04-01,2014-01-01,2013-03-01,2014-02-26,2014-04’.”}}
At line:114 char:13
I tried different API version I am getting: {“message”:”No HTTP resource was found that matches the request URI….
What could be the problem?
Thanks.
LikeLike
Hey Michal, I’ve made some updates to the script using the latest API version. Could you please give it a try and see if everything is working now
LikeLike
Hi, thanks it work now!
LikeLiked by 1 person
Hey i got an error – “{“error”:{“code”:”InvalidApiVersionParameter”,”message”:”The api-version ‘2023-06-20-preview’ is invalid”
Any ideas?
Thanks
Craig
LikeLike
Hey Craig, I’ve made some updates to the script using the latest API version. Could you please give it a try and see if everything is working now?
LikeLike
Hi! Thanks for the script. It helped me a lot. Please update the API version to 2023-10-03-preview.
It would be good to have the resource group and location in parameters like this:
param(
# $subscriptionName -> Name of the Azure Subscription
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $subscriptionName,
# $esuLicenseName -> Name of the ESU license
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $esuLicenseName,
# $rgNameArcManagement -> Name of the Azure Arc management resource group
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $rgNameArcManagement,
# $region -> The used Azure public region
[parameter(Mandatory =$true)][ValidateNotNullOrEmpty()] [string] $region
)
## —————————————————————————————————
## Variables
# $region = # The used Azure public region. Example: “westeurope”
# $rgNameArcManagement = # The name of the Azure resource group in which your Azure Arc managment resources are deployed. Example: “rg-prd-myh-arc-management-01”
LikeLike
Hi Oleksandr, I had already updated the API version on my end. But now, I’ve also added this change to the GitHub version of the script. Thanks for the suggestion.
LikeLike
Pingback: Festive Tech Calendar 2023: Exploring Azure Arc – Unleashing Extended Security Updates! – Wim Matthyssen