diff --git a/src/data/template/Microsoft.Authorization/policyExemptions.jq b/src/data/template/Microsoft.Authorization/policyExemptions.jq index ce6d0c74..1a566688 100644 --- a/src/data/template/Microsoft.Authorization/policyExemptions.jq +++ b/src/data/template/Microsoft.Authorization/policyExemptions.jq @@ -1 +1 @@ -del(.Id, .SystemDataCreatedAt, .SystemDataCreatedBy, .SystemDataCreatedByType, .SystemDataLastModifiedAt, .SystemDataLastModifiedBy, .SystemDataLastModifiedByType) \ No newline at end of file +del(.ResourceId, .resourceGroup, .subscriptionId, .properties.metadata.createdOn, .properties.metadata.updatedOn, .properties.metadata.createdBy, .properties.metadata.updatedBy, .properties.metadata.assignedBy) \ No newline at end of file diff --git a/src/data/template/Microsoft.Authorization/policyExemptions.template.jq b/src/data/template/Microsoft.Authorization/policyExemptions.template.jq deleted file mode 100644 index 3a3912c7..00000000 --- a/src/data/template/Microsoft.Authorization/policyExemptions.template.jq +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "AzOps" - } - }, - "parameters": {}, - "variables": {}, - "resources": [ - { - "type": .Type, - "name": .Name, - "apiVersion": "0000-00-00", - "properties": { - "assignmentScopeValidation": .AssignmentScopeValidation, - "description": .Description, - "displayName": .DisplayName, - "exemptionCategory": .ExemptionCategory, - "expiresOn": .ExpiresOn, - "metadata": .Metadata, - "policyAssignmentId": .PolicyAssignmentId, - "policyDefinitionReferenceIds": .PolicyDefinitionReferenceIds, - "resourceSelector": .ResourceSelector, - } - } - ], - "outputs": {} -} -| del(.. | select(. == null)) -| del(.. | select(. == "")) \ No newline at end of file diff --git a/src/internal/functions/Get-AzOpsPolicy.ps1 b/src/internal/functions/Get-AzOpsPolicy.ps1 index 15ae5ab8..82f32773 100644 --- a/src/internal/functions/Get-AzOpsPolicy.ps1 +++ b/src/internal/functions/Get-AzOpsPolicy.ps1 @@ -54,6 +54,10 @@ Write-AzOpsMessage -LogLevel Verbose -LogString 'Get-AzOpsResourceDefinition.Processing.Detail' -LogStringValues 'Policy Assignments', $ScopeObject.Scope $policyAssignments = Get-AzOpsPolicyAssignment -ScopeObject $ScopeObject -Subscription $Subscription -SubscriptionsToIncludeResourceGroups $SubscriptionsToIncludeResourceGroups -ResourceGroup $ResourceGroup $policyAssignments | ConvertTo-AzOpsState -StatePath $StatePath + # Process policy exemptions + Write-AzOpsMessage -LogLevel Verbose -LogString 'Get-AzOpsResourceDefinition.Processing.Detail' -LogStringValues 'Policy Exemptions', $ScopeObject.Scope + $policyExemptions = Get-AzOpsPolicyExemption -ScopeObject $ScopeObject -Subscription $Subscription -SubscriptionsToIncludeResourceGroups $SubscriptionsToIncludeResourceGroups -ResourceGroup $ResourceGroup + $policyExemptions | ConvertTo-AzOpsState -StatePath $StatePath } } \ No newline at end of file diff --git a/src/internal/functions/Get-AzOpsPolicyExemption.ps1 b/src/internal/functions/Get-AzOpsPolicyExemption.ps1 index c381469f..6e5a8bb5 100644 --- a/src/internal/functions/Get-AzOpsPolicyExemption.ps1 +++ b/src/internal/functions/Get-AzOpsPolicyExemption.ps1 @@ -7,6 +7,12 @@ Discover all custom policy exemptions at the provided scope (Management Groups, subscriptions or resource groups) .PARAMETER ScopeObject The scope object representing the azure entity to retrieve excemptions for. + .PARAMETER Subscription + Complete Subscription list + .PARAMETER SubscriptionsToIncludeResourceGroups + Scoped Subscription list + .PARAMETER ResourceGroup + ResourceGroup switch indicating desired scope condition .EXAMPLE > Get-AzOpsPolicyExemption -ScopeObject (New-AzOpsScope -Scope /providers/Microsoft.Management/managementGroups/contoso -StatePath $StatePath) Discover all custom policy exemptions deployed at Management Group scope @@ -17,36 +23,45 @@ param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [Object] - $ScopeObject + $ScopeObject, + [Parameter(Mandatory = $false)] + [object] + $Subscription, + [Parameter(Mandatory = $false)] + [object] + $SubscriptionsToIncludeResourceGroups, + [Parameter(Mandatory = $false)] + [bool] + $ResourceGroup ) process { if ($ScopeObject.Type -notin 'resourceGroups', 'subscriptions', 'managementGroups') { return } - - switch ($ScopeObject.Type) { - managementGroups { - Write-AzOpsMessage -LogLevel Debug -LogString 'Get-AzOpsPolicyExemption.ManagementGroup' -LogStringValues $ScopeObject.ManagementGroupDisplayName, $ScopeObject.ManagementGroup -Target $ScopeObject + if ($ScopeObject.Type -eq 'managementGroups') { + Write-AzOpsMessage -LogLevel Debug -LogString 'Get-AzOpsPolicyExemption.ManagementGroup' -LogStringValues $ScopeObject.ManagementGroupDisplayName, $ScopeObject.ManagementGroup -Target $ScopeObject + if ((-not $SubscriptionsToIncludeResourceGroups) -or (-not $ResourceGroups)) { + $query = "policyresources | where type == 'microsoft.authorization/policyexemptions' and resourceGroup == '' and subscriptionId == '' | order by ['id'] asc" + Search-AzOpsAzGraph -ManagementGroupName $ScopeObject.Name -Query $query -ErrorAction Stop } - subscriptions { + } + if ($Subscription) { + if ($SubscriptionsToIncludeResourceGroups -and $ResourceGroup) { Write-AzOpsMessage -LogLevel Debug -LogString 'Get-AzOpsPolicyExemption.Subscription' -LogStringValues $ScopeObject.SubscriptionDisplayName, $ScopeObject.Subscription -Target $ScopeObject + $query = "policyresources | where type == 'microsoft.authorization/policyexemptions' and resourceGroup != '' | order by ['id'] asc" + Search-AzOpsAzGraph -Subscription $SubscriptionsToIncludeResourceGroups -Query $query -ErrorAction Stop } - resourcegroups { + elseif ($ResourceGroup) { Write-AzOpsMessage -LogLevel Debug -LogString 'Get-AzOpsPolicyExemption.ResourceGroup' -LogStringValues $ScopeObject.ResourceGroup -Target $ScopeObject + $query = "policyresources | where type == 'microsoft.authorization/policyexemptions' and resourceGroup != '' | order by ['id'] asc" + Search-AzOpsAzGraph -Subscription $Subscription -Query $query -ErrorAction Stop } - } - try { - $parameters = @{ - Scope = $ScopeObject.Scope + else { + Write-AzOpsMessage -LogLevel Debug -LogString 'Get-AzOpsPolicyExemption.Subscription' -LogStringValues $ScopeObject.SubscriptionDisplayName, $ScopeObject.Subscription -Target $ScopeObject + $query = "policyresources | where type == 'microsoft.authorization/policyexemptions' and resourceGroup == '' | order by ['id'] asc" + Search-AzOpsAzGraph -Subscription $Subscription -Query $query -ErrorAction Stop } - # Gather policyExemption with retry and backoff support from Invoke-AzOpsScriptBlock - Invoke-AzOpsScriptBlock -ArgumentList $parameters -ScriptBlock { - Get-AzPolicyExemption @parameters -WarningAction SilentlyContinue -ErrorAction Stop | Where-Object Id -match $parameters.Scope - } -RetryCount 3 -RetryWait 5 -RetryType Exponential -ErrorAction Stop - } - catch { - Write-AzOpsMessage -LogLevel Warning -LogString 'Get-AzOpsPolicyExemption.Failed' -LogStringValues $ScopeObject.Scope } } diff --git a/src/internal/functions/Get-AzOpsResourceDefinition.ps1 b/src/internal/functions/Get-AzOpsResourceDefinition.ps1 index 59b67af4..b1f88d39 100644 --- a/src/internal/functions/Get-AzOpsResourceDefinition.ps1 +++ b/src/internal/functions/Get-AzOpsResourceDefinition.ps1 @@ -152,19 +152,13 @@ $script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot $script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider } - # Process Privileged Identity Management resources, Policies and Roles at managementGroup scope - if ((-not $using:SkipPim) -or (-not $using:SkipPolicy) -or (-not $using:SkipRole)) { + # Process Privileged Identity Management resources and Roles at managementGroup scope + if ((-not $using:SkipPim) -or (-not $using:SkipRole)) { & $azOps { $ScopeObject = New-AzOpsScope -Scope $managementgroup.id -StatePath $runspaceData.Statepath -ErrorAction Stop if (-not $using:SkipPim) { Get-AzOpsPim -ScopeObject $ScopeObject -StatePath $runspaceData.Statepath } - if (-not $using:SkipPolicy) { - $policyExemptions = Get-AzOpsPolicyExemption -ScopeObject $ScopeObject - if ($policyExemptions) { - $policyExemptions | ConvertTo-AzOpsState -StatePath $runspaceData.Statepath - } - } if (-not $using:SkipRole) { Get-AzOpsRole -ScopeObject $ScopeObject -StatePath $runspaceData.Statepath } @@ -196,19 +190,13 @@ $script:AzOpsPartialRoot = $runspaceData.runspace_AzOpsPartialRoot $script:AzOpsResourceProvider = $runspaceData.runspace_AzOpsResourceProvider } - # Process Privileged Identity Management resources, Policies, Locks and Roles at subscription scope - if ((-not $using:SkipPim) -or (-not $using:SkipPolicy) -or (-not $using:SkipLock) -or (-not $using:SkipRole)) { + # Process Privileged Identity Management resources, Locks and Roles at subscription scope + if ((-not $using:SkipPim) -or (-not $using:SkipLock) -or (-not $using:SkipRole)) { & $azOps { $scopeObject = New-AzOpsScope -Scope ($subscription.Type + '/' + $subscription.Id) -StatePath $runspaceData.Statepath -ErrorAction Stop if (-not $using:SkipPim) { Get-AzOpsPim -ScopeObject $scopeObject -StatePath $runspaceData.Statepath } - if (-not $using:SkipPolicy) { - $policyExemptions = Get-AzOpsPolicyExemption -ScopeObject $scopeObject - if ($policyExemptions) { - $policyExemptions | ConvertTo-AzOpsState -StatePath $runspaceData.Statepath - } - } if (-not $using:SkipLock) { Get-AzOpsResourceLock -ScopeObject $scopeObject -StatePath $runspaceData.Statepath } @@ -264,8 +252,8 @@ & $azOps { ConvertTo-AzOpsState -Resource $resourceGroup -StatePath $runspaceData.Statepath } - # Process Privileged Identity Management resources, Policies, Locks and Roles at resource group scope - if ((-not $using:SkipPim) -or (-not $using:SkipPolicy) -or (-not $using:SkipRole) -or (-not $using:SkipLock)) { + # Process Privileged Identity Management resources, Locks and Roles at resource group scope + if ((-not $using:SkipPim) -or (-not $using:SkipRole) -or (-not $using:SkipLock)) { & $azOps { $rgScopeObject = New-AzOpsScope -Scope $resourceGroup.id -StatePath $runspaceData.Statepath -ErrorAction Stop if (-not $using:SkipLock) { @@ -274,12 +262,6 @@ if (-not $using:SkipPim) { Get-AzOpsPim -ScopeObject $rgScopeObject -StatePath $runspaceData.Statepath } - if (-not $using:SkipPolicy) { - $policyExemptions = Get-AzOpsPolicyExemption -ScopeObject $rgScopeObject - if ($policyExemptions) { - $policyExemptions | ConvertTo-AzOpsState -StatePath $runspaceData.Statepath - } - } if (-not $using:SkipRole) { Get-AzOpsRole -ScopeObject $rgScopeObject -StatePath $runspaceData.Statepath }