patterns/alz/scripts/old-scripts/Start-AMBARemediation.ps1 (164 lines of code) (raw):
<#
.SYNOPSIS
Remediates Azure Policy Assignments
.DESCRIPTION
This script is used to trigger remediation on a specific policy or policy set at management group scope.
It first calls the Azure REST API to get the policy assignments in the management group scope, then it iterates through the policy assignments, checking by name whether it's a policy set or an individual policy.
Depending on the result the script will either enumerate the policy set and trigger remediation for each individual policy in the set or trigger remediation for the individual policy.
.PARAMETER managementGroupName
The management group name where the policy assignments are located.
.PARAMETER policyName
The name of the policy or policy set to remediate.
.EXAMPLE
Modify the following variables to match your environment:
$pseudoRootManagementGroup = "The pseudo root management group id parenting the Platform and Landing Zones management groups"
$identityManagementGroup = "The management group id for Identity"
$managementManagementGroup = "The management group id for Management"
$connectivityManagementGroup = "The management group id for Connectivity"
$LZManagementGroup = "The management group id for Landing Zones"
Run the following commands to initiate remediation:
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $pseudoRootManagementGroup -policyName Notification-Assets
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $pseudoRootManagementGroup -policyName Alerting-ServiceHealth
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $platformManagementGroup -policyName Alerting-HybridVM
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $platformManagementGroup -policyName Alerting-VM
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $connectivityManagementGroup -policyName Alerting-Connectivity
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $identityManagementGroup -policyName Alerting-Identity
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $managementManagementGroup -policyName Alerting-Management
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-KeyManagement
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-LoadBalancing
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-NetworkChanges
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-RecoveryServices
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-Storage
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-HybridVM
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-VM
.\patterns\alz\scripts\Start-AMBA-ALZ-Remediation.ps1 -managementGroupName $LZManagementGroup -policyName Alerting-Web
.LINK
https://azure.github.io/azure-monitor-baseline-alerts/patterns/alz/deploy/Remediate-Policies/
#>
# The following SuppressMessageAttribute entries are used to surpress PSScriptAnalyzer tests against known exceptions as per:
# https://github.com/powershell/psscriptanalyzer#suppressing-rules
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '', Justification = 'False positive')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'False positive')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Justification = 'Approved verbs are not available for this scenario')]
Param(
[Parameter(Mandatory = $true)] [string] $managementGroupName,
[Parameter(Mandatory = $true)] [string] $policyName
)
# Function to trigger remediation for a single policy
Function Start-PolicyRemediation {
Param(
[Parameter(Mandatory = $true)] [string] $managementGroupName,
[Parameter(Mandatory = $true)] [string] $policyAssignmentName,
[Parameter(Mandatory = $true)] [string] $polassignId,
[Parameter(Mandatory = $false)] [string] $policyDefinitionReferenceId
)
$guid = New-Guid
#create remediation for the individual policy
$uri = "https://management.azure.com/providers/Microsoft.Management/managementGroups/$($managementGroupName)/providers/Microsoft.PolicyInsights/remediations/$($policyName)-$($guid)?api-version=2021-10-01"
$body = @{
properties = @{
policyAssignmentId = "$polassignId"
}
}
if ($policyDefinitionReferenceId) {
$body.properties.policyDefinitionReferenceId = $policyDefinitionReferenceId
}
$body = $body | ConvertTo-Json -Depth 10
Invoke-AzRestMethod -Uri $uri -Method PUT -Payload $body
}
#Function to get the policy assignments in the management group scope
function Get-PolicyType {
Param (
[Parameter(Mandatory = $true)] [string] $managementGroupName,
[Parameter(Mandatory = $true)] [string] $policyName
)
#Validate that the management group exists through the Azure REST API
$uri = "https://management.azure.com/providers/Microsoft.Management/managementGroups/$($managementGroupName)?api-version=2021-04-01"
$result = (Invoke-AzRestMethod -Uri $uri -Method GET).Content | ConvertFrom-Json -Depth 100
if ($result.error) {
throw "Management group $managementGroupName does not exist, please specify a valid management group name"
}
# Getting custom policySetDefinitions
$uri = "https://management.azure.com/providers/Microsoft.Management/managementGroups/$($managementGroupName)/providers/Microsoft.Authorization/policySetDefinitions?&api-version=2023-04-01"
$initiatives = (Invoke-AzRestMethod -Uri $uri -Method GET).Content | ConvertFrom-Json -Depth 100
#Get policy assignments at management group scope
$assignmentFound = $false
$uri = "https://management.azure.com/providers/Microsoft.Management/managementGroups/$($managementGroupName)/providers/Microsoft.Authorization/policyAssignments?`$filter=atScope()&api-version=2022-06-01"
$result = (Invoke-AzRestMethod -Uri $uri -Method GET).Content | ConvertFrom-Json -Depth 100
#iterate through the policy assignments
$result.value | ForEach-Object {
#check if the policy assignment is for the specified policy set definition
If ($($PSItem.properties.policyDefinitionId) -match "/providers/Microsoft.Authorization/policySetDefinitions/$policyName") {
# Go to enumerating policy set
$assignmentFound = $true
Enumerate-PolicySet -managementGroupName $managementGroupName -policyAssignmentObject $PSItem
}
Elseif ($($PSItem.properties.policyDefinitionId) -match "/providers/Microsoft.Authorization/policyDefinitions/$policyName") {
# Go to handling individual policy
$assignmentFound = $true
Enumerate-Policy -managementGroupName $managementGroupName -policyAssignmentObject $PSItem
}
Else {
# Getting parent initiative for unassigned individual policies
If ($initiatives) {
$parentInitiative = $initiatives.value | Where-Object { ($_.properties.policyType -eq 'Custom') -and ($_.properties.metadata -like '*_deployed_by_amba*') } | Where-Object { $_.properties.policyDefinitions.policyDefinitionReferenceId -eq $policyname }
# Getting the assignment of the parent initiative
If ($parentInitiative) {
If ($($PSItem.properties.policyDefinitionId) -match "/providers/Microsoft.Authorization/policySetDefinitions/$($parentInitiative.name)") {
# Invoking policy remediation
$assignmentFound = $true
Start-PolicyRemediation -managementGroupName $managementGroupName -policyAssignmentName $PSItem.name -polassignId $PSItem.id -policyDefinitionReferenceId $policyName
}
}
}
}
}
#if no policy assignments were found for the specified policy name, throw an error
If (!$assignmentFound) {
throw "No policy assignments found for policy $policyName at management group scope $managementGroupName"
}
}
# Function to enumerate the policies in the policy set and trigger remediation for each individual policy
function Enumerate-PolicySet {
param (
[Parameter(Mandatory = $true)] [string] $managementGroupName,
[Parameter(Mandatory = $true)] [object] $policyAssignmentObject
)
#extract policy assignment information
$policyAssignmentObject
$polassignId = $policyAssignmentObject.id
$name = $policyAssignmentObject.name
$policySetId = $policyAssignmentObject.properties.policyDefinitionId
$policySetId
$psetUri = "https://management.azure.com$($policySetId)?api-version=2021-06-01"
$policySet = (Invoke-AzRestMethod -Uri $psetUri -Method GET).Content | ConvertFrom-Json -Depth 100
$policySet
$policies = $policySet.properties.policyDefinitions
#iterate through the policies in the policy set
If ($policyAssignmentObject.properties.policyDefinitionId -match "/providers/Microsoft.Authorization/policySetDefinitions/Alerting-ServiceHealth") {
$policyDefinitionReferenceId = "Deploy_ServiceHealth_ActionGroups"
Start-PolicyRemediation -managementGroupName $managementGroupName -policyAssignmentName $name -polassignId $polassignId -policyDefinitionReferenceId $policyDefinitionReferenceId
Write-Host " Waiting for 5 minutes while remediating the 'Deploy Service Health Action Group' policy before continuing." -ForegroundColor Cyan
Start-Sleep -Seconds 360
}
Foreach ($policy in $policies) {
$policyDefinitionId = $policy.policyDefinitionId
$policyDefinitionReferenceId = $policy.policyDefinitionReferenceId
#trigger remediation for the individual policy
Start-PolicyRemediation -managementGroupName $managementGroupName -policyAssignmentName $name -polassignId $polassignId -policyDefinitionReferenceId $policyDefinitionReferenceId
}
}
#Function to get specific information about a policy assignment for a single policy and trigger remediation
function Enumerate-Policy {
param (
[Parameter(Mandatory = $true)] [string] $managementGroupName,
[Parameter(Mandatory = $true)] [object] $policyAssignmentObject
)
#extract policy assignment information
$polassignId = $policyAssignmentObject.id
$name = $policyAssignmentObject.name
$policyDefinitionId = $policyAssignmentObject.properties.policyDefinitionId
Start-PolicyRemediation -managementGroupName $managementGroupName -policyAssignmentName $name -polassignId $polassignId
}
#Main script
Get-PolicyType -managementGroupName $managementGroupName -policyName $policyName