Microsoft 365: Privileged Identity Management Voor Bevoorrechte Rollen

💼 Management Samenvatting

Privileged Identity Management (PIM) is de enige duurzame manier om bevoorrechte toegang binnen Microsoft 365 en Entra ID te normaliseren. Het systeem vervangt permanente rechten door kortdurende, aantoonbaar goedgekeurde activaties die automatisch worden gelogd en direct kunnen worden beëindigd zodra het werk is afgerond.

Aanbeveling
IMPLEMENT
Risico zonder
Hoog
Risk Score
9/10
Implementatie
75u (tech: 40u)
Van toepassing op:
M365
Entra ID
Azure

Nederlandse overheidsorganisaties krijgen vanuit de BIO, NIS2 en AVG de opdracht om te bewijzen dat slechts een beperkte groep professionals tijdelijk toegang krijgt tot tenantconfiguraties, sleutelkluizen, auditlogs en andere kroonjuwelen. De snelheid waarmee cloudomgevingen veranderen maakt handmatige registratie en spreadsheet-gestuurde controles onhoudbaar, waardoor privileges sluimerend blijven bestaan en incidenten moeilijk te reconstrueren zijn.

PowerShell Modules Vereist
Primary API: Microsoft Graph API
Connection: Connect-MgGraph
Required Modules: Microsoft.Graph.Identity.Governance

Implementatie

Dit artikel laat stap voor stap zien hoe CISO's, identity-architecten en operatieverantwoordelijken PIM ontwerpen, implementeren en dagelijks besturen. We beschrijven het actuele dreigingsbeeld, de architectuur van just-in-time toegang, de integratie met Conditional Access en ITSM-processen, de governance- en rapportagestructuur én de manier waarop het meegeleverde PowerShell-script als controlemechanisme fungeert.

Urgentie, dreigingsbeeld en compliance-verwachting

Bevoorrechte accounts in Microsoft 365 en Entra ID vormen het zenuwstelsel van iedere Nederlandse tenant. Ze bepalen wie beleid mag wijzigen, welke sleutelkluizen worden geopend en of logging kan worden uitgeschakeld. Aanvallers richten spearphishing, token replay en session hijacking specifiek op deze identiteiten omdat één geslaagde inlog voldoende is om alle andere maatregelen te omzeilen. In incidentdossiers van het NCSC blijkt dat vrijwel elk groot cloudincident begon met een niet-beheerde beheerder. Zonder systematische beperking van toewijzingen blijven gedeelde wachtwoorden, oude serviceaccounts en vergeten externe consultants actief, waardoor kwaadwillenden dagenlang onzichtbaar kunnen opereren. Door het ontbreken van tijdslimieten of justificatie is er geen natuurlijk moment waarop iemand de toegang heroverweegt. PIM adresseert dit direct door iedereen standaard in een inactieve, eligible status te plaatsen en activering alleen toe te staan wanneer er een aantoonbare reden is. Het resultaat is dat hoofdtaken en tijdelijke uitzonderingen strikt gescheiden blijven en dat SOC-analisten het gebruik van privileges realtime kunnen volgen.

Voor bestuurders is naleving van de BIO, NIS2 en AVG een harde eis, niet slechts een best practice. Deze kaders verlangen aantoonbare minimale privileges, verplicht meervoudige authenticatie en volledige herleidbaarheid van wijzigingen in kritieke systemen. Auditors accepteren geen spreadsheets meer waarin een beheerafdeling verklaart dat accounts sporadisch worden opgeschoond; zij eisen exportbestanden waaruit per activatie blijkt wie toestemming gaf, hoe lang de toegang actief bleef en welke maatregelen zijn genomen om misbruik te detecteren. Zonder PIM is dat vrijwel onmogelijk omdat traditionele rolbeheerprocessen geen uniform logboek genereren en uitzonderingen nergens worden geregistreerd. PIM legt justificatie, goedkeuring, start- en eindtijd automatisch vast in de Microsoft 365 auditlog en maakt de gegevens toegankelijk via Microsoft Graph. Hierdoor kan een organisatie binnen minuten rapporteren welke rollen de afgelopen maand zijn gebruikt, hoeveel aanvragen zijn afgewezen en waar aanvullende maatregelen nodig zijn, wat overtuigend bewijs vormt richting toezichthouders en verzekeraars.

