Naar hoofdinhoud
Joinly by KoppelHet

Entra ID en Active Directory

Van HR naar Active Directory: nieuwe medewerkers automatisch een account geven

Een nieuwe medewerker staat in het HR-systeem. Toch moet IT nog een AD-account maken, de juiste groepen toevoegen en soms een mailbox voorbereiden. Met een PowerShell-script kom je een eind, maar wat gebeurt er bij functiewijzigingen, fouten of vertrek? We vergelijken de klassieke aanpak met Microsofts provisioningmogelijkheden.

Van een HR-export naar een AD-account: de bekende aanpak

Een nieuwe medewerker staat in het HR-systeem. IT krijgt een export, draait een script en het account verschijnt in Active Directory. Dat werkt, totdat de uitzonderingen zich opstapelen.

Bijna elke IT-afdeling met Active Directory op locatie heeft het ooit gebouwd. HR zet nieuwe medewerkers in een export, iemand draait een script, en het script maakt met New-ADUser uit de ActiveDirectory-module een account aan in de juiste OU. Daarna komen de groepen erbij met Add-ADGroupMember, en via Entra Connect Sync of Cloud Sync verschijnt het account een tijd later in Microsoft Entra ID. Dit artikel begint bij dat script, omdat het laat zien welke beslissingen je hoe dan ook moet nemen. Hoe Joinly dit als product doet, staat op Active Directory op locatie.

Het voorbeeld hieronder werkt zoals het er staat, met een CSV met puntkomma's zoals een Nederlandse Excel-export die maakt. Het zoekt eerst op personeelsnummer of het account al bestaat, kiest de OU op afdeling, maakt een tijdelijk wachtwoord en zet de medewerker in de groepen van zijn afdeling.

Nieuwe medewerkers uit een HR-export aanmaken in Active Directory
Import-Module ActiveDirectory

$domein   = "bedrijf.nl"
$standaardOU = "OU=Nieuw,OU=Medewerkers,DC=bedrijf,DC=local"
$ouPerAfdeling = @{
  "Financien"  = "OU=Financien,OU=Medewerkers,DC=bedrijf,DC=local"
  "Verkoop"    = "OU=Verkoop,OU=Medewerkers,DC=bedrijf,DC=local"
  "Logistiek"  = "OU=Logistiek,OU=Medewerkers,DC=bedrijf,DC=local"
}
$groepenPerAfdeling = @{
  "Financien"  = @("GG-Financien", "GG-Alle-medewerkers")
  "Verkoop"    = @("GG-Verkoop", "GG-CRM-Gebruikers", "GG-Alle-medewerkers")
  "Logistiek"  = @("GG-Logistiek", "GG-Alle-medewerkers")
}

function New-TijdelijkWachtwoord {
  $tekens = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!#%+?"
  -join (1..20 | ForEach-Object { $tekens[(Get-Random -Maximum $tekens.Length)] })
}

$regels = Import-Csv -Path "C:\HR\nieuwe-medewerkers.csv" -Delimiter ";"

foreach ($r in $regels) {
  # Bestaat er al iemand met dit personeelsnummer? Dan niets aanmaken.
  if (Get-ADUser -Filter "EmployeeID -eq '$($r.Personeelsnummer)'") { continue }

  $sam = ("{0}.{1}" -f $r.Voornaam, $r.Achternaam).ToLower() -replace "[^a-z0-9.]", ""
  if (Get-ADUser -Filter "SamAccountName -eq '$sam'") { $sam = "$sam$($r.Personeelsnummer)" }

  $ou = $ouPerAfdeling[$r.Afdeling]
  if (-not $ou) { $ou = $standaardOU }

  $wachtwoord = New-TijdelijkWachtwoord
  $nieuw = @{
    Name                  = "$($r.Voornaam) $($r.Achternaam)"
    GivenName             = $r.Voornaam
    Surname               = $r.Achternaam
    DisplayName           = "$($r.Voornaam) $($r.Achternaam)"
    SamAccountName        = $sam
    UserPrincipalName     = "$sam@$domein"
    EmployeeID            = $r.Personeelsnummer
    Department            = $r.Afdeling
    Title                 = $r.Functie
    Path                  = $ou
    AccountPassword       = (ConvertTo-SecureString $wachtwoord -AsPlainText -Force)
    ChangePasswordAtLogon = $true
    Enabled               = $true
  }
  New-ADUser @nieuw

  foreach ($groep in $groepenPerAfdeling[$r.Afdeling]) {
    Add-ADGroupMember -Identity $groep -Members $sam
  }
  Write-Output "$sam aangemaakt in $ou"
}

