Public/Set-NLBaselineCAPolicyAdminRoles.ps1
|
function Set-NLBaselineCAPolicyAdminRoles { <# .SYNOPSIS Add or remove admin roles from Conditional Access policies .DESCRIPTION Allows bulk management of admin role inclusions/exclusions in Conditional Access policies. Useful for ensuring admin roles are properly protected. .EXAMPLE Set-NLBaselineCAPolicyAdminRoles -Action Include -RoleIds @("role-id-1", "role-id-2") -PolicyPrefix "CA100" #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidateSet("Include", "Exclude")] [string]$Action, [Parameter(Mandatory = $true)] [string[]]$RoleIds, [Parameter(Mandatory = $false)] [string]$PolicyPrefix = "" ) 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 " ADMIN ROLES MANAGEMENT" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "" Write-Host "Action: $Action admin roles" -ForegroundColor Yellow Write-Host "Roles: $($RoleIds.Count)" -ForegroundColor Yellow if ($PolicyPrefix) { Write-Host "Filter: Policies starting with '$PolicyPrefix'" -ForegroundColor Yellow } Write-Host "" # Get all policies Write-Host "Retrieving Conditional Access policies..." -ForegroundColor Gray $policies = Get-AllConditionalAccessPolicies # Filter by prefix if specified if ($PolicyPrefix) { $policies = $policies | Where-Object { $_.DisplayName -like "$PolicyPrefix*" } } Write-Host "Found $($policies.Count) policies to process" -ForegroundColor Green Write-Host "" $updatedCount = 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 = if ($policy.conditions.users.includeUsers) { $policy.conditions.users.includeUsers } else { @("All") } excludeUsers = if ($policy.conditions.users.excludeUsers) { $policy.conditions.users.excludeUsers } else { @() } excludeGroups = if ($policy.conditions.users.excludeGroups) { $policy.conditions.users.excludeGroups } else { @() } } } $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 } # Initialize role arrays if needed if ($Action -eq "Include") { if (-not $policyUpdate.conditions.users.includeRoles) { $policyUpdate.conditions.users.includeRoles = @() $needsUpdate = $true } # Add roles that aren't already included $currentRoles = if ($policyUpdate.conditions.users.includeRoles) { $policyUpdate.conditions.users.includeRoles } else { @() } $newRoles = $RoleIds | Where-Object { $_ -notin $currentRoles } if ($newRoles.Count -gt 0) { $policyUpdate.conditions.users.includeRoles = $currentRoles + $newRoles $needsUpdate = $true Write-Host " Adding roles to: $($policy.displayName)" -ForegroundColor Gray } } elseif ($Action -eq "Exclude") { if (-not $policyUpdate.conditions.users.excludeRoles) { $policyUpdate.conditions.users.excludeRoles = @() $needsUpdate = $true } # Add roles that aren't already excluded $currentRoles = if ($policyUpdate.conditions.users.excludeRoles) { $policyUpdate.conditions.users.excludeRoles } else { @() } $newRoles = $RoleIds | Where-Object { $_ -notin $currentRoles } if ($newRoles.Count -gt 0) { $policyUpdate.conditions.users.excludeRoles = $currentRoles + $newRoles $needsUpdate = $true Write-Host " Excluding roles from: $($policy.displayName)" -ForegroundColor Gray } } 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: $_" -ForegroundColor Red } } Write-Host "" Write-Host "========================================" -ForegroundColor Green Write-Host " SUMMARY" -ForegroundColor Green Write-Host "========================================" -ForegroundColor Green Write-Host "Updated: $updatedCount policies" -ForegroundColor White 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 admin roles: $_" } } |