Opschalen: paginering, throttling en audits van grote tenants in Microsoft 365
By Mirko Peters ·
Welkom terug op de blog! Als je een grote Microsoft 365-omgeving beheert, weet je al dat de standaard rapportagetools maar het oppervlak aanstippen…
Automatically translated with AI from the original post. Read the English original
Welkom terug op de blog! Als je een enorme Microsoft 365-omgeving beheert, weet je al dat de standaardrapportagetools je nauwelijks iets laten zien. Wanneer security-teams en compliance-officers grote tenants bekijken, falen eenvoudige scripts en standaardweergaven in het beheercentrum gewoon onder het gewicht van duizenden gebruikers, groepen en bestanden. Een audit van grote Microsoft 365-tenants vraagt om meer dan basisscripts; het vraagt om een tactische, geprogrammeerde aanpak met de Microsoft Graph API. In deze uitgebreide gids bouwen we rechtstreeks voort op ons recente gesprek in de podcastaflevering Map Microsoft 365 Users, Groups, Files, and Shares with Graph. Laten we diep ingaan op hoe je @odata.nextLink-paginering afhandelt, 429-limieten respecteert met exponentiële backoff en veelvoorkomende valkuilen zoals Page 1 bias vermijdt, zodat je volledig zicht op je tenant krijgt.
Inleiding tot de uitdagingen bij M365-audits
Bedrijfsomgevingen groeien organisch. Gebruikers komen en gaan, projecten zetten van de ene op de andere dag afdelingen op en externe leveranciers worden uitgenodigd in samenwerkingsruimtes. Na verloop van tijd neemt het administratieve overzicht af. Standaardbeheercentra tonen losse fragmenten van je infrastructuur, waardoor blinde vlekken ontstaan die kwaadwillenden of onachtzame insiders kunnen misbruiken. Om een echt beeld te krijgen van de beveiligingspositie van je tenant, moet je overstappen van handmatige point-and-click-audits naar geautomatiseerde, API-gedreven graph-traversal. Maar het opschalen van deze query's naar enterprise-formaat brengt complexe obstakels met zich mee, zoals enorme datapayloads, agressieve throttling en diep geneste relationele structuren.
Waarom M365 niet op zichzelf staat: inzicht in relationele toegang
Een van de fundamentele kenmerken van Microsoft 365 is dat diensten als SharePoint, Teams en OneDrive geen geïsoleerde silo's zijn. Ze beïnvloeden elkaar voortdurend via groepslidmaatschappen en onderliggende toegangscontrolelijsten (ACL's). Eén beheeractie, zoals het toevoegen van een gebruiker aan een beveiligingsgroep, kan doorwerken naar tientallen teamsites, documentbibliotheken en privékanalen, zonder dat er in standaardweergaven een duidelijk auditspoor achterblijft.
Dit creëert verborgen compliancerisico's. Gastlinks die in geïsoleerde chats zijn gedeeld, bestanden die in verschillende teambibliotheken zijn gespiegeld en verweesde shares van lang geleden afgeronde projecten vormen onzichtbare routes naar je bedrijfsdata. Toegang in M365 is fundamenteel relationeel en niet locatiegebonden. Om effectief te kunnen auditen moet je die opeenvolgende relaties in kaart brengen, in plaats van elke dienst als een op zichzelf staand eiland te behandelen.
Footprintmapping met Graph Explorer
Voordat je automatisering op enterprise-schaal schrijft, moet je handmatig leren hoe je de footprint van een gebruiker traceert met Graph Explorer. Door je queries stap voor stap op te bouwen, weet je zeker dat je logica klopt voordat je regels code schrijft. Hier is het blauwdruk voor het in kaart brengen van de contactpunten van een gebruiker:
- Verankeren op de gebruiker: begin met het ophalen van het kernobject van de gebruiker via GET /v1.0/users/{userPrincipalName}?$select=id,displayName,userPrincipalName.
- Lidmaatschappen opsommen: haal de groepen en rollen op die aan die identiteit zijn gekoppeld via GET /v1.0/users/{id}/memberOf?$select=id,displayName.
- Terugpivoteren naar de resources van die groepen: voor Microsoft 365-groepen en Teams richt je je op de onderliggende SharePoint-site via GET /v1.0/groups/{groupId}/drive/root/children?$select=id,name,lastModifiedDateTime,webUrl, of je somt de sitedrives direct op via GET /v1.0/sites/{siteId}/drives.
- Itemmachtigingen en links ophalen: controleer de toegang tot afzonderlijke bestanden met GET /v1.0/drives/{driveId}/items/{itemId}/permissions?$select=id,grantedToV2,link,roles,shareId.
- Nagaan wie wat heeft geopend: correleer gebruikersacties met aanmeldingslogboeken of beveiligingswaarschuwingen, gekoppeld aan bestands- en sitecontext.
- Sluit de lus met Teams-berichten: zoek in kanaalberichten naar specifieke bestandsverwijzingen via GET /v1.0/teams/{teamId}/channels/{channelId}/messages?$search="filename" (houd rekening met de bètamachtigingen en -vereisten).
Ruisonderdrukkende filters die je echt gaat gebruiken
Het opvragen van Microsoft Graph zonder filters is een snelle weg naar een overbelaste systeem met datastromen. Om echte risico's naar boven te halen, heb je precieze filterstrategieën nodig. Hier zijn de querypatronen die je moet inzetten:
- Externe deelacties in de afgelopen 7 dagen: richt je op anonieme of organisatiebrede links met GET /v1.0/drives/{driveId}/items/{itemId}/permissions?$filter=link/scope eq 'anonymous' or link/scope eq 'organization'.
- Alleen risicovolle bestandstypen: voeg filters toe zoals $filter=endsWith(resourceReference/name,'.xlsm') of endsWith(resourceReference/name,'.pst') om macro's en archieven op te sporen.
- Vermeldingen van gevoelige termen buiten kantooruren in Teams: zoek in kanaalberichten naar termen zoals confidential en filter de resultaten daarna op aanmaaktijdstempels buiten de normale werktijden.
- Houd je payloads beperkt: neem altijd $select-parameters op zodat alleen de noodzakelijke identifiers, namen, URL's en tijdstempels worden teruggegeven.
- Limiet voor triage: gebruik $top=50 voor snelle steekproeven, maar verwijder deze parameter wanneer je volledige exports naar je datastore uitvoert.
Enterprise-scale verplichtingen: paginering en throttling
Bij audits over een tenant met honderdduizenden objecten loop je vast als je scripts geen rekening houden met API-limieten en paginering. Je bent pas klaar met het ophalen van gegevens als je voor elke pagina die de API teruggeeft de eigenschap @odata.nextLink volgt. Als je dit negeert, legt je script alleen de eerste batch resultaten vast en mis je de rest van je tenant.
Daarnaast moet je HTTP 429-responses voor snelheidslimieten respecteren. Implementeer robuuste exponentiële backoff-logica zodat je script pauzeert, de afkoelperiode uitzit en naadloos verdergaat waar het gebleven was. Bundel je requests slim door te kiezen voor minder, grotere logische requests en door group-to-site-mappings te cachen. Voor zeer grote tenants partitioneer je je crawls op site of datumbereik en plan je ze buiten kantooruren, zodat de productieprestaties niet worden beïnvloed.
Veelvoorkomende valkuilen en snelle oplossingen
Zelfs ervaren beheerders lopen tegen obstakels aan wanneer ze M365-audits opschalen. Dit zijn de meest voorkomende valkuilen en hoe je ze oplost:
- Valkuil: CSV-exports lopen uit de pas naarmate schema's na verloop van tijd veranderen. Oplossing: gebruik de Graph API rechtstreeks met versiegebonden transformaties en verwerk onbekende velden op een nette manier.
- Valkuil: gemengde identifiers, zoals GUID's versus User Principal Names, breken databasekoppelingen. Oplossing: normaliseer alles naar een helder semantisch model met Users, Groups, Sites, Drives, Items en Permissions.
- Valkuil: paginabias verbergt het merendeel van de beveiligingsincidenten die dieper in de resultatenset zitten. Oplossing: registreer altijd het totale aantal verwerkte pagina's en configureer waarschuwingen als het verwachte datavolume plotseling daalt.
- Valkuil: stromen irrelevante bestanden overbelasten de verwerkingsengines. Oplossing: pas strikte filters toe op deelscopes, tijdvensters en lijsten met gevoelige termen.
- Valkuil: Teams-deelacties staan los van de onderliggende bestanden. Oplossing: koppel de web-URL's van kanaalberichten rechtstreeks aan drive-items en sla beide identifiers samen op.
Executive-KPI's die hiermee mogelijk worden
Technische data is alleen waardevol als je die kunt vertalen naar bruikbare business-intelligence voor het management. Het opzetten van een geautomatiseerde Graph-auditpipeline levert krachtige executive-KPI's op:
- Snelheid van externe blootstelling: meet hoeveel nieuwe gastlinks per week worden aangemaakt, uitgesplitst naar site en team.
- Aanraakpercentage van gevoelige bestanden: volg het aantal unieke kijkers op gelabelde content, met een onderscheid tussen interne gebruikers en externe gasten.
- Groepsrimpelrisico: meet bestanden die binnen 24 uur na grote wijzigingen in groepslidmaatschappen nieuw toegankelijk zijn.
- Schaduwcirculatie: houd bij hoe gevoelige bestanden binnen één sprint in meerdere teams of sites opduiken.
- Effectiviteit van opschoning: volg het aantal ingetrokken links en de tijd tot herstel in de loop van de tijd.
Quick-start querybundel
Als je klaar bent om je eigen verzamelpipeline op te zetten, gebruik dan deze kopieer-en-plakflow om direct aan de slag te gaan:
- Haal kerngegevens van gebruikers en hun lidmaatschappen op: /users/{upn}?$select=id,displayName en /users/{id}/memberOf?$select=id,displayName.
- Zoek voor elke M365-groep de driveitems op: /groups/{groupId}/drive/root/children?$select=id,name,webUrl,lastModifiedDateTime&$top=200, en volg daarbij @odata.nextLink.
- Haal voor elk item de machtigingen op: /drives/{driveId}/items/{itemId}/permissions?$select=id,roles,grantedToV2,link, en filter op anonieme of organisatiebrede scopes.
- Exporteer de rijen naar je eigen datastore en leg daarbij tenanttijd, site-ID's, drive-ID's, item-ID's, web-URL's, eigenaren, scopes en vervaldetails vast.
- Visualiseer je genormaliseerde data in Power BI voor executive- en operationele dashboards.
Van deze opzet een levend dashboard maken
Een audit die je één keer uitvoert, is een momentopname; een audit die je continu uitvoert, is een beveiligingsprogramma. Om ruwe Graph-aanroepen om te zetten in een levend dashboard, laad je je gegevens via Power Dataflows in genormaliseerde tabellen voor Users, Groups, Sites, Drives, Items, Permissions en Messages. Modelleer je gegevens met een sterrenschema met Items in het midden, met heldere relaties naar Users en Groups.
Configureer incrementele verversingen op basis van de velden lastModifiedDateTime en draai updates meerdere keren per dag voor sites met een hoog risico. Stel tot slot automatische waarschuwingen in die afgaan wanneer er nieuwe externe links verschijnen op gelabelde inhoud, of wanneer pieken in group-ripple wijzen op ongeautoriseerde uitbreiding van toegang.
Uitrolplan van 30 dagen
Rome is ook niet in één dag gebouwd, en een auditraamwerk voor een grote organisatie vraagt om zorgvuldige fasering. Volg dit uitrolplan van 30 dagen voor een soepele implementatie:
Week 1: Registreer je Azure-app, ken Graph API-machtigingen met de minste rechten toe en maak je eerste baseline-queries met de parameters $select en $filter.
Week 2: Ontwikkel je paginatiescripts, normaliseer identifiers naar consistente UPN's en apparaatnamen, en voer je eerste volledige end-to-end export uit.
Week 3: Bouw je Power BI-datamodel en configureer kernprestatie-indicatoren zoals externe blootstelling, ripple-risico en de doorlooptijd van ontdekking tot intrekking (dwell-to-revoke).
Week 4: Automatiseer de dataverversingen, implementeer anomaliewaarschuwingen en documenteer standaardwerkprocedures voor je team dat beveiligingsonderzoeken uitvoert.
Voor wie dit interessant is
Dit raamwerk is speciaal ontworpen voor M365-beheerders en SecOps-leads die vermoeden dat hun groene dashboards grijze gebieden verbergen, voor compliance-teams die end-to-end zicht op delen nodig hebben zonder wildgroei aan tools van derden, en voor collaboration owners die verantwoordelijk zijn voor veilige externe deelpraktijken.
Praktische tips
Houd bij het uitrollen van deze scripts in de praktijk de volgende snelle tips in gedachten: begin je onderzoeken altijd bij de gebruiker of het bestand en pivoteer dan in beide richtingen om blinde vlekken weg te nemen. Behandel elke gebeurtenis waarbij iemand aan een groep wordt toegevoegd als een wijziging met hoog risico en controleer de toegang die daaruit voortvloeit binnen 24 uur. Houd een actuele shortlist bij van gevoelige termen om te zoeken in bestandsnamen en Teams-berichten. Noteer tot slot zorgvuldig je paginatellingen en resultaatvolumes, want stilte van een script is vaak een teken van een kapotte taak en niet van een schone tenant.
Conclusie
Paginatie beheersen, rate limits respecteren en vermijden dat je alleen naar pagina 1 kijkt, zijn essentiële vaardigheden voor iedereen die een grote Microsoft 365-tenant moet beveiligen. Door verder te gaan dan standaard beheerconsoles en de volledige programmatische kracht van de Microsoft Graph API te benutten, maak je onzichtbare deelrisico's om in duidelijke, meetbare beveiligingsinzichten.
Voor diepere duiken, codevoorbeelden en praktijkvoorbeelden met Graph kun je ons volledige gesprek in de podcast beluisteren. Bekijk de bijbehorende aflevering en lees alle details op Map Microsoft 365 Users, Groups, Files, and Shares with Graph. Blijf veilig, blijf automatiseren, en tot in de volgende aflevering!