Skip to content

Commit

Permalink
Hydration kits updates, ALZ fixes (#684)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Watherston <[email protected]>
  • Loading branch information
anwather and Anthony Watherston authored Jun 21, 2024
1 parent b438ce3 commit ee3f2fb
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@
},
"parameters": {
"listOfResourceTypesNotAllowed": [
"microsoft.consumption/tags",
"microsoft.authorization/roleassignments",
"microsoft.authorization/roledefinitions",
"microsoft.authorization/policyassignments",
"microsoft.authorization/locks",
"microsoft.authorization/policydefinitions",
"microsoft.authorization/policysetdefinitions",
"microsoft.resources/tags",
"microsoft.authorization/roleeligibilityschedules",
"microsoft.authorization/roleeligibilityscheduleinstances",
"microsoft.authorization/roleassignmentschedules",
"microsoft.authorization/roleassignmentscheduleinstances"
"microsoft.network/expressroutecircuits",
"microsoft.network/expressroutegateways",
"microsoft.network/expressrouteports",
"microsoft.network/virtualwans",
"microsoft.network/virtualhubs",
"microsoft.network/vpngateways",
"microsoft.network/p2svpngateways",
"microsoft.network/vpnsites",
"microsoft.network/virtualnetworkgateways"
]
},
"nonComplianceMessages": [
Expand Down
1 change: 1 addition & 0 deletions Scripts/Helpers/Add-HelperScripts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
. "$PSScriptRoot/Write-AssignmentDetails.ps1"
. "$PSScriptRoot/Write-ErrorsFromErrorInfo.ps1"

. "$PSScriptRoot/RestMethods/Get-AzManagementGroupRestMethod.ps1"
. "$PSScriptRoot/RestMethods/Get-AzPolicyAssignmentRestMethod.ps1"
. "$PSScriptRoot/RestMethods/Get-AzPolicyExemptionsRestMethod.ps1"
. "$PSScriptRoot/RestMethods/Get-AzResourceListRestMethod.ps1"
Expand Down
2 changes: 1 addition & 1 deletion Scripts/Helpers/Build-ScopeTableForDeploymentRootScope.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function Build-ScopeTableForDeploymentRootScope {
-ScopeTable $scopeTable
}
else {
$managementGroup = Get-AzManagementGroup -GroupName $deploymentRootScopeManagementGroupName -Expand -Recurse -ErrorAction Stop
$managementGroup = Get-AzManagementGroupRestMethod -GroupId $deploymentRootScopeManagementGroupName -Expand -Recurse -ErrorAction Stop
$scopeDetails = Build-ScopeTableForManagementGroup `
-ManagementGroup $managementGroup `
-ResourceGroupsBySubscriptionId $resourceGroupsBySubscriptionId `
Expand Down
27 changes: 17 additions & 10 deletions Scripts/Helpers/Build-ScopeTableForManagementGroup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ function Build-ScopeTableForManagementGroup {
$notScopesList = [System.Collections.ArrayList]::new()
$notScopesTable = @{}
$excludedScopesTable = @{}
$managementGroupType = $ManagementGroup.Type
$managementGroupId = $ManagementGroup.Id
$managementGroupName = $ManagementGroup.Name
$managementGroupDisplayName = $ManagementGroup.DisplayName
$managementGroupChildren = $ManagementGroup.Children
#endregion initialize variables

#region get management group details
$managementGroupType = $ManagementGroup.type
$managementGroupId = $ManagementGroup.id
$managementGroupName = $ManagementGroup.name
$managementGroupDisplayName = $ManagementGroup.displayName
$managementGroupChildren = $ManagementGroup.children
if ($ManagementGroup.properties) {
$managementGroupDisplayName = $ManagementGroup.properties.displayName
$managementGroupChildren = $ManagementGroup.properties.children
}
#endregion get management group details

#region build scope details
$thisNotScope = $null
if ($null -ne $ParentScopeDetails) {
Expand Down Expand Up @@ -62,7 +69,7 @@ function Build-ScopeTableForManagementGroup {
excludedScopesTable = $excludedScopesTable
isExcluded = $IsExcluded
isInGlobalNotScope = $IsInGlobalNotScope
state = $resourceContainer.properties.state
state = "Enabled"
location = "global"
}
if ($IsExcluded) {
Expand All @@ -81,12 +88,12 @@ function Build-ScopeTableForManagementGroup {
#region recurse down the tree
if ($null -ne $managementGroupChildren) {
foreach ($child in $managementGroupChildren) {
$childId = $child.Id
$childId = $child.id
$childScopeDetails = $null
if ($child.Type -eq "/subscriptions") {
if ($child.type -eq "/subscriptions") {
$childScopeDetails = Build-ScopeTableForSubscription `
-SubscriptionId $child.Name `
-SubscriptionName $child.DisplayName `
-SubscriptionId $child.name `
-SubscriptionName $child.displayName `
-ResourceGroupsBySubscriptionId $ResourceGroupsBySubscriptionId `
-PacEnvironment $PacEnvironment `
-ScopeTable $ScopeTable `
Expand Down
6 changes: 3 additions & 3 deletions Scripts/Helpers/Get-HydrationChildManagementGroupNameList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ function Get-HydrrationChildManagementGroupNameList {
$ManagementGroupName
)
$childMgsList = @()
$mgs = Get-AzManagementGroup $ManagementGroupName -Recurse -Expand
$mgs = Get-AzManagementGroupRestMethod -GroupId $ManagementGroupName -Expand -Recurse
do {
$childMgs = @()
foreach ($mg in $mgs) {
$childMgsList += $mg
foreach ($cMg in $mg.Children) {
$childMgs += $cMg.Children | Where-Object { $_.Type -eq "Microsoft.Management/managementGroups" }
foreach ($cMg in $mg.properties.children) {
$childMgs += $cMg.properties.children | Where-Object { $_.Type -eq "Microsoft.Management/managementGroups" }
}
}
Clear-Variable mgs
Expand Down
33 changes: 27 additions & 6 deletions Scripts/Helpers/New-HydrationManagementGroupChildren.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
The New-HydrationManagementGroupChildren function takes a parent group name and a list of child names.
It then creates new child groups under the specified parent group.
.PARAMETER Hierarchy
An output from get-azmanagementgroup -GroupName $ManagementGroup -expand -Recurse, this will be used as the source for the management group copy job.
An output from Get-AzManagementGroupRestMethod -GroupId $ManagementGroup -Expand -Recurse , this will be used as the source for the management group copy job.
.PARAMETER Suffix
The prefix to be used for naming in the destination of the management group copy job.
.PARAMETER Prefix
Expand Down Expand Up @@ -38,7 +38,7 @@ function New-HydrationManagementGroupChildren {
}
Write-Debug "Suffix: $Suffix"
Write-Debug "Prefix: $Prefix"
foreach ($child in $Hierarchy.Children) {
foreach ($child in $Hierarchy.properties.children) {
$destParentGroupId = $( -join ("/providers/Microsoft.Management/managementGroups/", $Prefix, $Hierarchy.Name, $Suffix))
if ($child.Type -eq "Microsoft.Management/managementGroups") {
$newMGName = $( -join ($Prefix, $child.Name, $Suffix))
Expand All @@ -47,15 +47,36 @@ function New-HydrationManagementGroupChildren {
do {
$i++
if ($i -gt 1) {
Write-Warning " Last attempt failed, this is attempt number $i..."
Start-Sleep -seconds 30
Write-Warning " Last attempt appears to have failed, retry $i of 10..."
}
# Error action included because timeouts happen frequently, but mean nothing. Rather than have responses cause concern, we simply suppress the error and test. It takes longer, but this should be a task that is run very infrequently outside of a lab environment.
$newMg = New-AzManagementGroup -GroupName $newMGName -DisplayName $( -join ($Prefix, $child.DisplayName, $Suffix)) -ParentId $destParentGroupId -ErrorAction SilentlyContinue
}until($(Get-AzManagementGroup -GroupName $newMGName) -or $i -eq 10)
try {
$null = $newMg = New-AzManagementGroup -GroupName $newMGName -DisplayName $( -join ($Prefix, $child.DisplayName, $Suffix)) -ParentId $destParentGroupId -ErrorAction SilentlyContinue
}
catch {
Write-Information "Error: $_"
Write-Information "This is generally transient, so we test after, this is just here for debugging"
}
try {
$null = $testResult = Get-AzManagementGroupRestMethod -GroupId $newMGName -ErrorAction SilentlyContinue
}
catch {
$testResult = $false
}
}until($testResult.name -eq $newMGName -or $i -eq 10)
$mgChildren = $child.Children | Where-Object { $_.Type -eq "Microsoft.Management/managementGroups" }
if ($mgChildren.count -gt 0) {
Write-Information " Creating child Management Groups of $(-join($Prefix,$child.Name,$Suffix)) from $($mgChildren.Name -join ", ")..."
New-HydrationManagementGroupChildren -Hierarchy $child -Prefix $Prefix -Suffix $Suffix
do {
try {
$null = $childHierarchy = Get-AzManagementGroupRestMethod -GroupId $child.Name -Expand -Recurse
}
catch {
$testResult = $false
}
}until($testResult.name -or $i -eq 10)
New-HydrationManagementGroupChildren -Hierarchy $childHierarchy -Prefix $Prefix -Suffix $Suffix
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions Scripts/Helpers/Remove-HydrationChildHierarchy.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
function Remove-HydrationChildHierarchy {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
$ChildHierarchy
)
foreach ($child in $ChildHierarchy) {
if ($child.Type -eq "Microsoft.Management/managementGroups") {
# Error action included because timeouts happen frequently, but mean nothing. Rather than have responses cause concern, we simply suppress the error.
if ($child.children) {
Write-Information " Removing child objects of $($child.Name) -- $($child.children.Name -join ", ")..."
try {
Write-Debug "Starting Inner Loop"
$null = Remove-HydrationChildHierarchy -ChildHierarchy $child.children #-erroraction silentlycontinue
Write-Debug "Leaving Inner Loop"
}
catch {
write-error $_
}
}
do {
Write-Information " Removing $($child.Name)..."
$null = Remove-AzManagementGroup -GroupName $($child.Name)
try {
$null = Get-AzManagementGroupRestMethod -GroupId $($child.Name) -ErrorAction SilentlyContinue
}
catch {
if ($_.Exception.Message -match "NotFound") {
Write-Information " $($child.Name) confirmed to be removed..."
$complete = $true
}
else {
Write-Information " $($child.Name) generated an error during deletion, retrying $(6-$i) more times..."
$complete = $false
$i++
}
}
# }
}until($true -eq $complete -or $i -eq 6)
}
}
}
46 changes: 46 additions & 0 deletions Scripts/Helpers/RestMethods/Get-AzManagementGroupRestMethod.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

function Get-AzManagementGroupRestMethod {
[CmdletBinding()]
param (
[string] $ApiVersion = "2020-05-01",
[switch] $Expand,
[switch] $Recurse,
[string] $GroupID
)

# Print a message to indicate that the function is being called
Write-Debug "Get-AzManagementGroupRestMethod is being called"

# Assemble the API path
$path = "/providers/Microsoft.Management/managementGroups/$($GroupID)?api-version=$($ApiVersion)"
if ($Recurse) {
$path += "&`$recurse=True"
}
if ($Expand) {
$path += "&`$expand=children"
}

# Print the GroupID and API path for debugging
Write-Debug "GroupID: $GroupID"
Write-Debug "API Path: $path"

# Invoke the REST API
$response = Invoke-AzRestMethod -Path $path -Method GET

# Process response
$statusCode = $response.StatusCode
if ($statusCode -lt 200 -or $statusCode -ge 300) {
$content = $response.Content
Write-Error "Get Management Group error $($statusCode) -- $($content)" -ErrorAction Stop
}

# Convert the response content to a JSON object
$jsonContent = $response.Content | ConvertFrom-Json -Depth 100

# $jsonText = $jsonContent | ConvertTo-Json -Depth 100

return $jsonContent
}



