Praxistipp #02 - Regeln des bedingten Zugriffs für Admin-Rollen automatisch aktualisieren

Lesedauer 5 Minuten

Problem: Regeln des bedingten Zugriffs werden spezifisch auf Rollen angewendet, die das Wort "Administrator" im Namen tragen. Microsoft fügt immer wieder neue Rollen hinzu, die jedoch nicht automatisch in solchen Regeln ergänzt werden.

Aufgabe: Die Ergänzung neuer Rollen mittels Skripts automatisieren.

Aufbau des Skripts

Du findest das vollständige Skript in meinem Skriptnest. In der Folge wird die Funktionsweise im Detail erläutert.

Auswahl von Optionen

Zu Beginn des Skripts sind zwei Variablen zu modifizieren. Diese regeln, ob das Skript in einem Testmodus oder produktiv (d.h. mit tatsächlichen Änderungen) ausgeführt wird. Es wird empfohlen, das Skript wenigstens einmal im Testmodus auszuführen, um das Verhalten in der eigenen Umgebung zu prüfen.

Außerdem kann das Skript entweder interaktiv (d.h. mit einer Benutzeranmeldung) oder automatisiert (mittels Azure Automation) ausgeführt werden.

Die Variablen werden mit dem Anwendungsbereich $Script: erstellt, damit sie innerhalb aller Funktionen ansprechbar sind.

# Choose simulation mode: Set to $true to only simulate changes. Set to $false to apply changes live.
$Script:WhatIf = $true

# Choose authentication mode: Set to 'Interactive' for user prompt or 'Automated' for service principal authentication.
$Script:ExecutionMode = 'Interactive'
PowerShell

Überprüfung und Installation notwendiger Module

Die Funktion CheckModules prüft, ob die für die Ausführung notwendigen PowerShell-Module (Microsoft.Graph.Authentication, Microsoft.Graph.Identity.SignIns) installiert sind. Dies wird nur dann benötigt, wenn das Skript interaktiv ausgeführt wird. In Azure Automation muss für das Skript eine passende Laufzeitumgebung erstellt werden, welche die notwendigen Module beinhaltet.

function CheckModules
   {
   # Check if needed modules are installed and install, if not
   if (!(Get-InstalledModule -Name Microsoft.Graph.Authentication))
      {
      Write-Host 'Module Microsoft.Graph.Authentication is not installed. Installing for current user...' -ForegroundColor Yellow
      Install-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser -Force
      }
   if (!(Get-InstalledModule -Name Microsoft.Graph.Identity.SignIns))
      {
      Write-Host 'Module Microsoft.Graph.Identity.SignIns is not installed. Installing for current user...' -ForegroundColor Yellow
      Install-Module -Name Microsoft.Graph.Identity.SignIns -Scope CurrentUser -Force
      }
   }
PowerShell

Überprüfung und Aktualisierung von Regeln des bedingten Zugriffs

Die Funktion CheckAndUpdateCARules ermittelt zunächst alle Entra-Rollen, die das Wort "Administrator" im Namen tragen.

Anschließend ermittelt es alle Regeln, die spezifisch auf Administratorrollen angewendet werden und prüft, ob die zugewiesenen Rollen mit den ermittelten Rollen übereinstimmen. Falls nicht, werden die Regeln entsprechend mit den fehlenden Administratorrollen ergänzt. Falls der Testmodus aktiviert ist, gibt das Skript lediglich aus, welche Richtlinie angepasst werden würde.

Falls keine Rollen fehlen, gibt das Skript entsprechend eine Meldung aus und wird beendet.

