In my previous article I explained how to Create Your Own PowerShell APIs for Azure Governance with Azure Function App and how that can be useful for your daily Azure Administrator tasks.
Today I have another example of how to use that PowerShell API.
Azure Policies are a great way to prevent users from messing up your environment. But sometimes we need to make an exception to be able to deploy or edit something.
Here is a very simple PowerShell script that will allow you to add/remove exception Resource Group from your existing Azure Policy Assignment:
function Update-PolicyAssignmentExclusionList { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory = $true)] | |
[string]$PolicyAssignmentName, | |
[Parameter(Mandatory = $true)] | |
[string]$ResourceGroupName, | |
[Parameter(Mandatory = $true)] | |
[string]$Action | |
) | |
# Set the Azure context to the current subscription | |
Select-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id | |
# Get the policy assignment by name | |
$PolicyScope = "/subscriptions/$((Get-AzContext).Subscription.Id)" | |
$PolicyAssignment = Get-AzPolicyAssignment -Scope $PolicyScope | Where-Object { $_.Name -eq $PolicyAssignmentName } | |
if (!$PolicyAssignment) { | |
Write-Error "Policy assignment '$PolicyAssignmentName' does not exist." | |
} else { | |
# Get the resource group to modify | |
$ResourceGroup = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue | |
if (!$ResourceGroup) { | |
Write-Error "Resource group '$ResourceGroupName' does not exist." | |
} else { | |
# Get the existing exclusion list | |
$ExclusionList = $PolicyAssignment.Properties.NotScopes | |
# Add or remove the resource group from the exclusion list | |
if ($Action -eq "add") { | |
$ExclusionList += "/subscriptions/$((Get-AzContext).Subscription.Id)/resourceGroups/$ResourceGroupName" | |
} elseif ($Action -eq "remove") { | |
$ExclusionList = $ExclusionList | Where-Object { $_ -ne "/subscriptions/$((Get-AzContext).Subscription.Id)/resourceGroups/$ResourceGroupName" } | |
} | |
# Update the policy assignment with the new exclusion list | |
$PolicyAssignment.Properties.NotScopes = $ExclusionList | |
# NotScopes does not update if value is not provided. If the exclusion list is empty, set the NotScopes property to an empty array instead | |
if ($ExclusionList.Count -eq 0) { | |
$PolicyAssignment.Properties.NotScopes = @() | |
} | |
#Update the policy assignment | |
$PolicyAssignment | Set-AzPolicyAssignment | |
} | |
} | |
} |
Please note that if you created Policy Assignments from Portal and not from Templates, Policy Assignment Name will not be the name you see in the portal, but something completely different. You can check names like this:
Get-AzPolicyAssignment | select Name
The script will check if the provided policy assignment name exists and if the resource group exists before editing the policy assignment. If either one does not exist, it will return an error message and exit without modifying the policy assignment.
Here is how you can call your function:
Update-PolicyAssignmentExclusionList -PolicyAssignmentName "MyPolicyAssignment" -ResourceGroupName "MyResourceGroup" -Action "add"
Parameter values:
<policy-assignment-name>
: The name of the policy assignment to edit.<resource-group-to-modify>
: The name of the resource group to add or remove from the exclusion list.<add-or-remove>
: Either “add” or “remove” to indicate whether you want to add or remove the resource group from the exclusion list.
You can easily rewrite it to work inside Azure Functions. Additionally, you can customize the script further to suit your specific needs. For example, you can modify the script to add or remove multiple resource groups from the exclusion list at once, or to accept Subscriptions and Management Groups, or you can add error handling to provide more informative error messages.
Next time you receive a message that your deployment was denied due to Azure Policy, you will have a quick and easy way to crate temporary exception and proceed with your deployment.
And as a bonus, here is anoter quick script that you can use to quickly get the list of all Policy Assignments:
<# | |
This script will collect all policy assignments in available subscriptions and list them as a table. | |
#> | |
# Log in to your Azure account | |
#Connect-AzAccount | |
function Get-ScopeName($scopeId) { | |
if ($scopeId -match "/providers/Microsoft.Management/managementGroups/") { | |
$mgId = $scopeId -replace "/providers/Microsoft.Management/managementGroups/", "" | |
$mg = Get-AzManagementGroup -GroupName $mgId | |
return $mg.DisplayName | |
} elseif ($scopeId -match "/subscriptions/") { | |
$subId = $scopeId -replace "/subscriptions/", "" | |
$sub = Get-AzSubscription -SubscriptionId $subId | |
return $sub.Name | |
} elseif ($scopeId -match "/resourceGroups/") { | |
$subId = $scopeId -replace "/resourceGroups/.*", "" | |
$rgName = $scopeId -replace ".*/resourceGroups/", "" | |
$rg = Get-AzResourceGroup -Name $rgName -Scope "/subscriptions/$subId" | |
return $rg.ResourceGroupName | |
} else { | |
return "Unknown" | |
} | |
} | |
# Get all subscriptions | |
$subscriptions = Get-AzSubscription | |
# Initialize an empty array to store policy assignments and their scopes | |
$policyAssignmentsWithScopes = @() | |
# Loop through each subscription | |
foreach ($subscription in $subscriptions) { | |
# Select the current subscription | |
Set-AzContext -SubscriptionId $subscription.Id | |
# Get all policy assignments for the current subscription | |
$policyAssignments = Get-AzPolicyAssignment | |
# Loop through each policy assignment | |
foreach ($policyAssignment in $policyAssignments) { | |
# Get the scope name | |
$scopeName = Get-ScopeName -scopeId $policyAssignment.Properties.Scope | |
# Add policy assignment name and scope to the array | |
$policyAssignmentsWithScopes += [PSCustomObject]@{ | |
PolicyAssignmentName = $policyAssignment.Name | |
ScopeName = $scopeName | |
PolicyName = $policyAssignment.Properties.DisplayName | |
PolicyDescription = $policyAssignment.Properties.Description | |
Enforced = $policyAssignment.Properties.EnforcementMode | |
} | |
} | |
} | |
# Display policy assignments and their scopes | |
$policyAssignmentsWithScopes | Format-Table -AutoSize |
I hope this was useful. Keep clouding around.
Vukasin Terzic