Public/Permissions/Invoke-365TuneConnect.ps1

function Invoke-365TuneConnect {
    <#
    .SYNOPSIS
        Assigns all 365TUNE permissions — Azure and Exchange Online in one step.

    .DESCRIPTION
        Logs in once then runs Invoke-365TuneConnectAzure and
        Invoke-365TuneConnectExchange in sequence with a single login prompt.

        If Azure setup fails, Exchange setup is skipped.
        If Exchange setup fails, Azure permissions are retained and you can
        re-run Invoke-365TuneConnectExchange separately.

        Run from local PowerShell only (not Cloud Shell).
        Your account must have Global Administrator and Exchange Administrator rights.

    .EXAMPLE
        Invoke-365TuneConnect

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


    [CmdletBinding()]
    param()

    Write-Host "`n══════════════════════════════════════════════════════" -ForegroundColor Cyan
    Write-Host " 365TUNE — Full Permissions Setup" -ForegroundColor Cyan
    Write-Host " Configuring Azure + Exchange Online in one step" -ForegroundColor Cyan
    Write-Host "══════════════════════════════════════════════════════`n" -ForegroundColor Cyan

    # Login once upfront
    Write-Host "Authenticating..." -ForegroundColor Cyan
    Disconnect-AzAccount -ErrorAction SilentlyContinue | Out-Null
    Connect-AzAccount -WarningAction SilentlyContinue | Out-Null
    $context = Get-AzContext
    if (-not $context) { throw "Authentication failed. Please try again." }
    Write-Host " Tenant : $($context.Tenant.Id)" -ForegroundColor Gray
    Write-Host " Account : $($context.Account.Id)" -ForegroundColor Gray
    Write-Host " ✅ Authenticated.`n" -ForegroundColor Green

    # Step 1 — Azure
    Write-Host "[ STEP 1 OF 2 ] Azure Permissions" -ForegroundColor Magenta
    Write-Host "──────────────────────────────────────────────────────" -ForegroundColor Magenta
    try {
        Invoke-365TuneConnectAzure -SkipAuth
    } catch {
        Write-Host "`n❌ Azure setup failed: $($_.Exception.Message)" -ForegroundColor Red
        Write-Host " Exchange setup will be skipped." -ForegroundColor Yellow
        Write-Host " Fix Azure errors and re-run Invoke-365TuneConnect." -ForegroundColor Yellow
        return
    }

    # Step 2 — Exchange
    Write-Host "[ STEP 2 OF 2 ] Exchange Online Permissions" -ForegroundColor Magenta
    Write-Host "──────────────────────────────────────────────────────" -ForegroundColor Magenta
    try {
        Invoke-365TuneConnectExchange -SkipAuth
    } catch {
        Write-Host "`n❌ Exchange setup failed: $($_.Exception.Message)" -ForegroundColor Red
        Write-Host " Azure permissions were configured successfully." -ForegroundColor Yellow
        Write-Host " Fix Exchange errors and re-run Invoke-365TuneConnectExchange." -ForegroundColor Yellow
        return
    }

    Write-Host "`n══════════════════════════════════════════════════════" -ForegroundColor Cyan
    Write-Host " 365TUNE fully configured. ✅" -ForegroundColor Green
    Write-Host " ✅ Azure : Reader at / and /providers/Microsoft.aadiam" -ForegroundColor Green
    Write-Host " ✅ Exchange: View-Only Configuration role assigned" -ForegroundColor Green
    Write-Host "══════════════════════════════════════════════════════`n" -ForegroundColor Cyan
}