internal/functions/Find-AzNonCompliantResources.ps1
function Find-AzNonCompliantResources { [CmdletBinding()] param ( [switch] $RemmediationOnly, $PacEnvironment, [switch] $OnlyCheckManagedAssignments, [string[]] $PolicyDefinitionFilter, [string[]] $PolicySetDefinitionFilter, [string[]] $PolicyAssignmentFilter, [string[]] $PolicyExemptionFilter, [string[]] $PolicyEffectFilter, [switch] $ExcludeManualPolicyEffect ) Write-Information "===================================================================================================" Write-Information "Retrieve Policy Commpliance List" Write-Information "===================================================================================================" $effectFilter = "" if ($PolicyEffectFilter -and $ExcludeManualPolicyEffect) { Write-Error "Parameter PolicyEffectFilter cannot be used with parameter ExcludeManualPolicyEffect" -ErrorAction Stop } elseif ($ExcludeManualPolicyEffect -and $RemmediationOnly) { Write-Error "Parameter ExcludeManualPolicyEffect cannot be used with parameter RemmediationOnly" -ErrorAction Stop } elseif ($ExcludeManualPolicyEffect) { $effectFilter = " and properties.policyDefinitionAction <> `"manual`"" } else { if ($PolicyEffectFilter -and $PolicyEffectFilter.Count -ne 0) { $effectFilter = " and (" foreach ($filterValue in $PolicyEffectFilter) { if ($RemmediationOnly) { if ($filterValue -in @("deployifnotexists", "modify")) { $effectFilter += "properties.policyDefinitionAction == `"$filterValue`" or " } else { Write-Error "Invalid value(s) for parameter PolicyEffectFilter $($PolicyEffectFilter | ConvertTo-Json -Compress). Valid values are: deployifnotexists, modify" -ErrorAction Stop } } else { if ($filterValue -in @("audit", "deny", "append", "modify", "auditifnotexists", "deployifnotexists", "denyaction", "manual")) { $effectFilter += "properties.policyDefinitionAction == `"$filterValue`" or " } else { Write-Error "Invalid value(s) for parameter PolicyEffectFilter $($PolicyEffectFilter | ConvertTo-Json -Compress). Valid values are: audit, deny, append, modify, auditifnotexists, deployifnotexists, denyaction, manual" -ErrorAction Stop } } } $effectFilter = $effectFilter.Substring(0, $effectFilter.Length - 4) + ")" } elseif ($RemmediationOnly) { $effectFilter = " and (properties.policyDefinitionAction == `"deployifnotexists`" or properties.policyDefinitionAction == `"modify`")" } } $query = "" if ($RemmediationOnly) { $query = "policyresources | where type == `"microsoft.policyinsights/policystates`" and properties.complianceState == `"NonCompliant`"$($effectFilter)" } else { $query = "policyresources | where type == `"microsoft.policyinsights/policystates`" and properties.complianceState <> `"Compliant`"$($effectFilter)" } Write-Information "Az Graph Query: '$query'" $result = @() + (Search-AzGraphAllItems -Query $query -Scope @{ UseTenantScope = $true } -ProgressItemName "Policy compliance records") Write-Information "" $rawNonCompliantList = [System.Collections.ArrayList]::new() $deployedPolicyResources = $null $scopeTable = $null if ($result.Count -ne 0) { # Get all Policy Assignments, Policy Definitions and Policy Set Definitions $scopeTable = Get-AzScopeTree -PacEnvironment $PacEnvironment $notOnlyCheckManagedAssignments = -not $OnlyCheckManagedAssignments $deployedPolicyResources = Get-AzPolicyResources -PacEnvironment $PacEnvironment -ScopeTable $scopeTable -SkipExemptions -SkipRoleAssignments -CollectAllPolicies:$notOnlyCheckManagedAssignments $allAssignments = $deployedPolicyResources.policyassignments.all $strategy = $pacEnvironment.desiredState.strategy # Filter result if (-not $OnlyCheckManagedAssignments -and -not $PolicyDefinitionFilter -and -not $PolicySetDefinitionFilter -and -not $PolicyAssignmentFilter) { $null = $rawNonCompliantList.AddRange($result) } else { foreach ($entry in $result) { $entryProperties = $entry.properties $policyAssignmentId = $entryProperties.policyAssignmentId if ($allAssignments.ContainsKey($policyAssignmentId)) { $entryToAdd = $null $assignment = $allAssignments.$policyAssignmentId $assignmentPacOwner = $assignment.pacOwner if (-not $OnlyCheckManagedAssignments -or ($assignmentPacOwner -eq "thisPaC" -or ($assignmentPacOwner -eq "unknownOwner" -and $strategy -eq "full"))) { if ($PolicyDefinitionFilter -or $PolicySetDefinitionFilter -or $PolicyAssignmentFilter) { if ($PolicyDefinitionFilter) { foreach ($filterValue in $PolicyDefinitionFilter) { if ($entryProperties.policyDefinitionName -eq $filterValue -or $entryProperties.policyDefinitionId -eq $filterValue) { $entryToAdd = $entry break } } } if (!$entryToAdd -and $PolicySetDefinitionFilter) { foreach ($filterValue in $PolicySetDefinitionFilter) { if ($entryProperties.policySetDefinitionName -eq $filterValue -or $entryProperties.policySetDefinitionId -eq $filterValue) { $entryToAdd = $entry break } } } if (!$entryToAdd -and $PolicyAssignmentFilter) { foreach ($filterValue in $PolicyAssignmentFilter) { if ($entryProperties.policyAssignmentName -eq $filterValue -or $entryProperties.policyAssignmentId -eq $filterValue) { $entryToAdd = $entry break } } } } else { $entryToAdd = $entry } } if ($entryToAdd) { $null = $rawNonCompliantList.Add($entryToAdd) } } } } } Write-Information "Found $($rawNonCompliantList.Count) non-compliant resources" Write-Information "" return $rawNonCompliantList, $deployedPolicyResources, $scopeTable } |