Public/Permissions/Invoke-365TuneRevokeExchange.ps1
|
function Invoke-365TuneRevokeExchange { <# .SYNOPSIS Revokes Exchange Online View-Only Configuration role from the 365TUNE Enterprise App. .DESCRIPTION Removes the View-Only Configuration role assignment and Service Principal registration from Exchange Online. Safe to re-run - exits cleanly if nothing is found. Run from local PowerShell only (not Cloud Shell). Your account must have Global Administrator and Exchange Administrator rights. .EXAMPLE Invoke-365TuneRevokeExchange .NOTES Author : Metawise Consulting LLC Module : 365TUNE Version : 1.9.0 #> [CmdletBinding()] param( [switch]$SkipAuth ) $displayName = "365TUNE - Security and Compliance" Write-Host "`n======================================================" -ForegroundColor Cyan Write-Host " 365TUNE - Revoke Exchange Online Permissions" -ForegroundColor Cyan Write-Host "======================================================`n" -ForegroundColor Cyan # Step 1 - Check modules Write-Host "[1/4] Checking required modules..." -ForegroundColor Cyan foreach ($module in @("Az.Accounts", "ExchangeOnlineManagement")) { if (-not (Get-Module -ListAvailable -Name $module)) { Write-Host " Installing $module..." -ForegroundColor Yellow Install-Module -Name $module -Force -Scope CurrentUser } } Import-Module Az.Accounts, ExchangeOnlineManagement Write-Host " [OK] All modules ready." -ForegroundColor Green # Step 2 - Authenticate Write-Host "`n[2/4] Authenticating..." -ForegroundColor Cyan if (-not $SkipAuth) { $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 -Identity -WarningAction SilentlyContinue | Out-Null } else { Disconnect-AzAccount -ErrorAction SilentlyContinue | Out-Null Connect-AzAccount -WarningAction SilentlyContinue | Out-Null } } $context = Get-AzContext if (-not $context) { throw "Not authenticated. Run without -SkipAuth or log in manually first." } Write-Host " Tenant : $($context.Tenant.Id)" -ForegroundColor Gray Write-Host " Account : $($context.Account.Id)" -ForegroundColor Gray Write-Host " [OK] Authenticated." -ForegroundColor Green # Step 3 - Connect to Exchange Online and check assignments Write-Host "`n[3/4] Connecting to Exchange Online..." -ForegroundColor Cyan Connect-ExchangeOnline -ShowBanner:$false Start-Sleep -Milliseconds 500 Write-Host " [OK] Connected." -ForegroundColor Green $existingAssignment = Get-ManagementRoleAssignment -ErrorAction SilentlyContinue | Where-Object { $_.RoleAssigneeName -eq $displayName -and $_.Role -eq "View-Only Configuration" } $existingSP = Get-ServicePrincipal -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq $displayName } if (-not $existingAssignment -and -not $existingSP) { Write-Host "`n======================================================" -ForegroundColor Cyan Write-Host " No Exchange permissions found - nothing to revoke. [OK]" -ForegroundColor Green Write-Host "======================================================`n" -ForegroundColor Cyan Disconnect-ExchangeOnline -Confirm:$false Start-Sleep -Milliseconds 500 return } # Step 4 - Remove role and Service Principal Write-Host "`n[4/4] Removing role and Service Principal..." -ForegroundColor Cyan if ($existingAssignment) { try { Remove-ManagementRoleAssignment -Identity "$($existingAssignment.Name)" -Confirm:$false -ErrorAction Stop Write-Host " [OK] View-Only Configuration role removed." -ForegroundColor Green } catch { if ($_.Exception.Message -like "*couldn't be found*" -or $_.Exception.Message -like "*NotFound*") { Write-Warning " [WARN] Role assignment not found - already removed" } else { throw } } } else { Write-Warning " [WARN] No role assignment found - already removed" } if ($existingSP) { try { Remove-ServicePrincipal -Identity $existingSP.Identity -Confirm:$false -ErrorAction Stop Write-Host " [OK] Service Principal removed from Exchange Online." -ForegroundColor Green } catch { if ($_.Exception.Message -like "*couldn't be found*" -or $_.Exception.Message -like "*NotFound*") { Write-Warning " [WARN] Service Principal not found - already removed" } else { throw } } } else { Write-Warning " [WARN] No Service Principal found - already removed" } Disconnect-ExchangeOnline -Confirm:$false Start-Sleep -Milliseconds 500 Write-Host " Exchange Online session closed." -ForegroundColor Gray Write-Host "`n======================================================" -ForegroundColor Cyan Write-Host " 365TUNE Exchange Online permissions revoked. [OK]" -ForegroundColor Green Write-Host " Tenant : $($context.Tenant.Id)" -ForegroundColor Green Write-Host " Account : $($context.Account.Id)" -ForegroundColor Green Write-Host "======================================================`n" -ForegroundColor Cyan } |