Welke gegevens bepalen waar een medewerker terechtkomt?

Afdeling, functie en personeelsnummer lijken gewone administratie. In Active Directory kunnen ze bepalen in welke OU en groepen iemand belandt.

Een AD-account is een verzameling attributen. Welke je vult, bepaalt wat er later mogelijk is: een dynamische groep in Entra ID op afdeling werkt alleen als department gevuld is, en een organigram in Teams alleen als manager klopt. Dit is de koppeling die de meeste scripts maken:

Van HR-veld naar AD-attribuut
HR-veldAD-attribuutLet op
PersoneelsnummeremployeeIDDe sleutel om iemand terug te vinden. Een naam verandert, een personeelsnummer niet.
Voornaam, achternaamgivenName, sn, displayNameTussenvoegsels: kies één regel en houd je eraan, ook in de UPN.
AfdelingdepartmentBepaalt vaak de OU en de groepen. Een hernoemde afdeling in HR breekt de koppeling in het script.
FunctietitleWordt in Entra ID jobTitle. Vaak de basis voor rollen en licenties.
LeidinggevendemanagerVerwacht de distinguished name van een bestaand account, niet een naam. De manager moet dus eerst bestaan.
LocatiephysicalDeliveryOfficeName of lHandig voor een OU per vestiging of voor groepen per locatie.

