Azure Policies are a foundational component to securing your cloud environment. One of the challenges you may run into is that it can bloat your tab memory and slow response over time when trying to navigate large Azure implementations using the Portal. Hopping around the Azure Portal can become unmanageable, evaluating different policies for Compliance, only to have it crash due to the large number of information it attempts to front load in your browser. I find it silly that it doesn’t release memory when you jump to different areas of Policy, but I guess fixing that (if they are aware of it at all) is in the almighty backlog.
In short: It caused me frustration. And this frustration led me down a path of figuring out how to export all of the Policies across all Subscriptions to CSV. I ended up using PowerShell to accomplish this and am sharing if anyone else has felt the pain.
The first thing we need to become familiar with are the Azure Policy PowerShell commands. Microsoft’s documentation on a few of these are lacking, and they don’t fully explain in enough detail what each of the parameters does. This is something else that caused additional frustration. Anyway, this script uses:
- Get-AzSubscription
- Set-AzContext
- Get-AzPolicyAssignment
- Get-AzPolicyState
Collectively, with some other built in PowerShell commands, we can paint a picture of our entire Azure Tenant and All Subscription Policy through Excel. Much, much easier.
Here’s the code, and then I’ll break out how it works in detail after if you’re interested. Note: You’ll need to use Connect-AzAccount first.
$date = (Get-Date -Format MM-dd-yy-hh-mm-ss).ToString()
$subs = get-azsubscription
$i = 1
Write-Host $subs.Count "Subscriptions" -ForegroundColor Green
foreach ($sub in $subs) {
write-host "Setting subscription to "$sub.Name -ForegroundColor Green
set-azcontext -subscriptionid $sub.Id
write-host "Set subscription to "$sub.Name -ForegroundColor Green
$assignedPols = get-azpolicyassignment
write-host "Got policy assignments for"$sub.Name -ForegroundColor Green
foreach ($pol in $assignedPols) {
Get-AzPolicyState -PolicyAssignmentName $pol.Name | Select-Object *, @{Name='SubscriptionName';Expression={$($sub.Name)}}, @{Name='State';Expression={$($sub.State)}} | Export-Csv -Path "c:\temp\polexp-$date.csv" -NoTypeInformation -Append
$polState = Get-AzPolicyState -PolicyAssignmentName $pol.Name
write-host "Got policy assignment details for"$pol.Name -ForegroundColor Green
}
write-host "$i of"$subs.Count"subs processed." -ForegroundColor Cyan
$i++
}
The first thing the script does is use Get-Date to a variable. The second thing it does is collect all of our Azure Subscriptions across the entire tenant into another variable.
The first foreach block begins looping through each Subscription and uses Set-AzContext to set the PowerShell boundaries to that Subscription. Then it collects all Policy Assignments to a variable. But this alone will not give us all the information we need, and instead just provides a high level export of what Azure Policy Assignments exist against the Subscription. It is not detailed at all, and it is annoying. This is where the next foreach loop comes into play.
The nested foreach block then takes each Policy Assignment in the Subscription and does a deep dive against it. Get-AzPolicyState takes each Policy within the Assignment to truly get an understanding of what is Compliant, NonCompliant, or Exempt. It ended up working pretty well.
This is really the meat and potatoes of the script:
Get-AzPolicyState -PolicyAssignmentName $pol.Name | Select-Object *, @{Name='SubscriptionName';Expression={$($sub.Name)}}, @{Name='State';Expression={$($sub.State)}} | Export-Csv -Path "c:\temp\polexp-$date.csv" -NoTypeInformation -Append
Let’s break it down.
We get the state of all Policies within a unique Assignment by using the -PolicyAssignmentName parameter. We pull the Assignment name by querying against the $pol.Name variable attribute.
Because I would rather have all of the information and filter out what I don’t need, I use Select-Object * to return every attribute available against the Policy. I then create two custom Object’s pulling in the Subscription Name (Which is much easier to understand then the Subscription ID) and State of the Subscription, which tells me if it’s Enabled or Disabled.
Lastly, it then pumps all of the individual Resources that are applicable to that Policy, and exports everything into a nice, clean, CSV. These are the headers you get in the report:
- PolicySetDefinitionParameters
- ManagementGroupIds
- PolicyDefinitionReferenceId
- ComplianceState
- PolicyEvaluationDetails
- PolicyDefinitionGroupNames
- PolicyDefinitionVersion
- PolicySetDefinitionVersion
- PolicyAssignmentVersion
- SubscriptionName
- State
I hope this helps. Architecting secure cloud environments can be difficult, but thankfully we can automate things to make our lives a bit easier.
One thought on “Exporting Azure Policy Assignment Resource Compliance Across the Tenant to CSV”
Comments are closed.