All scripts
Azure AI 691

Azure Advisor Recommendations Report

Exports every open Azure Advisor recommendation for a subscription (cost, security, reliability, performance, and operational excellence) to a CSV file, so you can review them outside the portal or filter to one category at a time.

Get-AzureAdvisorRecommendationsReport.ps1
<#
.SYNOPSIS
    Exports Azure Advisor recommendations for a subscription to a CSV file.
.DESCRIPTION
    Connects to Azure and pulls every Advisor recommendation across the Cost, Security,
    Reliability, Performance, and Operational Excellence categories for a subscription.
    Writes the results to CSV so you can review them outside the portal, sort by impact,
    or hand a plain list to someone who does not have portal access. Useful for a monthly
    health check instead of clicking through the Advisor blade one category at a time.
.AUTHOR
    Shehryar Hassan
.EXAMPLE
    .\Get-AzureAdvisorRecommendationsReport.ps1 -SubscriptionId "11111111-2222-3333-4444-555555555555" -OutputPath "C:\Reports\advisor-report.csv"

    Connects to the given subscription and writes every open Advisor recommendation to
    advisor-report.csv, including category, impact, and the affected resource.
.EXAMPLE
    .\Get-AzureAdvisorRecommendationsReport.ps1 -SubscriptionId "11111111-2222-3333-4444-555555555555" -Category Cost

    Same report, filtered to only Cost recommendations, which is the category most people
    check first after a subscription starts running for a while.
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [string]$SubscriptionId,

    [Parameter(Mandatory = $false)]
    [ValidateSet("Cost", "Security", "Reliability", "Performance", "OperationalExcellence")]
    [string]$Category,

    [Parameter(Mandatory = $false)]
    [string]$OutputPath = ".\advisor-report-$(Get-Date -Format 'yyyy-MM-dd').csv"
)

if (-not (Get-Module -ListAvailable -Name Az.Advisor)) {
    Write-Error "The Az.Advisor module is not installed. Run: Install-Module Az.Advisor -Scope CurrentUser"
    return
}

if (-not (Get-AzContext)) {
    Write-Host "No active Azure session found, connecting now." -ForegroundColor Yellow
    Connect-AzAccount | Out-Null
}

Write-Host "Setting context to subscription $SubscriptionId" -ForegroundColor Cyan
Set-AzContext -SubscriptionId $SubscriptionId | Out-Null

Write-Host "Pulling Advisor recommendations, this can take a minute on a large subscription." -ForegroundColor Cyan
$recommendations = Get-AzAdvisorRecommendation

if ($Category) {
    $recommendations = $recommendations | Where-Object { $_.Category -eq $Category }
}

if (-not $recommendations -or $recommendations.Count -eq 0) {
    Write-Host "No Advisor recommendations found for the selected criteria." -ForegroundColor Green
    return
}

$report = $recommendations | ForEach-Object {
    [PSCustomObject]@{
        Category        = $_.Category
        Impact          = $_.Impact
        Problem         = $_.ShortDescriptionProblem
        Solution        = $_.ShortDescriptionSolution
        ImpactedField   = $_.ImpactedField
        ImpactedValue   = $_.ImpactedValue
        ResourceId      = $_.Id
        LastUpdated     = $_.LastUpdated
    }
}

$report | Sort-Object Category, Impact -Descending | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8

Write-Host "Exported $($report.Count) recommendations to $OutputPath" -ForegroundColor Green

$summary = $report | Group-Object Category | Select-Object Name, Count
Write-Host "`nSummary by category:" -ForegroundColor Cyan
$summary | Format-Table -AutoSize

Read it before you run it, and test in a safe tenant first.