Public/Set-NLBaselineCABreakGlassGroup.ps1
|
function Set-NLBaselineCABreakGlassGroup { <# .SYNOPSIS Manage break glass exclusion group for all Conditional Access policies .DESCRIPTION Adds or removes a break glass exclusion group from all Conditional Access policies. This ensures emergency access accounts are always excluded from policies. .EXAMPLE Set-NLBaselineCABreakGlassGroup -GroupName "CABreakGlassExclude" -Action Add #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$GroupName, [Parameter(Mandatory = $true)] [ValidateSet("Add", "Remove")] [string]$Action ) try { # Check connection $context = Get-MgContext -ErrorAction SilentlyContinue if (-not $context -or -not $context.TenantId) { Write-Host "Not connected to Microsoft 365. Connecting..." -ForegroundColor Yellow Write-Host "" $connection = Connect-NLBaselineCA if (-not $connection) { Write-Error "Cannot connect to Microsoft 365" return } $context = Get-MgContext } Write-Host "========================================" -ForegroundColor Cyan Write-Host " BREAK GLASS GROUP MANAGEMENT" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" # Find the group Write-Host "Searching for group: $GroupName" -ForegroundColor Yellow $group = Get-MgGroup -Filter "displayName eq '$GroupName'" -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $group) { Write-Error "Group '$GroupName' not found. Please create the group first." return } Write-Host "Found group: $($group.DisplayName) (ID: $($group.Id))" -ForegroundColor Green Write-Host "" # Get all policies Write-Host "Retrieving all Conditional Access policies..." -ForegroundColor Yellow $policies = Get-AllConditionalAccessPolicies Write-Host "Found $($policies.Count) policies" -ForegroundColor Green Write-Host "" $updatedCount = 0 $skippedCount = 0 $errors = @() foreach ($policy in $policies) { try { $needsUpdate = $false $policyUpdate = @{} # Ensure conditions structure exists if (-not $policy.conditions) { $policyUpdate.conditions = @{ "@odata.type" = "#microsoft.graph.conditionalAccessConditionSet" users = @{ "@odata.type" = "#microsoft.graph.conditionalAccessUsers" includeUsers = @("All") excludeUsers = @() excludeGroups = @() } } $needsUpdate = $true } else { $policyUpdate.conditions = $policy.conditions } # Ensure users structure exists if (-not $policyUpdate.conditions.users) { $policyUpdate.conditions.users = @{ "@odata.type" = "#microsoft.graph.conditionalAccessUsers" includeUsers = @("All") excludeUsers = @() excludeGroups = @() } $needsUpdate = $true } # Ensure excludeGroups array exists if (-not $policyUpdate.conditions.users.excludeGroups) { $policyUpdate.conditions.users.excludeGroups = @() $needsUpdate = $true } # Check if group is already in exclude list $groupInList = $policyUpdate.conditions.users.excludeGroups -contains $group.Id if ($Action -eq "Add" -and -not $groupInList) { # Add group to exclude list if ($policyUpdate.conditions.users.excludeGroups.Count -eq 0) { $policyUpdate.conditions.users.excludeGroups = @($group.Id) } else { $policyUpdate.conditions.users.excludeGroups = $policyUpdate.conditions.users.excludeGroups + $group.Id } $needsUpdate = $true Write-Host " Adding to: $($policy.displayName)" -ForegroundColor Gray } elseif ($Action -eq "Remove" -and $groupInList) { # Remove group from exclude list $policyUpdate.conditions.users.excludeGroups = $policyUpdate.conditions.users.excludeGroups | Where-Object { $_ -ne $group.Id } $needsUpdate = $true Write-Host " Removing from: $($policy.displayName)" -ForegroundColor Gray } else { $skippedCount++ continue } if ($needsUpdate) { # Update policy using REST API $body = @{ conditions = $policyUpdate.conditions } | ConvertTo-Json -Depth 10 $invokeCmd = Get-Command Invoke-MgGraphRequest -ErrorAction SilentlyContinue if ($invokeCmd) { Invoke-MgGraphRequest -Method PATCH ` -Uri "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies/$($policy.Id)" ` -Body $body ` -ContentType "application/json" ` -ErrorAction Stop $updatedCount++ } else { throw "Invoke-MgGraphRequest not available" } } } catch { $errors += "Error updating $($policy.displayName): $_" Write-Host " Error: $($policy.displayName) - $_" -ForegroundColor Red } } Write-Host "" Write-Host "========================================" -ForegroundColor Green Write-Host " SUMMARY" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "Updated: $updatedCount policies" -ForegroundColor White Write-Host "Skipped: $skippedCount policies (already configured)" -ForegroundColor Gray if ($errors.Count -gt 0) { Write-Host "Errors: $($errors.Count)" -ForegroundColor Red foreach ($error in $errors) { Write-Host " - $error" -ForegroundColor Yellow } } Write-Host "" } catch { Write-Error "Error managing break glass group: $_" } } |