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.3.4
    #>


    [CmdletBinding()]
    param()

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

    # Authenticate once - all three test functions will use -SkipAuth
    Write-Host "Authenticating..." -ForegroundColor Cyan
    $inCloudShell = ($env:ACC_CLOUD -eq "PROD") -or
                    ($env:POWERSHELL_DISTRIBUTION_CHANNEL -like "*CloudShell*") -or
                    ($env:AZUREPS_HOST_ENVIRONMENT -like "*cloud-shell*")
    if ($inCloudShell) {
        Connect-AzAccount -WarningAction SilentlyContinue -SkipContextPopulation | Out-Null
    } else {
        Disconnect-AzAccount -ErrorAction SilentlyContinue | Out-Null
        Connect-AzAccount -WarningAction SilentlyContinue | Out-Null
    }
    $ctx = Get-AzContext
    if (-not $ctx) { throw "Authentication failed." }
    Write-Host " Tenant : $($ctx.Tenant.Id)" -ForegroundColor Gray
    Write-Host " Account : $($ctx.Account.Id)" -ForegroundColor Gray
    Write-Host " [OK] Authenticated.`n" -ForegroundColor Green

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

    # Azure (SkipAuth - uses session from above; does internal elevation/de-elevation)
    Write-Host "[ TEST 1 OF 3 ] Azure Permissions" -ForegroundColor Magenta
    Write-Host "------------------------------------------------------" -ForegroundColor Magenta
    try {
        $results.Azure = Invoke-365TuneTestAzure -SkipAuth
    } 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
}