Los van compliance creëert het ontbreken van PIM een operationeel risico dat verder gaat dan incidentresponse. Permanente Global Administrators kunnen per ongeluk policies verwijderen, oude scripts kunnen credentials loggen en projectteams laten vaak tijdelijke accounts achter wanneer een implementatie klaar is. Omdat niemand eigenaar is van de offboarding blijft een sluimerende toegang bestaan die bij reorganisaties of outsourcingtrajecten volledig uit het zicht verdwijnt. Tijdens een crisissituatie moet het bestuur echter binnen minuten kunnen aangeven wie verantwoordelijk is voor herstelacties en wie bevoegd is om besluiten te nemen. Wanneer een scenario afhankelijk blijkt te zijn van een zwevend account zonder duidelijke eigenaar, staat het complete continuïteitsproces onder druk. PIM verplicht organisaties om per rol een eigenaar, een goedkeuringslijn en een maximale activeringsduur te definiëren. Daardoor ontstaat een actueel overzicht van wie beschikbaar is voor welke taak en welke accounts direct gedeactiveerd moeten worden zodra iemand vertrekt.

De urgentie voor PIM wordt versterkt doordat cloudplatformen voortdurend functionaliteit toevoegen en beheerrollen granularer worden. Nieuwe workloads brengen nieuwe rechten met zich mee en zonder centrale regie ontstaat privilegespreiding binnen enkele weken. PIM fungeert als de operationele laag bovenop zero-trust architectuur: activaties vereisen meervoudige verificatie, kunnen worden beperkt tot compliant devices en sturen automatisch meldingen naar het SOC. Daarnaast maakt PIM risicogebaseerde policies mogelijk. Een activatie vanaf een onbekende locatie kan bijvoorbeeld worden geblokkeerd totdat Identity Protection het aanmeldingsrisico heeft verlaagd, terwijl dezelfde aanvraag binnen de trusted workspace direct doorgang vindt. Het systeem zorgt er zo niet alleen voor dat minder mensen rechten hebben, maar vooral dat het gebruik van die rechten voorspelbaar, herleidbaar en automatiseerbaar wordt – precies de kern van de Nederlandse Baseline voor Veilige Cloud.

Architectuur en implementatie van just-in-time toegang

Een robuuste implementatie begint met een inventarisatie die verder gaat dan het exporteren van directory-rollen. Identity engineers combineren Microsoft Graph-exports met CMDB-gegevens, changekalenders en contractregistraties om elke rol aan een proces en eigenaar te koppelen. Daarbij worden ook app-rollen, Azure RBAC-posities en delegaties in Exchange of SharePoint meegenomen, omdat aanvallers anders via een omweg alsnog volledige toegang krijgen. Voor elke rol wordt vastgesteld welke bedrijfsfunctie de verantwoordelijkheid draagt, welk risicoprofiel eraan hangt, welke systemen erdoor geraakt worden en welke wetgeving van toepassing is. Deze analyse resulteert in een matrix waarin per rol staat welke activeringsduur maximaal acceptabel is, of justificatie in het Nederlands verplicht is, of vooraf goedkeuring moet plaatsvinden en welke logging minimaal beschikbaar moet zijn. Met die matrix als uitgangspunt kan PIM gericht worden geconfigureerd in plaats van generiek, waardoor de oplossing aansluit op de volwassenheid van afzonderlijke teams.

Na de inventarisatie worden de daadwerkelijke PIM-instellingen ingericht. Voor kroonjuweelrollen zoals Global Administrator, Security Administrator en Key Vault Administrator wordt de activatieduur beperkt tot twee uur en wordt meervoudige authenticatie altijd afgedwongen, ongeacht het Conditional Access-beleid. Goedkeurders bestaan uit een mix van CISO-office en proceseigenaren zodat zowel beveiliging als bedrijfscontinuïteit is geborgd. Voor operationele rollen, zoals SharePoint Administrator of Teams Administrator, kan een iets ruimer venster van vier uur worden toegestaan, mits justificatie verplicht blijft en automatiseringsscripts zijn geregistreerd. Alle meldingen worden doorgestuurd naar Microsoft Sentinel of Azure Monitor zodat SOC-analisten realtime inzicht krijgen. Daarnaast worden standaard notificaties naar e-mail en Teams geconfigureerd zodat rol-eigenaren ook buiten kantooruren updates ontvangen. Door configuratie-instellingen te documenteren in een versiebeheerde repository kunnen wijzigingen herleidbaar worden goedgekeurd.