De OU is meer dan een map. Groepsbeleid (GPO's) hangt aan OU's, en de scope van je sync naar Entra ID is vaak ook op OU ingesteld. Een account in de verkeerde OU krijgt dus de verkeerde instellingen op zijn werkplek, of komt helemaal niet in de cloud aan. Daarom zet het script hierboven onbekende afdelingen in een aparte OU Nieuw, zodat je ze ziet in plaats van dat ze ergens verdwijnen.

Groepen per afdeling werken tot iemand overstapt. Dan moet hij naar een andere OU (Move-ADObject) en in andere groepen, en moet hij uit de oude. Een script dat alleen nieuwe medewerkers aanmaakt, doet dat niet. Hoe je groepen opbouwt zodat een overstap één wijziging is, lees je in Entra ID-groepen inrichten voor roltoegang.

Waarom een werkend script toch steeds meer onderhoud vraagt

De eerste versie is vaak snel gebouwd. Het echte werk begint wanneer afdelingen veranderen, mensen terugkomen of meerdere systemen dezelfde gegevens nodig hebben.

Het script werkt op de dag dat het af is. Daarna verandert de omgeving eromheen, en het script verandert niet mee. Dit zijn de plekken waar het misgaat:

  • Het kent alleen nieuwe medewerkers. Een overstap, een naamswijziging en een vertrek komen er niet in. Wie vertrekt, blijft actief tot iemand eraan denkt. Een tweede script voor uitdienst is snel geschreven, maar draait dan op een andere export met andere kolommen.
  • De export verandert. HR hernoemt een kolom of voegt er een toe, en Import-Csv leest een leeg veld. Het script maakt dan accounts zonder afdeling, zonder fout.
  • De tabellen in het script verouderen. Een nieuwe afdeling staat niet in $ouPerAfdeling, en een hernoemde groep geeft een fout bij Add-ADGroupMember terwijl het account wel is aangemaakt. Je hebt dan een half account.
  • Herintreders en dubbele namen. Iemand die terugkomt, heeft een uitgeschakeld account met hetzelfde personeelsnummer. Twee mensen met dezelfde naam krijgen een UPN met een nummer erachter, en niemand weet meer welke regel dat bepaalde.
  • Het draait onder een account met te veel rechten. Een geplande taak met een serviceaccount dat accounts mag aanmaken in alle OU's, en soms een wachtwoord in het script zelf.
  • Er is geen spoor. Het script schrijft een regel naar de console, of naar een logbestand dat niemand bewaart. Vraagt een auditor wie een account heeft aangemaakt en waarom, dan is het antwoord een geplande taak.
  • De bouwer is weg. Het script is van één beheerder. Na twee jaar is die vertrokken of met iets anders bezig, en durft niemand het nog aan te passen.

Een script blijft bruikbaar, zolang je weet waar het ophoudt. Neem vertrek daarbij minstens zo serieus als indiensttreding. Wat er in Entra ID allemaal bij vertrek hoort, staat in offboarding in Entra ID.

Accounts in lokale AD aanmaken via Microsoft Entra

Er is ook een route waarbij Microsoft de accountverwerking doet. Dat neemt een deel van het scriptwerk weg, maar niet alle keuzes over rollen en rechten.

Microsoft heeft voor dit scenario een eigen route: de enterprise-app API-driven provisioning to on-premises Active Directory. Je stuurt de gegevens uit HR naar een endpoint in Microsoft Graph (/bulkUpload), in SCIM-opmaak. De provisioning service in Entra ID vergelijkt die gegevens met wat er in AD staat en bepaalt zelf of een account aangemaakt, bijgewerkt, ingeschakeld of uitgeschakeld moet worden. De Microsoft Entra provisioning agent op een server in je netwerk voert dat uit in Active Directory. Daarna komt het account via Entra Connect Sync of Cloud Sync in Entra ID, zoals elk ander AD-account.

Het verschil met het script: je hoeft niet meer zelf te bepalen of iemand nieuw is of al bestaat. Je stuurt het hele record, en de provisioning service kijkt. Wat je nog wel zelf bouwt, is het stuk dat de export uit HR leest en naar het endpoint stuurt. Hoe dat verzoek eruitziet, staat in API-driven inbound provisioning.

  1. Zorg voor een server met Windows Server 2016 of later die bij je domeincontrollers kan, met minstens 4 GB geheugen en .NET 4.7.1 of later. Microsoft raadt aan deze server als tier 0 te behandelen, net als een domeincontroller. Zet er voor hoge beschikbaarheid een tweede naast.
  2. Ga in het Microsoft Entra-beheercentrum naar Enterprise apps, kies New application en zoek op API-driven. Kies de app voor on-premises Active Directory. Je hebt daarvoor Application Administrator en Hybrid Identity Administrator nodig.
  3. Zet onder Provisioning de modus op Automatic, sla op, download de provisioning agent via de banner en installeer hem. De agent maakt een group managed service account (gMSA) aan voor de verbinding met AD.
  4. Kies je domein en de OU waar nieuwe accounts standaard in komen, test de verbinding en sla op.
  5. Vul onder Settings een e-mailadres voor meldingen in. Zonder dat adres gaat de provisioning in quarantaine zodra je start.
  6. Bekijk de standaardkoppeling van attributen, pas de OU-regel aan (zie hieronder) en start de provisioning. Kopieer het Provisioning API Endpoint voor je eigen script of automatisering.
De OU per afdeling als expressie op parentDistinguishedName, met een standaard-OU als laatste vangnet
Switch([department], "OU=Nieuw,OU=Medewerkers,DC=bedrijf,DC=local",
  "Financien", "OU=Financien,OU=Medewerkers,DC=bedrijf,DC=local",
  "Verkoop",   "OU=Verkoop,OU=Medewerkers,DC=bedrijf,DC=local",
  "Logistiek", "OU=Logistiek,OU=Medewerkers,DC=bedrijf,DC=local")

Microsoft gebruikt parentDistinguishedName met Switch() ook voor een overstap: verandert de afdeling, dan verplaatst de provisioning het account naar de nieuwe OU. Voor een unieke UPN en sAMAccountName heeft de app naar AD de functie SelectUniqueValue, die een reeks regels afloopt tot hij een waarde vindt die nog vrij is.

Wat je moet weten voor je begint
API-driven provisioning naar AD
LicentieMicrosoft Entra ID P1 of hoger voor elke gebruiker die uit HR komt.
Bestaande accounts herkennenStandaard op externalId uit je verzoek tegen employeeId. Is employeeID in AD niet gevuld, vul het dan eerst, anders maakt de provisioning dubbele accounts.
Limieten op het endpoint40 verzoeken per 5 seconden, en per tenant 2.000 verzoeken per 24 uur met P1 of P2, of 6.000 met Entra ID Governance. Tot 50 medewerkers per verzoek.
Vertrekactive op false schakelt het account uit. Verwijderen kan het endpoint niet; Microsoft verwijst daarvoor naar Lifecycle Workflows in Entra ID Governance.
Groepen in ADNiet. Microsoft noemt het toewijzen van AD-groepen in zijn handleidingen voor HR-provisioning naar AD niet ondersteund en raadt een eigen script op de agentserver aan.
Proberen per persoonProvision on demand werkt niet voor deze app.

En als de medewerker ook een mailbox nodig heeft?

In hybride omgevingen is een AD-account alleen niet altijd voldoende. Exchange vraagt soms nog een aparte stap.

Heb je nog een Exchange-server op locatie voor het beheer van je mailboxen in Exchange Online, dan is het AD-account niet het einde. De mailbox hoort dan vanuit Exchange op locatie te worden aangemaakt, zodat die omgeving weet dat de gebruiker een mailbox in de cloud heeft. Daarvoor is Enable-RemoteMailbox: het maakt van een bestaande AD-gebruiker een mail-enabled gebruiker met een kenmerk dat Exchange Online vertelt dat er bij de volgende sync een mailbox moet komen.

In de Exchange Management Shell, nadat het AD-account bestaat
Enable-RemoteMailbox -Identity "jan.jansen" -RemoteRoutingAddress "jan.jansen@bedrijf.mail.onmicrosoft.com"
  • De mailbox is er niet meteen. Hij ontstaat in Exchange Online pas als het account met de Exchange-attributen naar Entra ID is gesynchroniseerd. Wijs de Exchange Online-licentie daarna toe.
  • Licentie te vroeg, dan twee werelden. Krijgt de gebruiker een Exchange Online-licentie voordat de remote mailbox bestaat, dan kan Exchange Online een mailbox maken waar Exchange op locatie niets van weet. Microsoft beschrijft in een apart artikel hoe je herstelt als een mailbox op beide plekken bestaat; voorkomen is eenvoudiger.
  • Het is een aparte stap. Enable-RemoteMailbox bestaat alleen in Exchange op locatie. De provisioning naar AD vult attributen op het gebruikersobject; deze stap blijft dus een script of handwerk ernaast, net als de groepen.

Joinly

Van eerste account tot vertrek, vanuit HR

Een script kan een account aanmaken. Het echte werk begint wanneer iemand van afdeling verandert, andere rechten nodig heeft of vertrekt. Dan moeten AD, groepen en eventueel hybride Exchange weer op elkaar aansluiten.

Joinly gebruikt HR als startpunt voor die wijzigingen. De Joinly Agent voert de benodigde acties in je eigen Active Directory-omgeving uit, zonder inkomende verbindingen vanuit internet. Rollen bepalen welke groepen en andere toegang erbij horen. Daarmee wordt het niet alleen makkelijker om iemand te laten starten, maar ook om wijzigingen en vertrek consequent te verwerken.

De Joinly Agent die een hybride en on-premise Active Directory beheertBekijk Active Directory-automatisering met Joinly

Waar je op kunt rekenen

  • Geen vendor lock-inJe identiteiten en je inrichting blijven van jou.
  • Je data eruit wanneer je wiltJe kunt je gegevens op elk moment exporteren.
  • Standaard SLAOnze standaard SLA is opvraagbaar.
  • Begeleiding bij de implementatieOnze specialisten richten het samen met je in.
  • ISO 27001-gecertificeerdInformatiebeveiliging volgens een internationaal erkende norm.

Van HR naar Active Directory

Veelgestelde vragen

  • Kan Microsoft Entra provisioning AD-groepen vullen?

    Niet bij de provisioning vanuit HR naar Active Directory. Die maakt het account aan en werkt het bij, maar Microsoft noemt het toewijzen van AD-groepen niet ondersteund en raadt een eigen script op de server van de provisioning agent aan.

  • Welke licentie heb ik nodig voor API-driven provisioning naar Active Directory?

    Microsoft Entra ID P1 of hoger, voor elke gebruiker die uit HR komt. Met Entra ID Governance mag je meer verzoeken per dag naar het endpoint sturen: 6.000 in plaats van 2.000.

  • Hoe verplaats ik een account naar een andere OU als iemand van afdeling wisselt?

    Met de hand of in een script met `Move-ADObject`. Gebruik je API-driven provisioning, dan zet je een `Switch()`-expressie op `parentDistinguishedName`; verandert de afdeling, dan verplaatst de provisioning het account naar de bijbehorende OU.

  • Verwijdert API-driven provisioning ook accounts?

    Het endpoint zelf niet: met `active` op false wordt het account uitgeschakeld. Verwijderen na een aantal dagen doe je in Microsoft's eigen route met Lifecycle Workflows uit Entra ID Governance, of met een eigen script.

  • Waarom krijgt een nieuwe medewerker twee mailboxen bij hybride Exchange?

    Meestal omdat de Exchange Online-licentie is toegewezen voordat de remote mailbox op locatie bestond. Maak eerst het AD-account, dan de remote mailbox met `Enable-RemoteMailbox`, wacht op de sync en wijs dan pas de licentie toe.

Probeer Joinly bovenop je eigen Microsoft-omgeving

Rollen, workflows, externen en een auditlog voor Entra ID en Active Directory. Begin met demodata in de gratis proefomgeving.

Geen creditcard, geen installatie.

Liever eerst een gesprek? Praat met een IAM-specialist