Public/Permissions/Invoke-365TUNETestAll.ps1

function Invoke-365TUNETestAll {
    <#
    .SYNOPSIS
        Tests all 365TUNE permissions - Azure, Exchange Online, and Teams - in one step.

    .DESCRIPTION
        Runs all three test functions in sequence and produces a combined summary.
        Read-only - makes no changes.

        Works in both local PowerShell and Azure Cloud Shell.

    .EXAMPLE
        Invoke-365TUNETestAll

    .NOTES
        Author : Metawise Consulting LLC
        Module : 365TUNE
        Version : 2.2.7
    #>


    [CmdletBinding()]
    param()

    Write-Host "`n======================================================" -ForegroundColor Cyan
    Write-Host " 365TUNE - Full Permissions Test" -ForegroundColor Cyan
    Write-Host "======================================================`n" -ForegroundColor Cyan

    $results = @{
        Azure    = $false
        Exchange = $false
        Teams    = $false
    }

    # Azure
    Write-Host "[ TEST 1 OF 3 ] Azure Permissions" -ForegroundColor Magenta
    Write-Host "------------------------------------------------------" -ForegroundColor Magenta
    try {
        $results.Azure = Invoke-365TuneTestAzure
    } catch {
        Write-Host "`n[FAIL] Azure test error: $($_.Exception.Message)" -ForegroundColor Red
    }

    # Exchange
    Write-Host "[ TEST 2 OF 3 ] Exchange Online Permissions" -ForegroundColor Magenta
    Write-Host "------------------------------------------------------" -ForegroundColor Magenta
    try {
        $results.Exchange = Invoke-365TuneTestExchange -SkipAuth
    } catch {
        Write-Host "`n[FAIL] Exchange test error: $($_.Exception.Message)" -ForegroundColor Red
    }

    # Teams
    Write-Host "[ TEST 3 OF 3 ] Teams Permissions" -ForegroundColor Magenta
    Write-Host "------------------------------------------------------" -ForegroundColor Magenta
    try {
        $results.Teams = Invoke-365TuneTestTeams -SkipAuth
    } catch {
        Write-Host "`n[FAIL] Teams test error: $($_.Exception.Message)" -ForegroundColor Red
    }

    # Summary
    Write-Host "`n======================================================" -ForegroundColor Cyan
    Write-Host " 365TUNE - Permissions Summary" -ForegroundColor Cyan
    Write-Host "======================================================" -ForegroundColor Cyan

    $azureStatus    = if ($results.Azure)    { "[OK] " } else { "[FAIL] " }
    $exchangeStatus = if ($results.Exchange) { "[OK] " } else { "[FAIL] " }
    $teamsStatus    = if ($results.Teams)    { "[OK] " } else { "[FAIL] " }

    $azureColor    = if ($results.Azure)    { "Green" } else { "Red" }
    $exchangeColor = if ($results.Exchange) { "Green" } else { "Red" }
    $teamsColor    = if ($results.Teams)    { "Green" } else { "Red" }

    Write-Host " $azureStatus Azure : Reader at / and /providers/Microsoft.aadiam" -ForegroundColor $azureColor
    Write-Host " $exchangeStatus Exchange: View-Only Configuration role" -ForegroundColor $exchangeColor
    Write-Host " $teamsStatus Teams : Teams Reader role" -ForegroundColor $teamsColor

    $allOk = $results.Azure -and $results.Exchange -and $results.Teams
    Write-Host ""
    if ($allOk) {
        Write-Host " All permissions correctly assigned. [OK]" -ForegroundColor Green
    } else {
        $missing = @()
        if (-not $results.Azure)    { $missing += "Azure -> Run Invoke-365TuneConnectAzure" }
        if (-not $results.Exchange) { $missing += "Exchange -> Run Invoke-365TuneConnectExchange" }
        if (-not $results.Teams)    { $missing += "Teams -> Run Invoke-365TuneConnectTeams" }
        Write-Host " Missing permissions:" -ForegroundColor Red
        foreach ($m in $missing) {
            Write-Host " - $m" -ForegroundColor Yellow
        }
    }
    Write-Host "======================================================`n" -ForegroundColor Cyan
}