Force cancelation of subscription in Azure with REST call

Normally you can only cancel/disable a subscription by code if the subscription is empty.

If you add IgnoreResourceCheck=true and thereby still cancel the subscription. This give you the grace time before deletion. Remember to change {subscriptionId} in the URI

https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Subscription/cancel?IgnoreResourceCheck=true&api-version=2021-10-01

Documentation on grace period

https://docs.microsoft.com/en-us/azure/cost-management-billing/manage/cancel-azure-subscription#what-happens-after-subscription-cancellation

Azure function to test network connectivity on Hybrid/relay connection

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

$server = $Request.Query.Server
$port = $Request.Query.Port

try {  (new-object Net.Sockets.TcpClient).Connect($server,$port) }
catch { $closed = $true }

if ($closed) { Write-host "nogo"; $body = "nogo for " + $server + ":" + $port }
Else { Write-host "yeah" ; $body = "yeah, clear paths to "  + $server + ":" + $port }

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

Powershell script to activate client KMS on Windows Server

# Elevate to adm
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
 if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
  $CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
  Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
  Exit
 }
}

# Find OS
$OS = (Get-WMIObject win32_operatingsystem).Caption

if ($OS.Length -lt 2) { Write-host -ForegroundColor Yellow "Unable to determine OS"; Break}
Else { Write-host -ForegroundColor Green "$OS"}

# Find domain and check DNS
$Domain = (Get-WmiObject win32_computersystem).Domain
$DnsOutPUT = Resolve-DnsName -Name _vlmcs._tcp.$domain -Type SRV -ErrorAction SilentlyContinue
if ($DnsOutPUT.Length -lt 2) { Write-host -ForegroundColor Yellow "Unable to determine DNS records for KMS"; Break}

Else { Write-host -ForegroundColor Green "KMS server(s): " $DnsOutPUT.NameTarget}

# Test connectivity to KMS servers
foreach ( $KMSserver in $DnsOutPUT.NameTarget ) {
if ((Test-NetConnection -ComputerName $KMSserver -Port 1688 -ErrorAction SilentlyContinue).TcpTestSucceeded) { Write-host -ForegroundColor Green "Succesfully connected to:" $KMSserver}
}


# Build Array of KMS keys - https://docs.microsoft.com/en-us/windows-server/get-started/kms-client-activation-keys
$kmsKeys = @()
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2022 Datacenter";'Key'="WX4NM-KYWYW-QJJR4-XV3QB-6VM33" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2022 Standard";'Key'="VDYBN-27WPP-V4HQT-9VMD4-VMK7H" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2019 Datacenter";'Key'="WMDGN-G9PQG-XVVXX-R3X43-63DFG" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2019 Standard";'Key'="N69G4-B89J2-4G8F4-WWYCC-J464C" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2019 Essentials";'Key'="WVDHN-86M7X-466P6-VHXV7-YY726" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2016 Datacenter";'Key'="CB7KF-BWN84-R7R2Y-793K2-8XDDG" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2016 Standard";'Key'="WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2016 Essentials";'Key'="JCKRF-N37P4-C2D82-9YXRT-4M63B" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2012 R2 Standard";'Key'="D2N9P-3P6X9-2R39C-7RTCD-MDVJX" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2012 R2 Datacenter";'Key'="W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2012 R2 Essentials";'Key'="KNC87-3J2TX-XB4WP-VCPJV-M4FWM" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2008 R2 Standard";'Key'="YC6KT-GKW9T-YTKYR-T4X34-R7VHC" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2008 R2 Enterprise";'Key'="489J6-VHDMP-X63PK-3K798-CPX3Y" })
 $kmsKeys += New-Object –TypeName PSObject –Prop ([ordered]@{'OS'="Microsoft Windows Server 2008 R2 Datacenter";'Key'="74YFP-3QFB3-KQT8W-PMXWJ-7M648" })

# Set KMS Key
$SetKeyOutPut = cscript c:\windows\system32\slmgr.vbs /ipk $kmsKeys[$kmsKeys.os.IndexOf($OS)].key
$SetKeyOutClean = $SetKeyOutPut | select -last 2 | select -First 1

if ($SetKeyOutClean.Contains("successfully")) { Write-host -ForegroundColor Green "Set key succesfully"}
Else { Write-host -ForegroundColor Yellow $SetKeyOutClean ; break }

# Activate KMS 
$ActivateOutPut = cscript c:\windows\system32\slmgr.vbs /ato
$ActivateOutClean = $ActivateOutPut | select -last 2 | select -First 1

if ($ActivateOutClean.Contains("successfully")) { Write-host -ForegroundColor Green "Activated succesfully"}
Else { Write-host -ForegroundColor Yellow $ActivateOutClean ; break }