Private/Cache/Get-CAPolicy.ps1
function Get-CAPolicy { <# .SYNOPSIS Retrieves Conditional Access policies from Microsoft Graph. .DESCRIPTION Retrieves Conditional Access policies from Microsoft Graph, with optional filtering by policy IDs. Uses query parameter optimization, batch processing, and centralized caching for improved performance. .PARAMETER PolicyIds The IDs of specific policies to retrieve. If not specified, all policies are retrieved. .PARAMETER IncludeReportOnly Whether to include policies in report-only mode in the results. .PARAMETER UseBatchProcessing Whether to use batch processing for retrieving multiple policies. This is more efficient when retrieving multiple specific policies. .PARAMETER ForceRefresh Forces a refresh of the policy cache. .EXAMPLE Get-CAPolicy .EXAMPLE Get-CAPolicy -PolicyIds "policy1", "policy2" -IncludeReportOnly -UseBatchProcessing #> [CmdletBinding()] param ( [Parameter()] [string[]]$PolicyIds, [Parameter()] [switch]$IncludeReportOnly, [Parameter()] [switch]$UseBatchProcessing, [Parameter()] [switch]$ForceRefresh ) try { # Select fields to optimize data retrieval $select = "id,displayName,state,conditions,grantControls,sessionControls" # If force refresh is set, clear the policy cache if ($ForceRefresh) { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Forcing policy cache refresh" -Level "Info" Get-CacheManager -Operation Clear -CacheType Policies } # Check if we need to get all policies if (-not $PolicyIds) { # Try to get cached "all policies" collection $allPolicies = Get-CacheManager -Operation Get -CacheType Policies -Key "AllPolicies" if (-not $allPolicies) { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Retrieving all policies from Microsoft Graph" -Level "Info" # Retrieve all policies with optimized query $allPolicies = Get-MgIdentityConditionalAccessPolicy -Select $select # Cache the policies Get-CacheManager -Operation Set -CacheType Policies -Key "AllPolicies" -Value $allPolicies # Also cache individual policies for direct lookups foreach ($policy in $allPolicies) { Get-CacheManager -Operation Set -CacheType Policies -Key $policy.Id -Value $policy } } # Filter by state if IncludeReportOnly is not specified if (-not $IncludeReportOnly) { return $allPolicies | Where-Object { $_.State -ne "enabledForReportingButNotEnforced" } } else { return $allPolicies } } # If we're looking for specific policies $filteredPolicies = @() $uncachedPolicyIds = @() # Check cache for each requested policy foreach ($policyId in $PolicyIds) { $policy = Get-CacheManager -Operation Get -CacheType Policies -Key $policyId if ($policy) { $filteredPolicies += $policy } else { $uncachedPolicyIds += $policyId } } # If there are uncached policies, retrieve them if ($uncachedPolicyIds.Count -gt 0) { if ($UseBatchProcessing -and $uncachedPolicyIds.Count -gt 1) { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Using batch processing for retrieving $($uncachedPolicyIds.Count) policies" -Level "Info" # Create batch requests $batchRequests = @() for ($i = 0; $i -lt $uncachedPolicyIds.Count; $i++) { # Construct URL without string concatenation $url = "/identity/conditionalAccess/policies/$($uncachedPolicyIds[$i])?`$select=$select" $batchRequests += @{ Id = "request-$i" Method = "GET" Url = $url } } # Execute batch request $batchResponses = Invoke-GraphBatchRequest -Requests $batchRequests # Process responses and update cache for ($i = 0; $i -lt $batchResponses.Count; $i++) { $response = $batchResponses[$i] if ($response.status -eq 200) { $policy = $response.body $filteredPolicies += $policy # Cache the policy Get-CacheManager -Operation Set -CacheType Policies -Key $policy.id -Value $policy } else { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Failed to retrieve policy: $($response.error.message)" -Level "Warning" } } } else { # Get policies individually foreach ($policyId in $uncachedPolicyIds) { try { $policy = Get-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policyId -Select $select $filteredPolicies += $policy # Cache the policy Get-CacheManager -Operation Set -CacheType Policies -Key $policy.Id -Value $policy } catch { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Failed to retrieve policy {$policyId}: $_" -Level "Warning" } } } } # Filter by state if IncludeReportOnly is not specified if (-not $IncludeReportOnly) { return $filteredPolicies | Where-Object { $_.State -ne "enabledForReportingButNotEnforced" } } else { return $filteredPolicies } } catch { Write-DiagnosticOutput -Source "Get-CAPolicy" -Message "Failed to retrieve Conditional Access policies: $_" -Level "Error" throw $_ } } |