Just-in-time toegang werkt pas echt als PIM is geïntegreerd met Conditional Access, Identity Protection en changeprocessen. Conditional Access policies controleren of de aanvrager gebruikmaakt van een compliant device, zich binnen een gedefinieerde geografische zone bevindt en geen legacy authenticatie gebruikt. Identity Protection invalideert activaties zodra het aanmeldingsrisico stijgt, bijvoorbeeld bij onmogelijk reizen of gelekte credentials. Tegelijkertijd wordt PIM gekoppeld aan ITSM-toepassingen zoals ServiceNow of TOPdesk: een change-aanvraag bevat automatisch het nummer van de benodigde PIM-rol en de gewenste activatieduur. Wanneer het change record wordt goedgekeurd, kan het script uit dit artikel alvast de eligible status controleren en een waarschuwing geven als de engineer nog geen onboarding heeft afgerond. Hierdoor verdwijnt de afhankelijkheid van ad-hoc chatberichten en ontstaat een reproduceerbare keten van aanvraag tot afsluiting.

De uitrol gebeurt bewust gefaseerd zodat businesskritieke processen niet stilvallen. In de pilotfase worden enkele beheerdersgroepen geselecteerd die representatief zijn voor verschillende scenario's, zoals 24x7 operations, projectteams en leveranciers. Hun ervaringen worden dagelijks verzameld in een logboek waarin staat hoelang activeren duurt, waar gebruikers vastlopen en welke notificaties ontbreken. Deze data wordt gebruikt om instellingen te verfijnen voordat de rest van de organisatie volgt. Na elke tranche wordt een formeel besluit genomen in het security board waarin staat welke rollen zijn omgezet, welke break-glass accounts actief blijven en welke trainingen zijn gegeven. Tegelijkertijd wordt in Entra ID vastgesteld dat niemand nieuwe permanente toewijzingen kan toevoegen zonder dat het CISO-office deze wijziging reviewt. Zo blijft de implementatie beheersbaar en wordt voorkomen dat oude gewoonten terugkeren.

Operationele borging, rapportage en continue optimalisatie

Operationele borging begint met duidelijke rolverantwoordelijkheden. Per PIM-rol wordt een owner benoemd die verantwoordelijk is voor de lijst met eligible gebruikers, de goedkeuringsworkflow en de periodieke review. Deze owner is vaak de proceseigenaar of lead engineer, maar werkt nauw samen met het CISO-office dat toeziet op uniforme toepassing. Elke maand ontvangen de eigenaren een rapportage met statistieken over activeringen, afgewezen aanvragen en uitzonderingen. Het rapport wordt besproken in het security board zodat beslissingen worden vastgelegd en lessons learned uit incidenten direct leiden tot aanpassingen in PIM. Door governance structureel in te bedden verdwijnt de reflex om bij spoed permanente rechten uit te delen.

Monitoring en rapportage rusten op drie databronnen: het PIM-activiteitlogboek, Microsoft Graph-rapportages en het PowerShell-script dat bij dit artikel hoort. SOC-analisten gebruiken de streaming API om activaties naast alerts uit Defender, Purview en Sentinel te leggen en correlaties te zoeken tussen verdachte gebeurtenissen en beheerdersacties. Identity engineers draaien het script dagelijks of wekelijks in een gecontroleerde runbook-omgeving. Het script telt permanente toewijzingen, signaleert activeringen zonder eindtijd en vergelijkt de duur van activaties met de afgesproken baseline. De resultaten worden automatisch opgeslagen als JSON of CSV zodat auditors later exact dezelfde bevindingen kunnen reproduceren. Wanneer een afwijking wordt gevonden, creëert het script optioneel een taak in ITSM via een webhooksjabloon zodat opvolging nooit afhankelijk is van e-mails.

Professionele sturing vereist indicatoren die verder gaan dan het absolute aantal Global Administrators. Typische KPI's zijn het percentage kritieke rollen dat volledig via PIM loopt, het aandeel aanvragen dat extra goedkeuring nodig had, de gemiddelde tijd tussen aanvraag en activatie en het aantal break-glass accounts dat daadwerkelijk is getest. Door deze KPI's per kwartaal met bestuur en auditcomités te delen ontstaat een duidelijke trend. Wanneer bijvoorbeeld blijkt dat activaties structureel langer duren dan gepland, kan men gerichte investeringen doen in automatisering of in de uitbreiding van het goedkeurderspool. Als auditrapportages laten zien dat bepaalde teams opvallend meer uitzonderingen aanvragen, vormt dat input voor extra training of voor aanpassing van de rolindeling.