function CheckAndUpdateCARules
   {
   if ($WhatIf) 
      {
      Write-Output  '==================================================' -ForegroundColor Yellow
      Write-Output ' RUNNING IN WHAT-IF MODE (SIMULATION ON)          ' -ForegroundColor Yellow
      Write-Output  ' No live changes will be made to your policies.   ' -ForegroundColor Yellow
      Write-Output  '==================================================' -ForegroundColor Yellow
      }

   # Connect to Microsoft Graph
   Write-Output 'Connecting to Microsoft Graph...' -ForegroundColor Yellow
   if ($AuthenticationMode -eq 'Interactive'){Connect-MgGraph -Scopes 'Policy.ReadWrite.ConditionalAccess', 'RoleManagement.Read.Directory'}
   if ($AuthenticationMode -eq 'Automated'){Connect-MgGraph -Identity}

   # Retrieve all directory roles containing "Administrator" in their name
   Write-Output 'Retrieving all directory roles with "Administrator" in the name...' -ForegroundColor Cyan
   $allAdminRoles = Get-MgDirectoryRoleTemplate | Where-Object { $_.DisplayName -like "*Administrator*" }

   if ($null -eq $allAdminRoles -or $allAdminRoles.Count -eq 0) 
      {
      Write-Error "No directory roles found containing the word 'Administrator' in the name."
      return
      }

   Write-Output "Total administrator roles found: $($allAdminRoles.Count)" -ForegroundColor Green

   # Retrieve all Conditional Access policies
   Write-Output "Retrieving all Conditional Access policies..." -ForegroundColor Cyan
   $caPolicies = Get-MgIdentityConditionalAccessPolicy

   ForEach ($policy in $caPolicies) 
      {
      # Check if the policy targets specific roles
      $includedRoles = $policy.Conditions.Users.IncludeRoles
        
      if ($null -ne $includedRoles -and $includedRoles.Count -gt 0) 
         {
         # Check if at least one of the included roles is an administrator role
         $hasAdminRole = $false
         foreach ($roleId in $includedRoles) 
            {
            if ($roleId -in $allAdminRoles.Id) 
               {
               $hasAdminRole = $true
               break
               }
            }
            
         # If the policy applies to at least one administrator role
         if ($hasAdminRole) 
            {
            Write-Output '--------------------------------------------------' -ForegroundColor Yellow
            Write-Output "Policy matched: $($policy.DisplayName)" -ForegroundColor Yellow
                
            # Identify missing administrator roles
            $missingRoles = @()
            foreach ($adminRole in $allAdminRoles) 
               {
               if ($adminRole.Id -notin $includedRoles) 
                  {
                  $missingRoles += $adminRole.Id
                  }
               }
                
            if ($missingRoles.Count -gt 0) 
               {
               Write-Output "The following roles are missing in this policy: $($missingRoles.Count)" -ForegroundColor Magenta
                    
               # Create a new list of roles to include (Existing + Missing)
               $updatedRoles = $includedRoles + $missingRoles
                    
               # Prepare the update object
               $updateParams = @{
                  Conditions = @{
                     Users = @{
                        IncludeRoles = $updatedRoles
                        }
                  }
               }
                    
               # Update or simulate the policy update
               if ($WhatIf) {Write-Output "[WHAT-IF] Would update policy '$($policy.DisplayName)' to include all administrator roles." -ForegroundColor DarkYellow}
               else {
                  try {
                      Update-MgIdentityConditionalAccessPolicy -ConditionalAccessPolicyId $policy.Id -BodyParameter $updateParams
                      Write-Output "Policy '$($policy.DisplayName)' successfully updated." -ForegroundColor Green
                      }
                  catch {
                        Write-Error "Failed to update policy '$($policy.DisplayName)': $_"
                        }
                    }
               }
            else {
                 Write-Output "Policy '$($policy.DisplayName)' already contains all administrator roles." -ForegroundColor Green
                 }
            }
        }
    }

    Write-Output '--------------------------------------------------' -ForegroundColor Cyan
    Write-Output  'Review and update process completed.' -ForegroundColor Cyan
   }
PowerShell

Ausführung der Funktionen

Die Funktionen als solche sind nur ein logischer Container für die Ausführung von Befehlen. Sie müssen jedoch explizit ausgeführt werden, damit tatsächlich eine Aktion geschieht. Daher werden die Funktionen am Ende des Skripts entsprechend referenziert und dadurch ausgeführt.

Die Funktion CheckModules wird nur bei interaktiver Ausführung des Skripts ausgeführt, da bei Azure Automation davon ausgegangen wird, dass eine passende Laufzeitumgebung konfiguriert wurde.

# Execute functions
if ($ExecutionMode -eq 'Interactive'){CheckModules}
CheckAndUpdateCARules
PowerShell


Gefällt Dir der Beitrag? Lass es andere wissen!