mirror of
https://dev.azure.com/effectory/Survey%20Software/_git/Cloud%20Engineering
synced 2026-02-27 10:45:02 +01:00
288 lines
14 KiB
PowerShell
288 lines
14 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Exports detailed information about Azure Application Insights resources across all enabled subscriptions.
|
|
|
|
.DESCRIPTION
|
|
This script analyzes all Application Insights resources across enabled Azure subscriptions and
|
|
collects comprehensive information including:
|
|
- Basic resource metadata (ID, name, resource group, subscription)
|
|
- Log Analytics workspace associations
|
|
- Resource tags for governance and organization
|
|
|
|
The script is particularly useful for:
|
|
- Application Insights inventory and governance
|
|
- Monitoring workspace associations for centralized logging
|
|
- Tag compliance auditing
|
|
- Cost management and resource organization
|
|
|
|
.PARAMETER SubscriptionFilter
|
|
Optional array of subscription IDs to analyze. If not specified, all enabled subscriptions are processed.
|
|
|
|
.PARAMETER OutputPath
|
|
Custom path for the output CSV file. If not specified, creates a timestamped file in the current directory.
|
|
|
|
.EXAMPLE
|
|
.\AppInsightsWorkspace.ps1
|
|
|
|
Analyzes all Application Insights resources across all enabled subscriptions.
|
|
|
|
.EXAMPLE
|
|
.\AppInsightsWorkspace.ps1 -SubscriptionFilter @("12345678-1234-1234-1234-123456789012", "87654321-4321-4321-4321-210987654321")
|
|
|
|
Analyzes Application Insights resources in specific subscriptions only.
|
|
|
|
.EXAMPLE
|
|
.\AppInsightsWorkspace.ps1 -OutputPath "C:\Reports\appinsights-analysis.csv"
|
|
|
|
Analyzes all Application Insights resources and saves to a custom location.
|
|
|
|
.OUTPUTS
|
|
Creates a CSV file with the following columns:
|
|
- SubscriptionId: Azure subscription unique identifier
|
|
- SubscriptionName: Azure subscription display name
|
|
- Id: Application Insights resource ID
|
|
- ResourceGroupName: Resource group containing the Application Insights resource
|
|
- Name: Application Insights resource name
|
|
- WorkspaceResourceId: Associated Log Analytics workspace resource ID (if any)
|
|
- Tag_Team: Value of 'team' tag
|
|
- Tag_Product: Value of 'product' tag
|
|
- Tag_Environment: Value of 'environment' tag
|
|
- Tag_Data: Value of 'data' tag
|
|
- Tag_CreatedOnDate: Value of 'CreatedOnDate' tag
|
|
- Tag_Deployment: Value of 'drp_deployment' tag
|
|
|
|
Also displays a formatted table of results in the console.
|
|
|
|
.NOTES
|
|
Author: Cloud Engineering Team
|
|
Created: 2025
|
|
Requires: PowerShell 5.1 or later, Az PowerShell module
|
|
Dependencies: Az.ApplicationInsights, Az.Accounts, Az.Resources modules
|
|
|
|
Prerequisites:
|
|
- Install Az PowerShell module: Install-Module -Name Az
|
|
- Connect to Azure: Connect-AzAccount
|
|
- Appropriate permissions to read Application Insights resources across target subscriptions
|
|
|
|
Performance Considerations:
|
|
- Processing time depends on the number of subscriptions and Application Insights resources
|
|
- The script switches contexts between subscriptions, which may take time with many subscriptions
|
|
- Large numbers of resources may result in longer execution times
|
|
|
|
Tag Analysis:
|
|
The script looks for specific tags commonly used for governance:
|
|
- team: Identifies the responsible team
|
|
- product: Associates the resource with a product or service
|
|
- environment: Indicates the environment (dev, test, prod, etc.)
|
|
- data: Data classification or sensitivity level
|
|
- CreatedOnDate: Resource creation timestamp
|
|
- drp_deployment: Deployment-related information
|
|
|
|
Workspace Association:
|
|
- Modern Application Insights resources should be associated with Log Analytics workspaces
|
|
- Resources without workspace associations may be using legacy standalone mode
|
|
- Workspace associations enable advanced querying and cross-resource analytics
|
|
|
|
.LINK
|
|
https://docs.microsoft.com/en-us/powershell/module/az.applicationinsights/
|
|
https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview
|
|
#>
|
|
|
|
param(
|
|
[Parameter(Mandatory = $false, HelpMessage = "Array of subscription IDs to analyze (analyzes all enabled subscriptions if not specified)")]
|
|
[string[]]$SubscriptionFilter = @(),
|
|
|
|
[Parameter(Mandatory = $false, HelpMessage = "Custom path for the output CSV file")]
|
|
[string]$OutputPath = ""
|
|
)
|
|
|
|
# Check Azure PowerShell authentication
|
|
Write-Host "Verifying Azure PowerShell authentication..." -ForegroundColor Yellow
|
|
try {
|
|
$azContext = Get-AzContext
|
|
if (-not $azContext) {
|
|
Write-Host "Not authenticated to Azure. Attempting to connect..." -ForegroundColor Yellow
|
|
Connect-AzAccount
|
|
$azContext = Get-AzContext
|
|
}
|
|
Write-Host "Azure authentication verified - Account: $($azContext.Account.Id)" -ForegroundColor Green
|
|
}
|
|
catch {
|
|
Write-Host "ERROR: Unable to authenticate to Azure. Please run 'Connect-AzAccount' manually." -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Generate filename if not provided
|
|
if (-not $OutputPath) {
|
|
[string] $date = Get-Date -Format "yyyy-MM-dd HHmm"
|
|
$OutputPath = ".\$date appinsights.csv"
|
|
}
|
|
|
|
# Get target subscriptions based on filter or all enabled subscriptions
|
|
Write-Host "Retrieving target subscriptions..." -ForegroundColor Yellow
|
|
if ($SubscriptionFilter.Count -gt 0) {
|
|
$subscriptions = $SubscriptionFilter | ForEach-Object {
|
|
Get-AzSubscription -SubscriptionId $_ | Where-Object State -eq "Enabled"
|
|
} | Where-Object { $_ -ne $null }
|
|
Write-Host "Analyzing $($subscriptions.Count) filtered subscriptions" -ForegroundColor Green
|
|
} else {
|
|
$subscriptions = Get-AzSubscription | Where-Object State -eq "Enabled"
|
|
Write-Host "Analyzing all $($subscriptions.Count) enabled subscriptions" -ForegroundColor Green
|
|
}
|
|
|
|
# Define a class to structure Application Insights resource information
|
|
class AppInsightsCheck {
|
|
[string] $SubscriptionId = "" # Azure subscription unique identifier
|
|
[string] $SubscriptionName = "" # Azure subscription display name
|
|
[string] $Id = "" # Application Insights resource ID
|
|
[string] $ResourceGroupName = "" # Resource group containing the resource
|
|
[string] $Name = "" # Application Insights resource name
|
|
[string] $WorkspaceResourceId = "" # Associated Log Analytics workspace resource ID
|
|
[string] $Tag_Team = "" # Team responsible for the resource
|
|
[string] $Tag_Product = "" # Product or service association
|
|
[string] $Tag_Environment = "" # Environment designation (dev, test, prod)
|
|
[string] $Tag_Data = "" # Data classification or sensitivity level
|
|
[string] $Tag_CreatedOnDate = "" # Resource creation date from tags
|
|
[string] $Tag_Deployment = "" # Deployment-related information
|
|
}
|
|
|
|
# Initialize array to store Application Insights analysis results
|
|
[AppInsightsCheck[]]$Result = @()
|
|
$totalResourcesProcessed = 0
|
|
|
|
# Display analysis banner
|
|
Write-Host "`n========================================================================================================================================================================"
|
|
Write-Host "AZURE APPLICATION INSIGHTS ANALYSIS"
|
|
Write-Host "========================================================================================================================================================================"
|
|
|
|
# Process each subscription to analyze Application Insights resources
|
|
foreach ($subscription in $subscriptions) {
|
|
Write-Host "`nAnalyzing subscription: $($subscription.Name) ($($subscription.Id))" -ForegroundColor Cyan
|
|
|
|
try {
|
|
# Switch to the current subscription context
|
|
Set-AzContext -SubscriptionId $subscription.Id -ErrorAction Stop | Out-Null
|
|
|
|
# Get all Application Insights resources in the subscription
|
|
Write-Host " Retrieving Application Insights resources..." -ForegroundColor Gray
|
|
$allAppinsights = Get-AzApplicationInsights -ErrorAction Stop
|
|
|
|
if ($allAppinsights.Count -eq 0) {
|
|
Write-Host " No Application Insights resources found" -ForegroundColor Yellow
|
|
continue
|
|
}
|
|
|
|
Write-Host " Found $($allAppinsights.Count) Application Insights resources" -ForegroundColor Green
|
|
|
|
# Process each Application Insights resource
|
|
foreach ($appinsights in $allAppinsights) {
|
|
Write-Host " Processing: $($appinsights.Name)" -ForegroundColor Gray
|
|
|
|
try {
|
|
# Create new analysis object and populate basic information
|
|
[AppInsightsCheck] $AppInsightsCheck = [AppInsightsCheck]::new()
|
|
$AppInsightsCheck.SubscriptionId = $subscription.Id
|
|
$AppInsightsCheck.SubscriptionName = $subscription.Name
|
|
$AppInsightsCheck.Id = $appinsights.Id
|
|
$AppInsightsCheck.Name = $appinsights.Name
|
|
$AppInsightsCheck.ResourceGroupName = $appinsights.ResourceGroupName
|
|
$AppInsightsCheck.WorkspaceResourceId = $appinsights.WorkspaceResourceId
|
|
|
|
# Check workspace association
|
|
if ($appinsights.WorkspaceResourceId) {
|
|
Write-Host " Workspace-based Application Insights" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " Legacy standalone Application Insights (consider migrating)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# Retrieve detailed resource information for tags
|
|
Write-Host " Retrieving resource tags..." -ForegroundColor Gray
|
|
$resource = Get-AzResource -ResourceId $appinsights.Id -ErrorAction Stop
|
|
|
|
# Extract governance tags
|
|
$AppInsightsCheck.Tag_Team = $resource.Tags.team
|
|
$AppInsightsCheck.Tag_Product = $resource.Tags.product
|
|
$AppInsightsCheck.Tag_Environment = $resource.Tags.environment
|
|
$AppInsightsCheck.Tag_Data = $resource.Tags.data
|
|
$AppInsightsCheck.Tag_CreatedOnDate = $resource.Tags.CreatedOnDate
|
|
$AppInsightsCheck.Tag_Deployment = $resource.Tags.drp_deployment
|
|
|
|
# Report on tag compliance
|
|
$tagCount = @($AppInsightsCheck.Tag_Team, $AppInsightsCheck.Tag_Product, $AppInsightsCheck.Tag_Environment) | Where-Object { $_ } | Measure-Object | Select-Object -ExpandProperty Count
|
|
if ($tagCount -eq 3) {
|
|
Write-Host " All required tags present" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " Missing required tags (team, product, environment)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# Add to results
|
|
$Result += $AppInsightsCheck
|
|
$totalResourcesProcessed++
|
|
|
|
} catch {
|
|
Write-Host " ERROR processing resource: $($_.Exception.Message)" -ForegroundColor Red
|
|
# Still add basic info even if tag retrieval fails
|
|
[AppInsightsCheck] $AppInsightsCheck = [AppInsightsCheck]::new()
|
|
$AppInsightsCheck.SubscriptionId = $subscription.Id
|
|
$AppInsightsCheck.SubscriptionName = $subscription.Name
|
|
$AppInsightsCheck.Id = $appinsights.Id
|
|
$AppInsightsCheck.Name = $appinsights.Name
|
|
$AppInsightsCheck.ResourceGroupName = $appinsights.ResourceGroupName
|
|
$AppInsightsCheck.WorkspaceResourceId = $appinsights.WorkspaceResourceId
|
|
$Result += $AppInsightsCheck
|
|
$totalResourcesProcessed++
|
|
}
|
|
}
|
|
|
|
} catch {
|
|
Write-Host " ERROR accessing subscription: $($_.Exception.Message)" -ForegroundColor Red
|
|
continue
|
|
}
|
|
}
|
|
|
|
# Export results to CSV file
|
|
Write-Host "`nExporting results to: $OutputPath" -ForegroundColor Yellow
|
|
$Result | Export-Csv -Path $OutputPath -NoTypeInformation -Force
|
|
|
|
# Calculate and display summary statistics
|
|
$totalSubscriptions = $subscriptions.Count
|
|
$workspaceBasedCount = ($Result | Where-Object { $_.WorkspaceResourceId -ne "" }).Count
|
|
$legacyCount = ($Result | Where-Object { $_.WorkspaceResourceId -eq "" }).Count
|
|
$taggedResourcesCount = ($Result | Where-Object { $_.Tag_Team -ne "" -and $_.Tag_Product -ne "" -and $_.Tag_Environment -ne "" }).Count
|
|
|
|
# Display completion summary
|
|
Write-Host "`n========================================================================================================================================================================"
|
|
Write-Host "APPLICATION INSIGHTS ANALYSIS COMPLETED SUCCESSFULLY!" -ForegroundColor Green
|
|
Write-Host "========================================================================================================================================================================"
|
|
Write-Host ""
|
|
Write-Host "SUMMARY STATISTICS:" -ForegroundColor Cyan
|
|
Write-Host "Subscriptions analyzed: $totalSubscriptions" -ForegroundColor Yellow
|
|
Write-Host "Total Application Insights resources: $totalResourcesProcessed" -ForegroundColor Yellow
|
|
Write-Host "Workspace-based resources: $workspaceBasedCount" -ForegroundColor Yellow
|
|
Write-Host "Legacy standalone resources: $legacyCount" -ForegroundColor Yellow
|
|
Write-Host "Resources with complete tags (team, product, environment): $taggedResourcesCount" -ForegroundColor Yellow
|
|
|
|
# Highlight areas needing attention
|
|
if ($legacyCount -gt 0) {
|
|
Write-Host ""
|
|
Write-Host "RECOMMENDATIONS:" -ForegroundColor Cyan
|
|
Write-Host "- $legacyCount legacy Application Insights resources should be migrated to workspace-based mode" -ForegroundColor Yellow
|
|
}
|
|
|
|
if ($taggedResourcesCount -lt $totalResourcesProcessed) {
|
|
$untaggedCount = $totalResourcesProcessed - $taggedResourcesCount
|
|
Write-Host "- $untaggedCount resources are missing required governance tags" -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Output file: $OutputPath" -ForegroundColor Yellow
|
|
|
|
# Display results table
|
|
Write-Host ""
|
|
Write-Host "DETAILED RESULTS:" -ForegroundColor Cyan
|
|
$Result | Format-Table -Property SubscriptionName, Name, ResourceGroupName, @{
|
|
Name = 'WorkspaceAssociated'
|
|
Expression = { if ($_.WorkspaceResourceId) { 'Yes' } else { 'No' } }
|
|
}, Tag_Team, Tag_Product, Tag_Environment -AutoSize
|
|
|
|
Write-Host "========================================================================================================================================================================" |