Public/Permissions/Invoke-365TuneConnectAzure.ps1
|
function Invoke-365TuneConnectAzure { <# .SYNOPSIS Assigns Reader permissions to the 365TUNE Enterprise App in Azure. .DESCRIPTION Grants Reader access at root scope "/" and AAD IAM scope "/providers/Microsoft.aadiam". Temporarily elevates to User Access Administrator then self-cleans after assignment. Run from local PowerShell or Cloud Shell. Your account must have Global Administrator rights and "Access management for Azure resources" enabled in Entra ID > Properties. .EXAMPLE Invoke-365TuneConnectAzure .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 — Assign Azure Permissions" -ForegroundColor Cyan Write-Host "══════════════════════════════════════════════════════`n" -ForegroundColor Cyan # Step 1 — Check modules Write-Host "[1/5] Checking required modules..." -ForegroundColor Cyan foreach ($module in @("Az.Accounts", "Az.Resources")) { if (-not (Get-Module -ListAvailable -Name $module)) { Write-Host " Installing $module..." -ForegroundColor Yellow Install-Module -Name $module -Force -Scope CurrentUser } } Import-Module Az.Accounts, Az.Resources Write-Host " ✅ Modules ready." -ForegroundColor Green # Step 2 — Authenticate Write-Host "`n[2/5] Authenticating..." -ForegroundColor Cyan if (-not $SkipAuth) { 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 " ✅ Authenticated." -ForegroundColor Green # Step 3 — Fetch Service Principal Write-Host "`n[3/5] Looking up 365TUNE Service Principal..." -ForegroundColor Cyan $sp = Get-AzADServicePrincipal -DisplayName $displayName | Select-Object Id, AppId, DisplayName if (-not $sp) { throw "Service Principal '$displayName' not found. Ensure the 365TUNE app has been consented to in this tenant." } $servicePrincipalId = $sp.Id Write-Host " Display Name : $($sp.DisplayName)" Write-Host " Object ID : $servicePrincipalId" Write-Host " App ID : $($sp.AppId)" # Step 4 — Elevate and assign Reader Write-Host "`n[4/5] Elevating and assigning Reader permissions..." -ForegroundColor Cyan Write-Host " (Elevation is temporary — removed at end of script)" Invoke-365TuneElevation foreach ($scope in @("/", "/providers/Microsoft.aadiam")) { try { New-AzRoleAssignment ` -ObjectId $servicePrincipalId ` -Scope $scope ` -RoleDefinitionName "Reader" ` -ObjectType "ServicePrincipal" ` -SkipClientSideScopeValidation ` -ErrorAction Stop Write-Host " ✅ Reader assigned at '$scope'" -ForegroundColor Green } catch { if ($_.Exception.Message -like "*Conflict*") { Write-Warning " ⚠️ Reader at '$scope' already exists — skipping" } else { throw } } } # Step 5 — Verify and remove elevation Write-Host "`n[5/5] Verifying and removing elevation..." -ForegroundColor Cyan $verified = Invoke-AzRestMethod ` -Path "providers/Microsoft.aadiam/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01&`$filter=principalId eq '$servicePrincipalId'" ` -Method GET $verifiedValues = ($verified.Content | ConvertFrom-Json).value if ($verifiedValues.Count -gt 0) { $verifiedValues | Select-Object -ExpandProperty properties | ForEach-Object { Write-Host " Verified scope: $($_.scope)" -ForegroundColor Green } } else { Write-Warning " Could not verify assignments — check Azure Portal." } Remove-365TuneElevation Write-Host "`n══════════════════════════════════════════════════════" -ForegroundColor Cyan Write-Host " 365TUNE Azure permissions configured. ✅" -ForegroundColor Green Write-Host " Tenant : $($context.Tenant.Id)" -ForegroundColor Green Write-Host " Account : $($context.Account.Id)" -ForegroundColor Green Write-Host "══════════════════════════════════════════════════════`n" -ForegroundColor Cyan } |