<# .SYNOPSIS Exports Azure Front Door route configuration and origin mappings to a CSV file. .DESCRIPTION This script retrieves and documents the complete routing configuration for an Azure Front Door (Standard/Premium) CDN profile. It extracts detailed information about endpoints, routes, route patterns, origin groups, and individual origins, providing a comprehensive view of traffic routing and backend configurations. The script is designed for: - Front Door configuration documentation and auditing - Traffic routing analysis and optimization - Origin backend inventory and health monitoring - Troubleshooting routing issues and misconfigurations - Migration planning and configuration validation - Compliance documentation for CDN configurations Key features: - Complete route topology mapping from endpoints to backends - Pattern matching rules documentation - Origin health and enabled state tracking - Route enablement status monitoring - Structured CSV export for analysis and reporting The exported data includes full URL construction for both front-end endpoints and backend origins, making it easy to understand the complete request flow through the Front Door configuration. .PARAMETER SubscriptionId The Azure subscription ID containing the Front Door profile. This parameter is optional - if not provided, the script will use the current subscription context. Must be a valid GUID format. Example: "4820b5d8-cc1d-49bd-93e5-0c7a656371b7" .PARAMETER ResourceGroupName The name of the resource group containing the Front Door profile. This parameter is mandatory and is case-sensitive. Example: "my-effectory-global" .PARAMETER FrontDoorName The name of the Azure Front Door (Standard/Premium) profile to analyze. This parameter is mandatory and is case-sensitive. Must be a valid Front Door profile name (not the legacy Front Door Classic). Example: "my-effectory-frontDoor" .EXAMPLE .\FrontDoorRoutes.ps1 -SubscriptionId "4820b5d8-cc1d-49bd-93e5-0c7a656371b7" -ResourceGroupName "my-effectory-global" -FrontDoorName "my-effectory-frontDoor" Exports all route configurations for the specified Front Door profile with explicit subscription targeting. .EXAMPLE .\FrontDoorRoutes.ps1 -ResourceGroupName "production-rg" -FrontDoorName "prod-frontdoor" Exports route configurations using the current subscription context. .EXAMPLE # Analyze multiple Front Door profiles $frontDoors = @("frontdoor1", "frontdoor2", "frontdoor3") foreach ($fd in $frontDoors) { .\FrontDoorRoutes.ps1 -ResourceGroupName "global-rg" -FrontDoorName $fd } Batch processes multiple Front Door profiles for comprehensive documentation. .EXAMPLE # Export and immediately analyze results .\FrontDoorRoutes.ps1 -ResourceGroupName "my-rg" -FrontDoorName "my-frontdoor" $results = Import-Csv ".\$(Get-Date -Format 'yyyy-MM-dd HHmm') Front Door Routes (my-frontdoor).csv" $results | Where-Object RouteEnabled -eq "Disabled" | Format-Table Exports configuration and immediately identifies disabled routes for analysis. .NOTES Author: Cloud Engineering Team Version: 1.0 Prerequisites: - Azure PowerShell module (Az) must be installed - Az.Cdn module specifically required for Front Door operations - User must be authenticated to Azure (Connect-AzAccount) - User must have at least 'Reader' permissions on the Front Door profile Required Permissions: - Reader access to the subscription and resource group - CDN Profile Reader or Contributor permissions on the Front Door profile - Access to Front Door endpoints, routes, and origin groups Front Door Compatibility: - Supports Azure Front Door Standard and Premium profiles - Does NOT support legacy Azure Front Door Classic (different API) - Requires Front Door profile to be in Standard or Premium tier Output File: - Format: "YYYY-MM-DD HHMM Front Door Routes ({FrontDoorName}).csv" - Location: Current directory - Content: Complete route topology with origins and patterns CSV Structure: - FrontDoorName: Front Door profile name - EndpointName: Front Door endpoint name - RouteName: Individual route configuration name - RoutePatterns: URL patterns matched by this route (semicolon-separated) - RouteUrl: Complete front-end URL for the endpoint - OriginGroupName: Backend origin group name - OriginName: Individual origin/backend name - OriginUrl: Backend origin hostname/URL - OriginEnabled: Origin availability status - RouteEnabled: Route activation status Performance Considerations: - Processing time depends on the number of endpoints and routes - Large Front Door configurations may require extended execution time - Network latency affects configuration retrieval speed Troubleshooting Notes: - Ensure Front Door is Standard/Premium (not Classic) - Verify resource group and Front Door names are correct - Check that all required Az modules are installed and updated - Confirm appropriate permissions on the Front Door resource .LINK https://docs.microsoft.com/en-us/azure/frontdoor/ https://docs.microsoft.com/en-us/powershell/module/az.cdn/ #> param( [Parameter(Mandatory = $false, HelpMessage = "Azure subscription ID (optional - uses current context if not specified)")] [ValidateScript({ if ([string]::IsNullOrEmpty($_) -or ($_ -match '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$')) { $true } else { throw "Subscription ID must be a valid GUID format" } })] [string]$SubscriptionId, [Parameter(Mandatory = $true, HelpMessage = "Resource group name containing the Front Door profile")] [ValidateNotNullOrEmpty()] [ValidateLength(1, 90)] [string]$ResourceGroupName, [Parameter(Mandatory = $true, HelpMessage = "Front Door profile name (Standard/Premium)")] [ValidateNotNullOrEmpty()] [ValidateLength(1, 260)] [string]$FrontDoorName ) # Display script header and configuration Write-Host "======================================================================================================================================================================" Write-Host "Azure Front Door Route Configuration Export" Write-Host "======================================================================================================================================================================" Write-Host "Front Door Profile: $FrontDoorName" Write-Host "Resource Group: $ResourceGroupName" if ($SubscriptionId) { Write-Host "Target Subscription: $SubscriptionId" } else { Write-Host "Using current subscription context" } Write-Host "Script execution started: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Write-Host "======================================================================================================================================================================" Write-Host "" # Generate timestamped filename for export [string] $date = Get-Date -Format "yyyy-MM-dd HHmm" $fileName = ".\$date Front Door Routes ($FrontDoorName).csv" Write-Host "Export file: $fileName" Write-Host "" # Ensure Azure authentication Write-Host "Verifying Azure authentication..." if (-not (Get-AzContext)) { Write-Host "No Azure context found. Initiating authentication..." try { Connect-AzAccount -ErrorAction Stop Write-Host "✓ Successfully authenticated to Azure" } catch { Write-Error "Failed to authenticate to Azure. Please run Connect-AzAccount manually." throw $_ } } else { Write-Host "✓ Azure authentication verified" } # Set target subscription if provided if ($SubscriptionId) { Write-Host "Setting subscription context..." try { $context = Select-AzSubscription -SubscriptionId $SubscriptionId -ErrorAction Stop Write-Host "✓ Successfully connected to subscription: $($context.Subscription.Name)" -ForegroundColor Green } catch { Write-Error "Failed to select subscription: $SubscriptionId" Write-Error "Please verify the subscription ID and ensure you have access" throw $_ } } else { $currentContext = Get-AzContext Write-Host "✓ Using current subscription: $($currentContext.Subscription.Name)" -ForegroundColor Green } Write-Host "" Write-Host "======================================================================================================================================================================" Write-Host "Retrieving Front Door Configuration" Write-Host "======================================================================================================================================================================" try { # Get Front Door profile and validate existence Write-Host "Accessing Front Door profile '$FrontDoorName'..." $frontDoor = Get-AzFrontDoorCdnProfile -ResourceGroupName $ResourceGroupName -Name $FrontDoorName -ErrorAction Stop if (-not $frontDoor) { Write-Error "Front Door profile '$FrontDoorName' not found in resource group '$ResourceGroupName'" Write-Error "Please verify the Front Door name and resource group are correct" return } Write-Host "✓ Successfully accessed Front Door profile: $($frontDoor.Name)" Write-Host " Profile Type: $($frontDoor.Sku.Name)" Write-Host " Profile State: $($frontDoor.FrontDoorId)" Write-Host "" # Get all endpoints for the Front Door profile Write-Host "Discovering Front Door endpoints..." $endpoints = Get-AzFrontDoorCdnEndpoint -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -ErrorAction Stop if (-not $endpoints -or $endpoints.Count -eq 0) { Write-Warning "No endpoints found for Front Door profile '$FrontDoorName'" Write-Host "This Front Door profile may not have any configured endpoints." return } Write-Host "✓ Found $($endpoints.Count) endpoint(s):" foreach ($endpoint in $endpoints) { Write-Host " - $($endpoint.Name) (https://$($endpoint.HostName))" } Write-Host "" # Initialize collection for route data and processing counters $routeData = @() $totalRoutes = 0 $totalOrigins = 0 $enabledRoutes = 0 $disabledRoutes = 0 $enabledOrigins = 0 $disabledOrigins = 0 Write-Host "Processing endpoints and route configurations..." Write-Host "" # Process each endpoint to extract route and origin information foreach ($endpoint in $endpoints) { Write-Host "Processing endpoint: $($endpoint.Name)" Write-Host " Endpoint URL: https://$($endpoint.HostName)" try { # Get all routes configured for this endpoint $routes = Get-AzFrontDoorCdnRoute -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -EndpointName $endpoint.Name -ErrorAction Stop if (-not $routes -or $routes.Count -eq 0) { Write-Host " ⚠ No routes found for this endpoint" -ForegroundColor Yellow continue } Write-Host " ✓ Found $($routes.Count) route(s) for endpoint" # Process each route in the endpoint foreach ($route in $routes) { Write-Host " Processing route: $($route.Name)" Write-Host " Patterns: $($route.PatternsToMatch -join ', ')" Write-Host " Status: $($route.EnabledState)" # Track route statistics $totalRoutes++ if ($route.EnabledState -eq "Enabled") { $enabledRoutes++ } else { $disabledRoutes++ } try { # Extract origin group information from route $originGroupId = $route.OriginGroupId $originGroupName = ($originGroupId -split '/')[-1] Write-Host " Origin Group: $originGroupName" # Get all origins in the origin group $origins = Get-AzFrontDoorCdnOrigin -ResourceGroupName $ResourceGroupName -ProfileName $FrontDoorName -OriginGroupName $originGroupName -ErrorAction Stop if (-not $origins -or $origins.Count -eq 0) { Write-Host " ⚠ No origins found in origin group '$originGroupName'" -ForegroundColor Yellow # Create entry even if no origins found $routeData += [PSCustomObject]@{ FrontDoorName = $FrontDoorName EndpointName = $endpoint.Name RouteName = $route.Name RoutePatterns = ($route.PatternsToMatch -join '; ') RouteUrl = "https://$($endpoint.HostName)" OriginGroupName = $originGroupName OriginName = "No origins found" OriginUrl = "N/A" OriginEnabled = "N/A" RouteEnabled = $route.EnabledState } continue } Write-Host " ✓ Found $($origins.Count) origin(s) in group" # Process each origin in the origin group foreach ($origin in $origins) { Write-Host " Origin: $($origin.Name) -> $($origin.HostName) ($($origin.EnabledState))" # Track origin statistics $totalOrigins++ if ($origin.EnabledState -eq "Enabled") { $enabledOrigins++ } else { $disabledOrigins++ } # Create structured data entry for CSV export $routeData += [PSCustomObject]@{ FrontDoorName = $FrontDoorName EndpointName = $endpoint.Name RouteName = $route.Name RoutePatterns = ($route.PatternsToMatch -join '; ') RouteUrl = "https://$($endpoint.HostName)" OriginGroupName = $originGroupName OriginName = $origin.Name OriginUrl = $origin.HostName OriginEnabled = $origin.EnabledState RouteEnabled = $route.EnabledState } } } catch { Write-Host " ❌ Error processing origin group: $($_.Exception.Message)" -ForegroundColor Red # Create error entry for troubleshooting $routeData += [PSCustomObject]@{ FrontDoorName = $FrontDoorName EndpointName = $endpoint.Name RouteName = $route.Name RoutePatterns = ($route.PatternsToMatch -join '; ') RouteUrl = "https://$($endpoint.HostName)" OriginGroupName = "Error retrieving" OriginName = "Error" OriginUrl = $_.Exception.Message OriginEnabled = "Error" RouteEnabled = $route.EnabledState } } } } catch { Write-Host " ❌ Error processing routes for endpoint '$($endpoint.Name)': $($_.Exception.Message)" -ForegroundColor Red } Write-Host "" } Write-Host "======================================================================================================================================================================" Write-Host "Exporting Results and Analysis" Write-Host "======================================================================================================================================================================" # Export route configuration to CSV file Write-Host "Exporting Front Door route configuration to CSV..." try { $routeData | Export-Csv -Path $fileName -NoTypeInformation -Force Write-Host "✓ Successfully exported $($routeData.Count) route entries to: $fileName" -ForegroundColor Green } catch { Write-Error "Failed to export route data to CSV: $($_.Exception.Message)" throw $_ } # Display configuration summary table Write-Host "" Write-Host "Front Door Route Configuration Summary:" Write-Host "======================================================================================================================================================================" $routeData | Format-Table -Property FrontDoorName, EndpointName, RouteName, RoutePatterns, OriginGroupName, OriginName, RouteEnabled, OriginEnabled -AutoSize # Generate detailed analysis and statistics Write-Host "" Write-Host "======================================================================================================================================================================" Write-Host "Configuration Analysis Summary" Write-Host "======================================================================================================================================================================" Write-Host "Export completed: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" Write-Host "" Write-Host "Front Door Statistics:" Write-Host " Profile Name: $FrontDoorName" Write-Host " Profile Type: $($frontDoor.Sku.Name)" Write-Host " Total Endpoints: $($endpoints.Count)" Write-Host " Total Routes: $totalRoutes" Write-Host " Total Origins: $totalOrigins" Write-Host "" # Analyze route and origin health status Write-Host "Route Status Analysis:" Write-Host " ✓ Enabled Routes: $enabledRoutes" Write-Host " ❌ Disabled Routes: $disabledRoutes" Write-Host "" Write-Host "Origin Status Analysis:" Write-Host " ✓ Enabled Origins: $enabledOrigins" Write-Host " ❌ Disabled Origins: $disabledOrigins" Write-Host "" # Identify potential issues $issuesFound = @() if ($disabledRoutes -gt 0) { $issuesFound += "Some routes are disabled" } if ($disabledOrigins -gt 0) { $issuesFound += "Some origins are disabled" } $errorEntries = $routeData | Where-Object { $_.OriginName -eq "Error" } if ($errorEntries.Count -gt 0) { $issuesFound += "Configuration retrieval errors detected" } if ($issuesFound.Count -gt 0) { Write-Host "⚠ ATTENTION REQUIRED:" foreach ($issue in $issuesFound) { Write-Host " - $issue" -ForegroundColor Yellow } Write-Host " Review the CSV file for detailed information on affected routes/origins" } else { Write-Host "✓ All routes and origins are enabled and accessible" } Write-Host "" Write-Host "Output File Information:" Write-Host " File Path: $fileName" Write-Host " File Size: $([Math]::Round((Get-Item $fileName).Length / 1KB, 2)) KB" Write-Host " Records Exported: $($routeData.Count)" Write-Host "" Write-Host "Recommendations:" Write-Host " - Review disabled routes and origins for intentional configuration" Write-Host " - Validate routing patterns match expected traffic flow" Write-Host " - Monitor origin health and performance regularly" Write-Host " - Document configuration changes for audit trails" Write-Host "======================================================================================================================================================================" } catch { Write-Host "" Write-Host "======================================================================================================================================================================" Write-Host "❌ ERROR OCCURRED DURING PROCESSING" Write-Host "======================================================================================================================================================================" Write-Error "Error retrieving Front Door route configuration: $($_.Exception.Message)" Write-Host "" Write-Host "Troubleshooting Steps:" Write-Host " 1. Verify Front Door profile name and resource group are correct" Write-Host " 2. ensure the Front Door is Standard or Premium (not Classic)" Write-Host " 3. Check that you have appropriate permissions on the Front Door resource" Write-Host " 4. Confirm the Az.Cdn PowerShell module is installed and up to date" Write-Host " 5. Verify network connectivity to Azure services" Write-Host "======================================================================================================================================================================" throw $_ }