12 changes: 7 additions & 5 deletions Scripts/HydrationKit/Copy-HydrationManagementGroupHierarchy.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,17 @@ $InformationPreference = "Continue"
if (!($Suffix) -and !($Prefix)) {
Write-Error "You must modify the name with either a Suffix, a Prefix, or both in order to replicate within the current tenant without naming collision errors."
}
$destParent = Get-AzManagementGroup -GroupName $DestinationParentGroupName -ErrorAction SilentlyContinue
if (!(Get-AzManagementGroup -GroupName $DestinationParentGroupName)) {
Write-Information "Destination Management Group $DestinationParentGroupName was not found."
try {
$null = $destParent = Get-AzManagementGroupRestMethod -GroupID $DestinationParentGroupName -ErrorAction SilentlyContinue
}
catch {
Write-Information $_.Exception.Message
Write-Error "Cannot continue, a valid `$DestinationParentGroupName must be specified to tell the cmdlet where to anchor your new hierarchy."
return
}
Write-Information "Beginning Duplication to $DestinationParentGroupName..."
$hierarchy = Get-AzManagementGroup -GroupName $SourceGroupName -Expand -Recurse
$hierarchy = Get-AzManagementGroupRestMethod -GroupID $SourceGroupName -Expand -Recurse
Write-Information " Creating $(-join($Prefix,$hierarchy.Name,$Suffix))..."
# Error action included because timeouts happen frequently, but mean nothing. Rather than have responses cause concern, we simply suppress the error.
$createdMg = New-AzManagementGroup -GroupName $( -join ($Prefix, $hierarchy.Name, $Suffix)) -DisplayName $( -join ($Prefix, $hierarchy.DisplayName, $Suffix)) -ParentId $destParent.Id -ErrorAction SilentlyContinue
$createdMg = New-AzManagementGroup -GroupName $( -join ($Prefix, $hierarchy.Name, $Suffix)) -DisplayName $( -join ($Prefix, $hierarchy.properties.displayName, $Suffix)) -ParentId $destParent.Id -ErrorAction SilentlyContinue
New-HydrationManagementGroupChildren -Hierarchy $hierarchy -Prefix $Prefix -Suffix $Suffix
8 changes: 4 additions & 4 deletions Scripts/HydrationKit/New-HydrationAnswerFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Clear-Variable repeat
Write-Information "`nResult Verified for variable $($tenantEntry.pacSelector), which will be used to identify the deployment to this Tenant.`n"

# Define intermediateRootGroupName
$tenantRootObject = Get-AzManagementGroup -GroupName $tenantEntry.tenantId -recurse -expand
$tenantRootObject = Get-AzManagementGroupRestMethod -GroupId $tenantEntry.tenantId -recurse -expand
$tenantChildrenString = $tenantRootObject.Children.Name -join ", "
do {
Write-Host "`n################################################################################"
Expand All @@ -123,7 +123,7 @@ do {

$tenantEntry.intermediateRootGroupName = Read-Host "What is the ID of your Intermediate Management Group Root?"
$repeat = $true
$test = Get-AzManagementGroup -GroupName $tenantEntry.intermediateRootGroupName
$test = Get-AzManagementGroupRestMethod -GroupId $tenantEntry.intermediateRootGroupName
}until($null -ne $test)
Clear-Variable repeat
Write-Information "`nResult Verified for variable intermediateRootGroupName: $($tenantEntry.intermediateRootGroupName)`n"
Expand All @@ -139,7 +139,7 @@ do {
Write-Host "Recommendation: $($tenantEntry.intermediateRootGroupName)"
$tenantEntry.initialPolicyScope = Read-Host "What is the ID of the Management Group for this PacSelector?"
$repeat = $true
$test = Get-AzManagementGroup -GroupName $tenantEntry.intermediateRootGroupName -ErrorAction SilentlyContinue
$test = Get-AzManagementGroupRestMethod -GroupID $tenantEntry.intermediateRootGroupName -ErrorAction SilentlyContinue
}until($null -ne $test)
Clear-Variable repeat
Clear-Variable test
Expand All @@ -164,7 +164,7 @@ do {
Write-Host "Recommendation: $($returnData.initialTenantId)"
$returnData.epacParentGroupName = Read-Host "What is the ID of the Management Group that you would like to use?"
$repeat = $true
$test = Get-AzManagementGroup -GroupName $returnData.epacParentGroupName -ErrorAction SilentlyContinue
$test = Get-AzManagementGroupRestMethod -GroupId $returnData.epacParentGroupName -ErrorAction SilentlyContinue
}until($null -ne $test)
Clear-Variable repeat
Clear-Variable test
Expand Down
Loading

0 comments on commit ee3f2fb

Please sign in to comment.