Tot slot draait duurzame borging om cultuur en adoptie. Nieuwe beheerders krijgen tijdens onboarding een praktijkgerichte instructie waarin wordt geoefend met justificaties, activaties vanuit verschillende locaties en het vroegtijdig beëindigen van rechten zodra het werk klaar is. Leverancierscontracten bevatten clausules over PIM-ondersteuning en eisen dat escalaties uitsluitend via geregistreerde contactpersonen plaatsvinden. Tijdens crisisoefeningen moeten teams expliciet aantonen welk playbook en welke PIM-roleset zij gebruiken, zodat de organisatie ervaart dat het systeem geen hinderpaal is maar juist vertrouwen geeft. Door successen zichtbaar te maken, zoals een incident dat snel was ingedamd omdat een verdachte activatie onmiddellijk werd gemeld, groeit het draagvlak. Uiteindelijk wordt PIM daarmee een vanzelfsprekend onderdeel van het bredere zero-trust programma.

Technische monitoring met PowerShell

Gebruik PowerShell-script privileged-identity-management.ps1 (functie Invoke-Monitoring) – Controleert of kritieke directory-rollen nog permanente toewijzingen hebben, vergelijkt activeringsduur met de baseline en rapporteert eligible versus actieve PIM-toewijzingen via Microsoft Graph..

De monitoringsmodus van het script maakt verbinding met Microsoft Graph en controleert vervolgens of de geselecteerde kritieke rollen nog directe toewijzingen bevatten. Voor elke rol worden de permanente gebruikers, de hoeveelheid eligible accounts en de duur van recente activaties vastgelegd. Wanneer een activatie langer duurt dan het afgesproken maximum of wanneer de eindtijd ontbreekt, verschijnt een waarschuwing met een exitcode die eenvoudig in CI/CD-pijplijnen, Azure Automation of een SOC-runbook kan worden verwerkt. De uitvoer kan als JSON of CSV worden opgeslagen zodat auditors exact dezelfde dataset kunnen reproduceren.

Operationele opvolging en remediatie

Gebruik PowerShell-script privileged-identity-management.ps1 (functie Invoke-Remediation) – Genereert een gestructureerde checklist om permanente toewijzingen om te zetten naar eligible status, inclusief communicatie naar rol-eigenaren en validatie van justificatie- en goedkeuringsinstellingen..

Tijdens remediatie wordt dezelfde dataset gebruikt om automatisch een stappenplan te tonen per rol. Het script groepeert de gevonden permanente accounts, toont welke goedkeuringsinstellingen ontbreken en geeft concrete instructies voor het converteren naar eligible status. Indien gewenst kan een WhatIf-modus worden gebruikt om het effect van de aanpassingen te beoordelen voordat acties in Entra ID worden uitgevoerd. De resultaten worden aangevuld met aanbevelingen voor communicatie naar rol-eigenaren en voor het vastleggen van besluiten in het security board, zodat opvolging niet afhankelijk is van losse notities.

Compliance & Frameworks

Automation

Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).

