-
Notifications
You must be signed in to change notification settings - Fork 1
/
Remove-AzManagementGroups.ps1
89 lines (78 loc) · 3.41 KB
/
Remove-AzManagementGroups.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#requires -version 7
#requires -module Az
<#
.SYNOPSIS
Script to delete all management groups in a tenant and resets all subscriptions to the tenant root group
.DESCRIPTION
Script to delete all management groups in a tenant and resets all subscriptions to the tenant root group
.PARAMETER TenantId
The tenant id to run the script against
.NOTES
Version: 1.1.2
Author: Jelle Broekhuijsen - jll.io Consultancy
Last Update: 4/9/2023
.EXAMPLE
./Remove-AzManagementGroups.ps1 -TenantId 00000000-0000-0000-0000-000000000000
#>
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]
$TenantId
)
$ErrorActionPreference = 'Continue'
$errorCount = 0
#Get all management groups except the root group
$managementGroups = Get-AzManagementGroup -ErrorAction Stop | Where-Object { $_.Name -ne $TenantId }
#Get all subscriptions
$subscriptions = Get-AzSubscription
#Create a concurrent bag to store failures
$failures = [System.Collections.Concurrent.ConcurrentBag[PSObject]]::new()
#Get all management group assignments for non-root assignme
$assignments = $managementGroups | ForEach-Object {
Get-AzManagementGroupSubscription -GroupName $_.Name
}
#Reset all subscriptions to the root group
$assignments | ForEach-Object -Parallel {
$localFailures = $using:failures
Write-Output "Reset subscription: $(($_.Id -split '/')[-1]) to root group."
$result = Remove-AzManagementGroupSubscription -GroupName ($_.Parent -split '/')[-1] -SubscriptionId ($_.Id -split '/')[-1]
if($result -ne $true) {
Write-Warning "Failed to reset subscription: $(($_.Id -split '/')[-1]) to root group."
$localFailures.Add($result)
}
}
#Remove the entire hierachy of management groups
Write-Output "Attempting to remove $($managementGroups.Count) management groups."
$lingeringManagementGroups = [System.Collections.Concurrent.ConcurrentBag[PSObject]]::new()
do {
$managementGroups | ForEach-Object -Parallel {
$localLingeringManagementGroups = $using:lingeringManagementGroups
$localFailures = $using:failures
$managementGroup = Get-AzManagementGroup -GroupName $_.Name -ErrorAction SilentlyContinue
if ($null -ne $managementGroup) {
Write-Output "Attempting to remove management group: $($managementGroup.Name)."
$result = Remove-AzManagementGroup -GroupName $managementGroup.Name -ErrorAction Continue
if ($result -ne $true) {
Write-Warning "'Remove-AzManagementGroup -GroupId $($managementGroup.Name)' did not return 'true', this will result in the script retrying the removal of this management group."
}
}
else {
Write-Output "Deleted management group '$($_.Name)' added to lingering management group count."
$localLingeringManagementGroups.Add($_)
}
}
$managementGroups = Get-AzManagementGroup | Where-Object { $_.Name -ne $TenantId }
if ($managementGroups.Count -gt 0 -and $lingeringManagementGroups.Count -lt $managementGroups.Count) {
Write-Output "Found $($managementGroups.Count - $lingeringManagementGroups.Count) remaining management groups to remove."
Write-Output "Waiting 30 seconds before retrying..."
$lingeringManagementGroups.Clear()
Start-Sleep -Seconds 30
}
}
while ($managementGroups.Count -gt 0 -and $lingeringManagementGroups.Count -lt $managementGroups.Count)
Write-Output "Successfully removed all management groups."
#Report failures
if($failures.Count -gt 0) {
Throw "Failed to remove $($failures.Count) management groups."
}