Public/Permissions/Invoke-365TUNEConnectAll.ps1

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

    .DESCRIPTION
        Works in both local PowerShell and Azure Cloud Shell.
        - Local PowerShell : Logs in once, no subscription picker, auto-selects
          home tenant, then runs ConnectAzure, ConnectExchange, and ConnectTeams in sequence.
        - Cloud Shell : Authenticates via Managed Identity (MSI) silently.

        If Azure setup fails, Exchange and Teams setup are skipped.
        If Exchange setup fails, Teams setup is skipped.
        Individual steps can be re-run separately if needed.

        Your account must have Global Administrator and Exchange Administrator rights.

    .EXAMPLE
        Invoke-365TUNEConnectAll

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


    [CmdletBinding()]
    param()

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

    # Authenticate — Cloud Shell uses MSI, local PowerShell uses interactive login
    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) {
        Write-Host " Cloud Shell detected — authenticating via Managed Identity." -ForegroundColor Gray
        Connect-AzAccount -Identity -WarningAction SilentlyContinue | Out-Null
        $context = Get-AzContext
        if (-not $context) { throw "No active Azure session found in Cloud Shell. Please reload Cloud Shell and try again." }
    } else {
        Disconnect-AzAccount -ErrorAction SilentlyContinue | Out-Null
        Connect-AzAccount -WarningAction SilentlyContinue -SkipContextPopulation | Out-Null
        $context = Get-AzContext
        if (-not $context) { throw "Authentication failed. Please try again." }

        # Auto-switch to home tenant — no subscription picker
        $allTenants = Get-AzTenant
        $userDomain = $context.Account.Id.Split("@")[1]
        $homeTenant = $allTenants | Where-Object { $_.Domains -contains $userDomain } | Select-Object -First 1

        if (-not $homeTenant) { throw "Could not identify home tenant for '$($context.Account.Id)'." }

        Set-AzContext -TenantId $homeTenant.Id -WarningAction SilentlyContinue | Out-Null
        $context = Get-AzContext
        if (-not $context) { throw "Could not connect to home tenant. 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 3 ] 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 and Teams setup will be skipped." -ForegroundColor Yellow
        Write-Host " Fix Azure errors and re-run Invoke-365TUNEConnectAll." -ForegroundColor Yellow
        return
    }

    # Step 2 — Exchange
    Write-Host "[ STEP 2 OF 3 ] 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 " Teams setup will be skipped." -ForegroundColor Yellow
        Write-Host " Fix Exchange errors and re-run Invoke-365TuneConnectExchange." -ForegroundColor Yellow
        return
    }

    # Step 3 — Teams
    Write-Host "[ STEP 3 OF 3 ] Teams Permissions" -ForegroundColor Magenta
    Write-Host "──────────────────────────────────────────────────────" -ForegroundColor Magenta
    try {
        Invoke-365TuneConnectTeams -SkipAuth
    } catch {
        Write-Host "`n❌ Teams setup failed: $($_.Exception.Message)" -ForegroundColor Red
        Write-Host " Azure and Exchange permissions were configured successfully." -ForegroundColor Yellow
        Write-Host " Fix Teams errors and re-run Invoke-365TuneConnectTeams." -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 " ✅ Teams : Teams Reader role assigned" -ForegroundColor Green
    Write-Host "══════════════════════════════════════════════════════`n" -ForegroundColor Cyan
}