PowerShell
<# .SYNOPSIS Microsoft 365 Privileged Identity Management Monitoring .DESCRIPTION Controleert of bevoorrechte Entra ID-rollen via Privileged Identity Management (PIM) worden beheerd. Het script identificeert permanente roltoewijzingen, vergelijkt eligible (geschikte) toewijzingen met actieve toewijzingen en signaleert activaties die langer duren dan de toegestane baseline (standaard acht uur). Optioneel kan de uitvoer worden geëxporteerd naar JSON of CSV voor auditdoeleinden. .NOTES Project : Nederlandse Baseline voor Veilige Cloud Version : 1.0 Author : Nederlandse Baseline voor Veilige Cloud Team Requires: Microsoft.Graph.Identity.Governance (RoleManagement.Read.All, Directory.Read.All) .EXAMPLE .\privileged-identity-management.ps1 -Monitoring Voert alle controles uit en geeft een overzichtelijke compliance-status terug. .EXAMPLE .\privileged-identity-management.ps1 -Monitoring -OutputPath .\pim-status.json Controleert de status en schrijft de resultaten weg naar een JSON-bestand. .EXAMPLE .\privileged-identity-management.ps1 -Remediation Genereert een checklist voor het omzetten van permanente toewijzingen naar eligible status. .EXAMPLE .\privileged-identity-management.ps1 -Remediation -WhatIf Toont welke stappen zouden worden uitgevoerd zonder wijzigingen door te voeren. #> #Requires -Version 5.1 #Requires -Modules Microsoft.Graph.Identity.Governance [CmdletBinding()] param( [Parameter(Mandatory = $false)] [switch]$Monitoring, [Parameter(Mandatory = $false)] [switch]$Remediation, [Parameter(Mandatory = $false)] [switch]$WhatIf, [Parameter(Mandatory = $false)] [string]$OutputPath, [Parameter(Mandatory = $false)] [ValidateSet("Json", "Csv")] [string]$OutputFormat = "Json" ) $ErrorActionPreference = 'Stop' $CriticalRoles = @( "Global Administrator", "Privileged Role Administrator", "Security Administrator", "Exchange Administrator", "SharePoint Administrator", "Teams Administrator", "Compliance Administrator", "Application Administrator" ) $MaximumActivationHours = 8 Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "Privileged Identity Management Monitoring" -ForegroundColor Cyan Write-Host "Nederlandse Baseline voor Veilige Cloud" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Connect-IdentityGraph { <# .SYNOPSIS Zorgt voor een geldige Microsoft Graph-verbinding. #> [CmdletBinding()] param() try { $context = Get-MgContext -ErrorAction SilentlyContinue if (-not $context) { Write-Host "[INFO] Verbinden met Microsoft Graph..." -ForegroundColor Gray Connect-MgGraph -Scopes "RoleManagement.Read.All", "Directory.Read.All", "AuditLog.Read.All" -ErrorAction Stop -NoWelcome } else { Write-Verbose "Microsoft Graph context actief voor $($context.Account)" } } catch { throw "Verbinding met Microsoft Graph is mislukt: $($_.Exception.Message)" } } function Get-PimStatus { <# .SYNOPSIS Haalt de PIM-configuratiestatus op voor kritieke directory-rollen. .OUTPUTS PSCustomObject met permanente toewijzingen, eligible toewijzingen en activatiebevindingen. #> [CmdletBinding()] param() Connect-IdentityGraph $status = [ordered]@{ Timestamp = Get-Date PermanentAssignments = @() EligibleAssignments = @() ActivationFindings = @() RoleCoverage = @() } try { $roles = Get-MgDirectoryRole -All -ErrorAction Stop | Where-Object { $_.DisplayName -in $CriticalRoles } } catch { throw "Kon directory-rollen niet ophalen: $($_.Exception.Message)" } foreach ($role in $roles) { Write-Verbose "Evalueren van rol '$($role.DisplayName)'..." $members = @() try { $members = Get-MgDirectoryRoleMember -DirectoryRoleId $role.Id -All -ErrorAction Stop } catch { Write-Warning "Kon leden van rol $($role.DisplayName) niet ophalen: $($_.Exception.Message)" } foreach ($member in $members) { if ($member."@odata.type" -ne "#microsoft.graph.user") { continue } try { $user = Get-MgUser -UserId $member.Id -ErrorAction Stop $status.PermanentAssignments += [pscustomobject]@{ Role = $role.DisplayName UserPrincipalName = $user.UserPrincipalName DisplayName = $user.DisplayName } } catch { Write-Warning "Kon gebruiker $($member.Id) niet ophalen: $($_.Exception.Message)" } } $status.RoleCoverage += [pscustomobject]@{ RoleName = $role.DisplayName PermanentCount = $members.Count } } try { $roleDefinitions = Get-MgRoleManagementDirectoryRoleDefinition -All -ErrorAction Stop $eligibleSchedules = Get-MgRoleManagementDirectoryRoleEligibilitySchedule -All -ErrorAction Stop foreach ($schedule in $eligibleSchedules) { $definition = $roleDefinitions | Where-Object { $_.Id -eq $schedule.RoleDefinitionId } if ($definition -and $definition.DisplayName -in $CriticalRoles) { $status.EligibleAssignments += [pscustomobject]@{ RoleName = $definition.DisplayName PrincipalId = $schedule.PrincipalId StartDateTime = $schedule.StartDateTime EndDateTime = $schedule.EndDateTime } } } } catch { Write-Warning "Kon eligible PIM-toewijzingen niet ophalen: $($_.Exception.Message)" } try { $assignmentInstances = Get-MgRoleManagementDirectoryRoleAssignmentScheduleInstance -All -ErrorAction Stop foreach ($instance in $assignmentInstances) { $definition = $roleDefinitions | Where-Object { $_.Id -eq $instance.RoleDefinitionId } if (-not $definition -or $definition.DisplayName -notin $CriticalRoles) { continue } if ($instance.EndDateTime -and $instance.StartDateTime) { $duration = ([datetime]$instance.EndDateTime) - ([datetime]$instance.StartDateTime) if ($duration.TotalHours -gt $MaximumActivationHours) { $status.ActivationFindings += [pscustomobject]@{ RoleName = $definition.DisplayName PrincipalId = $instance.PrincipalId DurationHours = [math]::Round($duration.TotalHours, 2) Finding = "Activatie overschrijdt $MaximumActivationHours uur" } } } elseif (-not $instance.EndDateTime) { $status.ActivationFindings += [pscustomobject]@{ RoleName = $definition.DisplayName PrincipalId = $instance.PrincipalId DurationHours = $null Finding = "Activatie zonder eindtijd gedetecteerd" } } } } catch { Write-Warning "Kon activeringsinstanties niet ophalen: $($_.Exception.Message)" } return [pscustomobject]$status } function Write-Findings { <# .SYNOPSIS Schrijft bevindingen naar de console. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Status ) Write-Host "`n[RESULTATEN]" -ForegroundColor Cyan Write-Host " Permanente toewijzingen : $($Status.PermanentAssignments.Count)" -ForegroundColor $(if ($Status.PermanentAssignments.Count -eq 0) { "Green" } else { "Yellow" }) Write-Host " Eligible toewijzingen : $($Status.EligibleAssignments.Count)" -ForegroundColor $(if ($Status.EligibleAssignments.Count -gt 0) { "Green" } else { "Red" }) Write-Host " Activatiebevindingen : $($Status.ActivationFindings.Count)" -ForegroundColor $(if ($Status.ActivationFindings.Count -eq 0) { "Green" } else { "Yellow" }) if ($Status.PermanentAssignments.Count -gt 0) { Write-Host "`n [DETAIL] Permanente toewijzingen:" -ForegroundColor Yellow $Status.PermanentAssignments | Sort-Object Role, UserPrincipalName | ForEach-Object { Write-Host " - $($_.Role) : $($_.UserPrincipalName)" -ForegroundColor Gray } } if ($Status.ActivationFindings.Count -gt 0) { Write-Host "`n [DETAIL] Activatiebevindingen:" -ForegroundColor Yellow $Status.ActivationFindings | ForEach-Object { $durationText = if ($_.DurationHours) { "$($_.DurationHours) uur" } else { "geen eindtijd" } Write-Host " - Rol $($_.RoleName) voor principal $($_.PrincipalId): $($_.Finding) ($durationText)" -ForegroundColor Gray } } } function Export-PimStatus { <# .SYNOPSIS Exporteert de resultaten optioneel naar JSON of CSV. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [pscustomobject]$Status ) if (-not $OutputPath) { return } try { $targetDir = Split-Path -Path $OutputPath -Parent if ([string]::IsNullOrWhiteSpace($targetDir)) { $targetDir = Get-Location } if (-not (Test-Path -Path $targetDir)) { New-Item -ItemType Directory -Path $targetDir -Force | Out-Null } if ($OutputFormat -eq "Json") { $Status | ConvertTo-Json -Depth 6 | Out-File -FilePath $OutputPath -Encoding UTF8 -Force } else { $rows = @() foreach ($item in $Status.PermanentAssignments) { $rows += [pscustomobject]@{ Section = "PermanentAssignment" Role = $item.Role Principal = $item.UserPrincipalName Details = $item.DisplayName } } foreach ($item in $Status.EligibleAssignments) { $rows += [pscustomobject]@{ Section = "EligibleAssignment" Role = $item.RoleName Principal = $item.PrincipalId Details = "{0} - {1}" -f $item.StartDateTime, $item.EndDateTime } } foreach ($item in $Status.ActivationFindings) { $durationText = if ($null -ne $item.DurationHours) { $item.DurationHours } else { "n.v.t." } $rows += [pscustomobject]@{ Section = "ActivationFinding" Role = $item.RoleName Principal = $item.PrincipalId Details = "{0} ({1})" -f $item.Finding, $durationText } } if (-not $rows) { $rows = ,([pscustomobject]@{ Section = "Summary" Role = "n.v.t." Principal = "n.v.t." Details = "Geen gegevens om te exporteren" }) } $rows | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 -Force } Write-Host "[OK] Resultaten geëxporteerd naar: $OutputPath" -ForegroundColor Green } catch { Write-Host "[WARN] Export is mislukt: $($_.Exception.Message)" -ForegroundColor Yellow } } function Invoke-Monitoring { <# .SYNOPSIS Voert alle PIM-controles uit en geeft een exitcode voor geautomatiseerde pipelines. #> [CmdletBinding()] param() Write-Host "[INFO] Start monitoring van Privileged Identity Management..." -ForegroundColor Cyan $status = Get-PimStatus Write-Findings -Status $status Export-PimStatus -Status $status $compliant = ($status.PermanentAssignments.Count -eq 0) -and ($status.ActivationFindings.Count -eq 0) -and ($status.EligibleAssignments.Count -gt 0) if ($compliant) { Write-Host "`n[OK] COMPLIANT - Alle kritieke rollen worden via PIM beheerd." -ForegroundColor Green exit 0 } else { Write-Host "`n[WARN] NIET VOLLEDIG COMPLIANT - Zie details hierboven." -ForegroundColor Yellow exit 1 } } function Invoke-Remediation { <# .SYNOPSIS Geeft richtlijnen voor het oplossen van PIM-afwijkingen. #> [CmdletBinding()] param() Write-Host "[INFO] Start remediatieoverzicht..." -ForegroundColor Cyan $status = Get-PimStatus Export-PimStatus -Status $status if ($status.PermanentAssignments.Count -eq 0 -and $status.ActivationFindings.Count -eq 0) { Write-Host "[OK] Geen directe remediatie nodig. Blijf monitoring uitvoeren." -ForegroundColor Green return } if ($status.PermanentAssignments.Count -gt 0) { Write-Host "`nStap 1: Converteer permanente toewijzingen naar eligible status." -ForegroundColor Yellow if ($WhatIf) { Write-Host "[WhatIf] De volgende toewijzingen worden geconverteerd:" -ForegroundColor Yellow } $status.PermanentAssignments | Sort-Object Role, UserPrincipalName | ForEach-Object { Write-Host (" - {0} : {1}" -f $_.Role, $_.UserPrincipalName) -ForegroundColor Gray } Write-Host "Voer deze stap uit in Entra ID Portal > Privileged Identity Management > Azure AD roles." -ForegroundColor Gray Write-Host "Selecteer de rol, kies 'Assignments', conversie naar 'Eligible' en bevestig justificatie- en MFA-instellingen." -ForegroundColor Gray } if ($status.ActivationFindings.Count -gt 0) { Write-Host "`nStap 2: Verscherp activeringsinstellingen." -ForegroundColor Yellow Write-Host "Controleer per rol of de maximale activeringsduur $MaximumActivationHours uur is, justificatie verplicht is en goedkeurders zijn ingesteld." -ForegroundColor Gray Write-Host "Verifieer tevens dat notificaties naar SOC-dashboards worden geleverd." -ForegroundColor Gray } Write-Host "`nStap 3: Documenteer besluitvorming in het security board en update change-registraties." -ForegroundColor Yellow Write-Host "Gebruik de output van dit script als auditbewijs en koppel bevindingen aan change tickets." -ForegroundColor Gray } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Gebruik -Monitoring voor controles of -Remediation voor opvolging." -ForegroundColor Yellow } } catch { Write-Host "`n[FAIL] Er is een fout opgetreden: $_" -ForegroundColor Red exit 2 } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan }

Risico zonder implementatie

Risico zonder implementatie
Hoog: Zonder PIM blijven tientallen permanente beheerdersaccounts actief, waardoor één gecompromitteerd wachtwoord voldoende is om logging, encryptie en compliance-instellingen uit te schakelen. Dit druist in tegen BIO en NIS2 en leidt vrijwel zeker tot sancties en langdurige verstoringen.

Management Samenvatting

Activeer PIM voor alle bevoorrechte rollen, converteer permanente toewijzingen naar eligible status, dwing justificatie, MFA en goedkeuring af en monitor activaties met scripts zodat audits en SOC's altijd inzicht hebben.