🕵️ Azure Forgotten Resource Detective
A comprehensive PowerShell script designed to identify and analyze Azure resources that may be forgotten, unused, or misconfigured, potentially leading to unnecessary costs.
Overview
The Azure Forgotten Resource Detective is a comprehensive PowerShell script designed to identify and analyze Azure resources that may be forgotten, unused, or misconfigured, potentially leading to unnecessary costs. This tool is part of the "FinOps for Everyone" series and helps organizations optimize their Azure spending by detecting orphaned resources and suspicious patterns.
Features
Resource Detection Capabilities
Orphaned Disks
Unattached managed disks consuming storage costs
Orphaned Network Interfaces
NICs not attached to any virtual machine
Unattached Public IP Addresses
Public IPs not associated with any resource
Empty Network Security Groups
NSGs not protecting any resources
Suspicious Load Balancers
Load balancers with no backend pools
Pattern-Based Detection
Resources with suspicious naming patterns or configurations
Cost Analysis
- Estimates monthly costs for identified resources
- Calculates potential savings from cleanup activities
- Provides cost impact assessments (High/Medium/Low)
Reporting
- HTML Report: Rich, interactive report with visual styling and actionable insights
- CSV Export: Structured data export for further analysis
- Console Summary: Real-time progress and summary information
Prerequisites
System Requirements
- PowerShell: Version 5.1 or later
- Azure CLI: Latest version installed and configured
- Azure Authentication: User must be logged in with
az login
Required Permissions
- Reader: Access to subscription and resource groups
- Cost Management Reader: For cost analysis (optional but recommended)
Azure CLI Setup
# Install Azure CLI (if not already installed)
# Download from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
# Login to Azure
az login
# Verify access to subscription
az account show
Usage
Basic Syntax
.orgotten-resource-detective.ps1 -SubscriptionId "<subscription-id>"
Parameters
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
SubscriptionId | String | ✅ Yes | - | Azure subscription ID to analyze |
DaysThreshold | Integer | ❌ No | 30 | Age threshold for resource analysis (days) |
OutputPath | String | ❌ No | forgotten-resources-report.html | Path for HTML report output |
CsvOutputPath | String | ❌ No | forgotten-resources-report.csv | Path for CSV export |
Example Usage
Basic Analysis
# Analyze subscription with default settings
.orgotten-resource-detective.ps1 -SubscriptionId "12345678-1234-1234-1234-123456789012"
Custom Configuration
# Custom thresholds and output paths
.orgotten-resource-detective.ps1 \
-SubscriptionId "12345678-1234-1234-1234-123456789012" \
-DaysThreshold 60 \
-OutputPath "C:\Reports\azure-analysis.html" \
-CsvOutputPath "C:\Reports\azure-analysis.csv"
Enterprise Analysis
# Analyze multiple subscriptions
$subscriptions = @(
"12345678-1234-1234-1234-123456789012",
"87654321-4321-4321-4321-210987654321"
)
foreach ($sub in $subscriptions) {
.\forgotten-resource-detective.ps1 \
-SubscriptionId $sub \
-OutputPath "report-$sub.html" \
-CsvOutputPath "report-$sub.csv"
}
Detection Patterns
Orphaned Resources
The script identifies truly orphaned resources that incur costs without providing value:
Orphaned Disks
Criteria: diskState == "Unattached"
AND managedBy == null
Cost Impact: High (direct storage costs)
Estimated Savings: Based on disk size and tier
Orphaned NICs
Criteria: Not attached to VM or private endpoint
Exclusions: Managed service NICs (AKS, private endpoints)
Cost Impact: Low (~$3-5/month per NIC)
Unattached Public IPs
Criteria: ipConfiguration == null
Cost Impact: Medium ($2.92-3.65/month depending on SKU)
Suspicious Patterns
Pattern | Risk Level | Description | Detection Logic |
---|---|---|---|
No Tags | High | Resources without proper tagging | tags == null OR tags.Count == 0 |
Test/Temp Names | High | Temporary-sounding resource names | Name contains: test, temp, demo, poc, backup, old, delete, tmp |
Premium Storage (Test/Dev) | High | Expensive storage for non-production | Storage account with premium SKU and test-like name |
Old Generation VMs | Medium | Outdated VM sizes | VM size matches: Basic_*, Standard_A[0-9], Standard_D[0-9]v1 |
Test Storage Accounts | Medium | Storage accounts with test-like names | Name contains: test, temp, backup, dev |
Smart Exclusions
The script intelligently excludes managed resources to reduce false positives:
- AKS Managed Resources: Resource groups starting with
MC_
- Private Endpoint NICs: NICs with private endpoint associations
- Service-Managed NICs: NICs with specific naming patterns or management tags
Cost Estimation
Disk Cost Calculation
# Cost per GB per month (USD)
Standard_LRS: $0.05/GB
Premium_LRS: $0.135/GB
StandardSSD_LRS: $0.075/GB
Premium_ZRS: $0.169/GB
StandardSSD_ZRS: $0.094/GB
Public IP Cost Calculation
# Monthly costs (USD)
Basic SKU: $2.92/month
Standard SKU: $3.65/month
Load Balancer Cost Calculation
# Monthly costs (USD)
Basic SKU: $18.25/month
Standard SKU: $18.25/month
Report Output
HTML Report Structure
Executive Summary
- Total suspicious resources found
- Critical issues breakdown
- Risk distribution analysis
- Potential monthly savings calculation
Detailed Findings Table
- Resource information and risk assessment
- Cost impact and estimated savings
- Additional technical details
- Tagging information
Action Priority Guide
- Week 1: Immediate actions (delete orphaned resources)
- Week 2: Quick wins (review load balancers)
- Month 1: Modernization efforts (upgrade VMs)
- Ongoing: Governance improvements
Cleanup Commands
Pre-generated Azure CLI commands for resource deletion with safety warnings.
CSV Export
Structured data export containing all findings for:
- Further analysis in Excel/Power BI
- Integration with other tools
- Historical tracking and trending
Safety and Best Practices
Before Running Cleanup Commands
Always verify resources before deletion to prevent accidental removal of critical infrastructure.
Verification Process
# Always verify resources before deletion
az disk show --name "suspicious-disk" --resource-group "rg-name"
az network nic show --name "suspicious-nic" --resource-group "rg-name"
Stakeholder Consultation
- Contact application owners
- Review with infrastructure teams
- Check deployment documentation
- Verify with business stakeholders
Backup Considerations
# Create snapshots before deleting disks
az snapshot create --name "backup-snapshot" --source "disk-name" --resource-group "rg-name"
Risk Mitigation
False Positive Scenarios
Disaster Recovery Resources
May appear unused but are critical
Scheduled Workloads
Resources used infrequently
Development Environments
May appear abandoned but are still needed
Compliance Requirements
Resources maintained for regulatory purposes
Recommended Workflow
- Generate Report: Run script to identify candidates
- Business Review: Validate findings with stakeholders
- Staged Cleanup: Delete resources in phases
- Monitor Impact: Watch for any issues post-cleanup
- Document Changes: Maintain cleanup audit trail
Troubleshooting
Common Issues
Authentication Problems
# Error: Please run 'az login' to setup account
az login --use-device-code # For environments without browser access
Permission Errors
# Error: Insufficient privileges
# Solution: Ensure user has Reader role on subscription
az role assignment list --assignee "user@domain.com" --subscription "sub-id"
Large Subscription Timeouts
# For subscriptions with many resources, consider:
# 1. Running during off-peak hours
# 2. Analyzing specific resource groups
# 3. Increasing PowerShell execution timeout
$ProgressPreference = 'SilentlyContinue' # Speeds up execution
Debug Mode
# Enable verbose output for troubleshooting
$VerbosePreference = 'Continue'
.orgotten-resource-detective.ps1 -SubscriptionId "sub-id" -Verbose
Integration Options
Automation Scenarios
Scheduled Reports
# Windows Task Scheduler or Azure Automation
# Run weekly/monthly for continuous monitoring
schtasks /create /tn "Azure Resource Detective" /tr "powershell.exe -File C:\Scripts\detective.ps1 -SubscriptionId 'sub-id'" /sc weekly
CI/CD Integration
# Azure DevOps Pipeline example
- task: PowerShell@2
displayName: 'Run Resource Detective'
inputs:
filePath: 'scripts/forgotten-resource-detective.ps1'
arguments: '-SubscriptionId $(subscriptionId)'
Email Notifications
# Add email functionality
$reportPath = "forgotten-resources-report.html"
Send-MailMessage -To "admin@company.com" -Subject "Azure Resource Report" -Body "See attached" -Attachments $reportPath
Data Export Integration
Power BI Integration
# Use CSV output for Power BI dashboards
$csvData = Import-Csv "forgotten-resources-report.csv"
# Process and upload to Power BI dataset
ServiceNow Integration
# Create tickets for resource cleanup
foreach ($resource in $highRiskResources) {
# API call to ServiceNow to create cleanup ticket
}
Performance Considerations
Script Optimization
- Parallel Processing: Consider using
ForEach-Object -Parallel
for large subscriptions - Selective Analysis: Target specific resource groups if full subscription scan is too slow
- Caching: Store intermediate results for repeated analysis
Resource Limits
- API Throttling: Azure CLI may throttle requests for large subscriptions
- Memory Usage: Large datasets may require memory optimization
- Execution Time: Full subscription analysis can take 5-30 minutes depending on size
Version History and Maintenance
Maintenance Tasks
- Monthly: Update cost estimates based on Azure pricing changes
- Quarterly: Review and update suspicious patterns
- Annually: Validate detection logic against new Azure services
Conclusion
The Azure Forgotten Resource Detective is a powerful tool for Azure cost optimization and resource governance. Regular use can help organizations:
- Reduce Costs: Identify and eliminate unnecessary expenses
- Improve Governance: Maintain clean, well-organized Azure environments
- Enhance Visibility: Better understand resource usage patterns
- Support Compliance: Maintain proper resource tagging and documentation
Remember to always verify findings and coordinate with stakeholders before making changes to production resources.
Get the Azure Forgotten Resource Detective
Ready to start optimizing your Azure costs? Download the Azure Forgotten Resource Detective script and start identifying forgotten resources today.