pwsh/dev/functions/getPolicyRemediation.ps1 (97 lines of code) (raw):
function getPolicyRemediation {
$currentTask = 'Getting NonCompliant (dine/modify)'
Write-Host $currentTask
#ref: https://learn.microsoft.com/en-us/rest/api/azureresourcegraph/resourcegraph/resources/resources
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.ResourceGraph/resources?api-version=2022-10-01"
$method = 'POST'
if ($ManagementGroupsOnly) {
$queryNonCompliant = @'
policyresources
| where type == 'microsoft.policyinsights/policystates' and properties.policyAssignmentScope startswith '/providers/Microsoft.Management/managementGroups/' and (properties.policyDefinitionAction =~ 'deployifnotexists' or properties.policyDefinitionAction =~ 'modify') and properties.complianceState =~ 'NonCompliant'
| summarize count() by assignmentScope = tostring(properties.policyAssignmentScope), assignmentName = tostring(properties.policyAssignmentName), assignmentId = tostring(properties.policyAssignmentId), definitionName = tostring(properties.policyDefinitionName), definitionId = tostring(properties.policyDefinitionId), policyDefinitionReferenceId = tostring(properties.policyDefinitionReferenceId), effect = tostring(properties.policyDefinitionAction)
| sort by count_, assignmentId, definitionId, policyDefinitionReferenceId, effect
'@
}
else {
$queryNonCompliant = @'
policyresources
| where (properties.policyDefinitionAction =~ 'deployifnotexists' or properties.policyDefinitionAction =~ 'modify') and properties.complianceState =~ 'NonCompliant'
| summarize count() by assignmentScope = tostring(properties.policyAssignmentScope), assignmentName = tostring(properties.policyAssignmentName), assignmentId = tostring(properties.policyAssignmentId), definitionName = tostring(properties.policyDefinitionName), definitionId = tostring(properties.policyDefinitionId), policyDefinitionReferenceId = tostring(properties.policyDefinitionReferenceId), effect = tostring(properties.policyDefinitionAction)
| sort by count_, assignmentId, definitionId, policyDefinitionReferenceId, effect
'@
}
$body = @"
{
"query": "$($queryNonCompliant)",
"managementGroups":[
"$($ManagementGroupId)"
],
"options": {
"`$top": 1000
}
}
"@
$getNonCompliant = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -body $body -listenOn 'Content'
$script:arrayRemediatable = [System.Collections.ArrayList]@()
Write-Host " Found $($getNonCompliant.Count) remediatable Policy definitions"
if ($getNonCompliant.Count -gt 0) {
Write-Host ' Enriching remediatable assignments with displayNames'
foreach ($nonCompliant in $getNonCompliant) {
if ($htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower())) {
if ($htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower()).assignment.properties.policyDefinitionId -like '*/providers/Microsoft.Authorization/policySetDefinitions/*') {
$policyAssignmentPolicyOrPolicySet = 'policySetDefinition'
$policySetDefinitionId = $htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower()).assignment.properties.policyDefinitionId
$policySetDefinitionDisplayName = $htCacheDefinitionsPolicySet.($policySetDefinitionId.ToLower()).DisplayName
$policySetDefinitionName = $policySetDefinitionId -replace '.*/'
$policySetDefinitionType = $htCacheDefinitionsPolicySet.($policySetDefinitionId.ToLower()).Type
}
elseif ($htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower()).assignment.properties.policyDefinitionId -like '*/providers/Microsoft.Authorization/policyDefinitions/*') {
$policyAssignmentPolicyOrPolicySet = 'policyDefinition'
$policySetDefinitionId = 'n/a'
$policySetDefinitionDisplayName = 'n/a'
$policySetDefinitionName = 'n/a'
$policySetDefinitionType = 'n/a'
}
else {
throw "unexpected .policyDefinitionId: $($htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower()).assignment.properties)"
}
switch ($nonCompliant.assignmentId) {
{ $_ -like '/subscriptions/*' } {
$policyAssignmentScopeType = 'Sub'
}
{ $_ -like '/subscriptions/*/resourcegroups/*' } {
$policyAssignmentScopeType = 'RG'
}
{ $_ -like '/providers/Microsoft.Management/managementGroups/*' } {
$policyAssignmentScopeType = 'MG'
}
default {
$policyAssignmentScopeType = 'notDetected'
}
}
$null = $script:arrayRemediatable.Add([PSCustomObject]@{
policyAssignmentScopeType = $policyAssignmentScopeType
policyAssignmentScope = $nonCompliant.assignmentScope
policyAssignmentId = $nonCompliant.assignmentId
policyAssignmentName = $nonCompliant.assignmentName
policyAssignmentDisplayName = $htCacheAssignmentsPolicy.($nonCompliant.assignmentId.toLower()).assignment.properties.displayName
policyAssignmentPolicyOrPolicySet = $policyAssignmentPolicyOrPolicySet
effect = $nonCompliant.effect
policyDefinitionId = $nonCompliant.definitionId
policyDefinitionName = $nonCompliant.definitionName
policyDefinitionDisplayName = $htCacheDefinitionsPolicy.($nonCompliant.definitionId.toLower()).Json.properties.displayName
policyDefinitionType = $htCacheDefinitionsPolicy.($nonCompliant.definitionId.toLower()).Type
policySetPolicyDefinitionReferenceId = $nonCompliant.policyDefinitionReferenceId
policySetDefinitionId = $policySetDefinitionId
policySetDefinitionName = $policySetDefinitionName
policySetDefinitionDisplayName = $policySetDefinitionDisplayName
policySetDefinitionType = $policySetDefinitionType
nonCompliantResourcesCount = $nonCompliant.count_
})
}
else {
Write-Host " skipping `$htCacheAssignmentsPolicy.($($nonCompliant.assignmentId)) potentially an assignment on an out-of-scope subscription"
}
}
}
}