Einstieg in Microsoft Graph PowerShell — Microsoft 365 betreiben nach der Abschaltung von AzureAD und MSOnline

· · PowerShell, Microsoft 365, Microsoft Entra ID, Microsoft Graph, Informationssysteme, Automatisierung, Betriebsoptimierung, Sicherheit

Für alle, die den Betrieb von Microsoft 365 automatisieren, war die größte Veränderung zwischen 2024 und 2025 die Abschaltung der Module AzureAD und MSOnline. Nicht wenige IT-Abteilungen hatten ihre Routinearbeiten — Austrittsverarbeitung, Lizenzbestände, Kontoerstellung für neue Mitarbeitende — mit Get-MsolUser oder Get-AzureADUser geschrieben, und diese Skripte hören nach und nach auf zu funktionieren.

Migrationsziel ist das Microsoft Graph PowerShell SDK. Dabei handelt es sich jedoch nicht um ein bloßes Austauschen von Befehlsnamen. Die Grundannahmen des Designs ändern sich: wie die Authentifizierung funktioniert (Scopes und Zustimmung), wie Daten abgerufen werden (OData-Filter und Paging) und wie unbeaufsichtigte Ausführung aufgebaut wird (App-Registrierung und Zertifikate). Wer das ersetzt, ohne dies zu verstehen, handelt sich andere Probleme ein — „es funktioniert, läuft aber mit übermäßigen Berechtigungen“ oder „bei einem großen Mandanten bekommen wir nur einen Teil der Daten“.

Dieser Artikel richtet sich an IT-Mitarbeitende, die den internen Microsoft-365-Betrieb mit PowerShell automatisieren. Er behandelt den Hintergrund der Abschaltungen, Verbindungsaufbau und Scope-Design, die Einrichtung der unbeaufsichtigten Ausführung sowie drei Standardrezepte — Bestandsaufnahme, Lizenzübersicht und Austrittsverarbeitung — in einer praxistauglichen Form.

1. Das Wichtigste zuerst

  • MSOnline und AzureAD wurden am 30. März 2024 als veraltet markiert; MSOnline erreichte am 30. Mai 2025 das Ende der Verfügbarkeit, und AzureAD wurde nach dem Support-Ende am 30. März 2025 abgeschaltet.1
  • Migrationsziel ist das Microsoft Graph PowerShell SDK oder das darauf aufbauende Microsoft Entra PowerShell (allgemein verfügbar seit März 2025). Letzteres ist szenarioorientiert und bietet außerdem Kompatibilitätsoptionen, um die Migration von AzureAD zu erleichtern.2
  • Microsoft.Graph ist ein Metamodul. Die komplette Installation ist schwergewichtig, daher installiert man in der Praxis Microsoft.Graph.Authentication plus nur die Submodule für die genutzten Arbeitslasten.3
  • Verbindungen beginnen mit Connect-MgGraph -Scopes. Halten Sie die Scopes auf das Minimum. Die benötigten Berechtigungen lassen sich mit Find-MgGraphPermission nachschlagen, und zu welchem Modul ein Befehl gehört, mit Find-MgGraphCommand.45
  • Unbeaufsichtigte Ausführung bedeutet reine App-Authentifizierung mit App-Registrierung plus Zertifikat. Verbinden Sie sich ohne Interaktion über -ClientId, -TenantId und -CertificateThumbprint. Ein Zertifikat wird gegenüber einem Client-Secret empfohlen.46
  • Delegierte und Anwendungsberechtigungen (App-only) sind unterschiedliche Dinge. Der für dieselbe Operation erforderliche Scope ändert sich, sodass beim Umstieg auf unbeaufsichtigte Ausführung die Berechtigungen neu vergeben werden müssen.6
  • Für Listen -All, für Eingrenzung -Filter, für Felder -Property verwenden. Eine clientseitige Eingrenzung mit Where-Object führt zu unnötigem Abruf und Drosselung.7
  • Umfangreiche Zugriffe werden gedrosselt. Bei einer 429-Antwort lautet die offizielle Empfehlung, gemäß Retry-After zu warten.8
  • App-Registrierungen nach Verwendungszweck trennen. Eine einzelne „App für alles“ häuft Berechtigungen an und vergrößert im Ernstfall den Schaden.

2. Der Hintergrund der Abschaltungen, und was jetzt zu wählen ist

Zunächst die Fakten.1

Modul Status
MSOnline (Get-MsolUser usw.) Am 30. März 2024 als veraltet markiert. Am 30. Mai 2025 abgeschaltet
AzureAD (Get-AzureADUser usw.) Am 30. März 2024 als veraltet markiert. Support-Ende am 30. März 2025, danach abgeschaltet
Microsoft Graph PowerShell SDK Aktuell. Die Graph-API direkt in Cmdlets umgesetzt
Microsoft Entra PowerShell Allgemein verfügbar seit März 2025. Ein szenarioorientiertes Modul, aufgebaut auf dem Graph SDK2

Hier die Richtlinie, welches Modul zu wählen ist. Wer die Struktur der Graph-API direkt nutzen oder eine breite Palette von Arbeitslasten (Exchange, Teams, Intune usw.) anfassen möchte, verwendet das Graph PowerShell SDK. Wer sich hauptsächlich auf die Identitätsverwaltung in Entra ID (früher Azure AD) konzentriert und die Migration vom AzureAD-Modul möglichst schmerzfrei gestalten möchte, verwendet Microsoft Entra PowerShell. Letzteres arbeitet mit dem Graph PowerShell SDK zusammen und bietet zudem Rückwärtskompatibilitätsoptionen, die die Migration vom AzureAD-Modul unterstützen.2

Dieser Artikel orientiert sich am Graph PowerShell SDK, das universeller einsetzbar und besser dokumentiert ist.

3. Installation — das Metamodul nicht komplett installieren

Microsoft.Graph ist ein Metamodul, das eine große Zahl von Submodulen bündelt. Die komplette Installation ist sowohl beim Installieren als auch beim Laden schwergewichtig, und je nach Ausführungsumgebung kann allein das Laden mehrere zehn Sekunden dauern.3

# [Schwergewichtig] Alle Arbeitslasten installieren
Install-Module Microsoft.Graph -Scope CurrentUser

# [Praxisnah] Authentifizierung plus nur die genutzten Arbeitslasten installieren
Install-Module Microsoft.Graph.Authentication -Scope CurrentUser   # Zwingend erforderlich
Install-Module Microsoft.Graph.Users          -Scope CurrentUser   # Benutzer
Install-Module Microsoft.Graph.Groups         -Scope CurrentUser   # Gruppen
Install-Module Microsoft.Graph.Identity.DirectoryManagement -Scope CurrentUser  # Lizenzen usw.
Install-Module Microsoft.Graph.Users.Actions  -Scope CurrentUser   # Aktionen für Benutzer
                                                                   # (Revoke-MgUserSignInSession usw.)

# Ermitteln, zu welchem Modul ein Befehl gehört und welche Berechtigungen er benötigt
Find-MgGraphCommand -Command Get-MgUser | Select-Object Module, Permissions -First 1
Find-MgGraphPermission user.read -PermissionType Delegated

Die Verwendung mit PowerShell 7 wird empfohlen. Es funktioniert auch mit Windows PowerShell 5.1, aber hier gibt es sowohl aus Leistungs- als auch aus Zukunftsfähigkeitsgründen gute Gründe für 7 (siehe „Die Unterschiede zwischen Windows PowerShell 5.1 und PowerShell 7“).3

4. Verbindung und Scopes — Schluss mit „einfach mal ReadWrite.All“

Der interaktive Verbindungsaufbau erfolgt über Connect-MgGraph -Scopes. Für die angegebenen Scopes erscheint ein Zustimmungsbildschirm, und das Ergebnis dieser Zustimmung wird im Mandanten gespeichert.4

# Nur lesender Zugriff für eine Bestandsaufnahme. Keine Schreibberechtigungen anfordern
Connect-MgGraph -Scopes 'User.Read.All', 'Organization.Read.All' -NoWelcome

Get-MgContext | Format-List Account, TenantId, Scopes, AuthType   # Aktuelle Verbindung prüfen
Disconnect-MgGraph

Hier zeigt sich bei der Migration der größte Unterschied. In der Ära von Get-MsolUser galt „mit einem Administratorkonto anmelden, und man kann alles“ — bei Graph dagegen ist der benötigte Scope je Operation definiert, und es funktioniert nur innerhalb des Bereichs, dem zugestimmt wurde. Das ist keine Einschränkung, sondern eine Sicherheitsvorkehrung. Ein Bestandsaufnahme-Skript kann nicht versehentlich schreiben, wenn nur .Read.All zugestimmt wurde.

Es gelten drei Grundsätze.

  • Für rein lesende Zwecke keine Schreib-Scopes anfordern (reicht User.Read.All, dann nicht User.ReadWrite.All anfordern)
  • App-Registrierungen nach Verwendungszweck trennen (eine für Bestandsaufnahmen, eine für Kontoerstellung, eine für Lizenzverwaltung)
  • Die Zustimmung soll ein Administrator bewusst erteilen (einmal erteilte Zustimmung bleibt im Mandanten erhalten)

Wenn Sie nicht wissen, welchen Scope Sie benötigen, suchen Sie mit Find-MgGraphPermission nach Kandidaten und prüfen Sie mit Find-MgGraphCommand, welche Berechtigungen ein Befehl erfordert.5

5. Unbeaufsichtigte Ausführung — App-Registrierung plus Zertifikat

Läuft das Skript jede Nacht über die Aufgabenplanung, scheidet die interaktive Anmeldung aus. Wechseln Sie zur reinen App-Authentifizierung mit App-Registrierung (Dienstprinzipal) und Zertifikat.6

Das Grundgerüst des Verfahrens ist wie folgt.

  1. Eine App im Microsoft Entra Admin Center registrieren
  2. Nur die minimal notwendigen Anwendungsberechtigungen (Application permissions) hinzufügen und die Administratorzustimmung erteilen
  3. Ein Zertifikat erstellen, den öffentlichen Schlüssel in die App-Registrierung hochladen und den privaten Schlüssel im Zertifikatspeicher des ausführenden Kontos ablegen
  4. Aus dem Skript heraus mit -CertificateThumbprint verbinden
# Verbindung für unbeaufsichtigte Ausführung (ohne Interaktion)
$connect = @{
    ClientId              = '11111111-2222-3333-4444-555555555555'
    TenantId              = '66666666-7777-8888-9999-000000000000'
    CertificateThumbprint = 'A1B2C3D4E5F6...'    # Ein Zertifikat im Speicher des ausführenden Kontos
    NoWelcome             = $true
}
Connect-MgGraph @connect

try {
    # Fachliche Verarbeitung
}
finally {
    Disconnect-MgGraph
}

Zwei Punkte sind zu beachten.

(1) Delegiert und App-only benötigen unterschiedliche Berechtigungen. Wenn Sie ein Skript, das interaktiv mit -Scopes 'User.Read.All' funktioniert hat, unbeaufsichtigt machen, müssen Sie auf Seiten der App-Registrierung dieselbe Art von Berechtigung erneut als Anwendungsberechtigung vergeben, mit Administratorzustimmung.6

(2) Zertifikate laufen ab. Dass der nächtliche Batch am Tag des Zertifikatsablaufs komplett ausfällt, ist tatsächlich ein häufiger Unfall. Tragen Sie das Ablaufdatum in einen Kalender ein und dokumentieren Sie das Erneuerungsverfahren. Zur sicheren Aufbewahrung von Anmeldeinformationen siehe auch „Anmeldeinformationen in PowerShell sicher handhaben“. Sie können sich auch mit einem Client-Secret verbinden, aber wegen des Risikos, es im Klartext herumzureichen, und der Umständlichkeit der Ablaufverwaltung wird ein Zertifikat empfohlen.

6. Daten abrufen — -All / -Filter / -Property

Graph ist eine API, die auf Paging aufbaut. Standardmäßig kommt nur eine Seite zurück; wenn Sie alles benötigen, fügen Sie -All hinzu.7

# [Schlecht] Paging ignorieren und clientseitig filtern (langsam, holt zu viel, verursacht Drosselung)
Get-MgUser | Where-Object { $_.Department -eq 'Sales' }

# [Gut] Serverseitig filtern, nur benötigte Felder abrufen und alle Seiten abholen
Get-MgUser -All -Filter "department eq 'Sales'" `
           -Property Id, DisplayName, UserPrincipalName, AccountEnabled, Department |
    Select-Object DisplayName, UserPrincipalName, AccountEnabled

Hier sind drei Punkte wichtig.

  • -Filter ist ein OData-Ausdruck und grenzt serverseitig ein. Where-Object grenzt lokal ein, das heißt, es wird alles abgerufen und der Großteil anschließend verworfen
  • Das Eingrenzen der Spalten mit -Property macht die Antwort leichter. Manche Eigenschaften, die standardmäßig nicht zurückgegeben werden, erhält man, wenn man sie explizit benennt
  • Mit -Property abgerufene Felder müssen auch in Select-Object stehen. Abruf und Anzeige sind getrennt, sodass bei Angabe nur eines von beiden Leerstellen entstehen

Für fortgeschrittene Abfragen wie startsWith oder endsWith, oder wenn nur die Anzahl benötigt wird, kombinieren Sie -ConsistencyLevel eventual mit -CountVariable.7

# Nur die Anzahl der aktivierten Benutzer zählen (Anzahl ohne vollständigen Abruf ermitteln)
Get-MgUser -Filter 'accountEnabled eq true' -ConsistencyLevel eventual -CountVariable total -Top 1 | Out-Null
"Aktivierte Benutzer: $total"

Umfangreiche Zugriffe werden gedrosselt und liefern HTTP 429. Die offizielle Empfehlung lautet: „Warten Sie die in der Kopfzeile Retry-After angegebene Sekundenzahl ab, bevor Sie erneut versuchen.“8 Die Cmdlets des SDK führen intern bereits eine gewisse Anzahl von Wiederholungen durch, aber wenn Sie Schleifen über Tausende von Elementen ausführen, ist es zuverlässiger, von vornherein die Anzahl der Abrufe zu reduzieren (Eingrenzung mit -Filter und -Property, benötigte Informationen in einem einzigen Aufruf abholen). Zum Retry-Design selbst siehe „Fehlerbehandlung und Retry-Design in PowerShell“.

7. Drei Standardrezepte

(1) Einen Benutzerbestand als CSV exportieren

# SignInActivity (Zeitpunkt der letzten Anmeldung) lässt sich nicht allein mit User.Read.All abrufen;
# AuditLog.Read.All ist zusätzlich erforderlich. Wird es nicht erfasst, aus -Property entfernen
Connect-MgGraph -Scopes 'User.Read.All', 'AuditLog.Read.All' -NoWelcome

$users = Get-MgUser -All -Property Id, DisplayName, UserPrincipalName, AccountEnabled,
                              Department, JobTitle, CreatedDateTime, SignInActivity |
    Select-Object DisplayName, UserPrincipalName, Department, JobTitle, AccountEnabled,
                  @{ n = 'Created'; e = { $_.CreatedDateTime } },
                  # Für die Beurteilung von Inaktivität "erfolgreiche Anmeldungen" verwenden. LastSignInDateTime ist der
                  # "Versuch" einer interaktiven Anmeldung, schließt Fehlschläge ein und nicht-interaktive Anmeldungen aus
                  @{ n = 'LastSuccessfulSignIn'; e = { $_.SignInActivity.LastSuccessfulSignInDateTime } },
                  @{ n = 'LastInteractiveSignInAttempt'; e = { $_.SignInActivity.LastSignInDateTime } },
                  @{ n = 'LastNonInteractiveSignIn'; e = { $_.SignInActivity.LastNonInteractiveSignInDateTime } }

# Eine CSV mit Nicht-ASCII-Text wird in Excel nicht falsch dargestellt, wenn sie als UTF-8 mit BOM geschrieben wird.
# Der Kodierungsname unterscheidet sich je nach Version: utf8BOM ab 7+, UTF8 (mit BOM) bei 5.1
$enc = if ($PSVersionTable.PSVersion.Major -ge 6) { 'utf8BOM' } else { 'UTF8' }
$users | Export-Csv -Path "D:\Inventory\users_$(Get-Date -f yyyyMMdd).csv" -Encoding $enc -NoTypeInformation

SignInActivity eignet sich gut, um inaktive Konten aufzuspüren. Wichtig ist jedoch, auf welches Feld Sie schauen. LastSignInDateTime erfasst Versuche einer interaktiven Anmeldung (einschließlich Fehlschlägen) und schließt nicht-interaktive Anmeldungen durch Apps oder Dienste aus. Wer allein danach urteilt, kann ein Konto, bei dem ein Angreifer erfolglos einzudringen versucht hat, für „in Benutzung“ halten, oder ein tatsächlich aktiv laufendes Dienstkonto für „inaktiv“. Verwenden Sie für die Beurteilung von Inaktivität LastSuccessfulSignInDateTime, das erfolgreiche interaktive und nicht-interaktive Anmeldungen widerspiegelt.9 Beachten Sie jedoch, dass sich allein diese Eigenschaft nicht mit User.Read.All abrufen lässt — zusätzlich ist AuditLog.Read.All erforderlich (dazu kommen Lizenzanforderungen auf Seiten des Mandanten). Bei unzureichenden Berechtigungen erhalten Sie entweder einen Fehler oder einen leeren Wert; entfernen Sie das Feld daher aus -Property, wenn Sie es nicht nutzen. Die benötigten Berechtigungen lassen sich mit Find-MgGraphPermission prüfen.9 Der Umgang mit der Zeichenkodierung von CSV-Dateien wird in „Excel- und CSV-Geschäftsaufgaben mit PowerShell automatisieren“ behandelt.

(2) Lizenzverbrauch zusammenfassen

Connect-MgGraph -Scopes 'Organization.Read.All' -NoWelcome

Get-MgSubscribedSku | Select-Object `
    SkuPartNumber,
    @{ n = 'Purchased'; e = { $_.PrepaidUnits.Enabled } },
    @{ n = 'Assigned';  e = { $_.ConsumedUnits } },
    @{ n = 'Available'; e = { $_.PrepaidUnits.Enabled - $_.ConsumedUnits } } |
    Sort-Object Available

„Wir haben zusätzliche Lizenzen gekauft, obwohl noch welche übrig waren“ und „die Lizenzen von Ausgeschiedenen wurden nie freigegeben“ lassen sich beide verhindern, indem man dies einfach monatlich ausführt.

(3) Austrittsverarbeitung (Anmeldung sperren und Sitzungen widerrufen)

# Dies beinhaltet Schreibvorgänge, daher unter einer eigenen App-Registrierung mit eigenen Scopes ausführen.
# Wird -ClientId weggelassen, erfolgt die Verbindung über die standardmäßige gemeinsame App des SDK, und die
# zugestimmten Berechtigungen häufen sich auf dieser App an (die organisationsweit geteilt wird). Gerade bei
# destruktiven Vorgängen wie der Austrittsverarbeitung sollten Berechtigungen in einer eigenen App-Registrierung
# isoliert werden
#
# Die benötigte Berechtigung unterscheidet sich je Operation, daher beide Operationen zusammen anfordern
#   Ändern von accountEnabled       -> User.EnableDisableAccount.All (minimale Berechtigung)
#   Widerrufen von Anmeldesitzungen -> User.RevokeSessions.All (minimale Berechtigung)
# Beides lässt sich auch mit User.ReadWrite.All erledigen, das gewährt jedoch weiterreichende Berechtigungen
$connect = @{
    ClientId  = '99999999-aaaa-bbbb-cccc-dddddddddddd'   # Eigene App-Registrierung für die Austrittsverarbeitung
    TenantId  = '66666666-7777-8888-9999-000000000000'
    Scopes    = 'User.Read.All', 'User.EnableDisableAccount.All', 'User.RevokeSessions.All'
    NoWelcome = $true
}
Connect-MgGraph @connect

# Revoke-MgUserSignInSession erfordert Microsoft.Graph.Users.Actions
Import-Module Microsoft.Graph.Users.Actions

$upn = 'taro.yamada@example.co.jp'
$user = Get-MgUser -UserId $upn -Property Id, DisplayName, AccountEnabled

# 1. Anmeldung sperren (die Löschung erfolgt später, nach einer Übergangsfrist)
Update-MgUser -UserId $user.Id -AccountEnabled:$false

# 2. Aktualisierungstoken und Browser-Sitzungscookies widerrufen
#    Hinweis: bereits ausgestellte Zugriffstoken können bis zu ihrem Ablauf weiter nutzbar bleiben (siehe unten)
Revoke-MgUserSignInSession -UserId $user.Id

Write-Host "Anmeldung für $($user.DisplayName) gesperrt"

Hier sind drei Dinge zu verinnerlichen. Erstens, mit welcher App-Registrierung Sie sich verbinden. Lässt man -ClientId weg, erfolgt die Verbindung über die standardmäßige App des Microsoft Graph PowerShell SDK, und die zugestimmten Berechtigungen werden gegen diese App gespeichert, die organisationsweit geteilt wird. Um den Grundsatz „App-Registrierungen nach Verwendungszweck trennen“ aus Abschnitt 4 in die Praxis umzusetzen, müssen Sie mit -ClientId Ihre eigene App-Registrierung benennen.4

Zweitens die Scopes. Bei Graph ist die benötigte Berechtigung je Operation definiert — „ich kann Benutzer schreiben, also kann ich alles“ funktioniert nicht. Das Ändern von accountEnabled und das Widerrufen von Anmeldesitzungen besitzen jeweils eigene Berechtigungen mit minimalem Umfang; stimmen Sie nur einer davon zu und führen das Skript aus, gelingt zwar die Verbindung, aber ein Befehl in der Mitte scheitert mit einem Fehler wegen unzureichender Berechtigung. Prüfen Sie die für jede Operation erforderlichen Berechtigungen mit Find-MgGraphPermission und in der Berechtigungstabelle der jeweiligen Graph-API-Referenz.1011

Und drittens genügen bei delegierter Ausführung die Scopes allein nicht. Führen Sie dies wie oben als Sie selbst angemeldet aus, benötigt das Ändern von accountEnabled zusätzlich eine Microsoft-Entra-Administratorrolle. Der Grund ist, dass eine delegierte Berechtigung nur festlegt, „was die App im Namen dieses Benutzers tun darf“ — sie hebt nicht die eigenen Berechtigungen des angemeldeten Benutzers an. Haben Sie der Berechtigung zugestimmt, fehlt aber die Rolle, scheitert die Ausführung mit einem 403. Die Dokumentation nennt Privileged Authentication Administrator als die Rolle mit dem geringsten Umfang, die diese Eigenschaft für alle Administratoren im Mandanten aktualisieren kann, und legt allgemeiner fest, dass eine höherrangige Administratorrolle als die des Ziels erforderlich ist.10 Da sich die benötigte Rolle danach unterscheidet, ob es sich beim Ausscheidenden um einen gewöhnlichen Benutzer oder einen Administrator handelt, sollten Sie vorab festlegen, was den Konten des Betriebsteams zugewiesen wird. Auch bei der zertifikatsbasierten reinen App-Ausführung gilt: Ist das Ziel ein Administrator, benötigt die App selbst eine zugewiesene höhere Administratorrolle.10

Sie müssen außerdem genau verstehen, was Revoke-MgUserSignInSession bewirkt. Was dieser Befehl ungültig macht, sind Aktualisierungstoken und Browser-Sitzungscookies; bereits ausgestellte Zugriffstoken können bis zu ihrem Ablauf weiter nutzbar bleiben.11 Wird eine sofortige Sperrung benötigt, setzt dies voraus, dass die beteiligten Anwendungen und Ressourcen die kontinuierliche Zugriffsauswertung (Continuous Access Evaluation, CAE) unterstützen. Gehen Sie nicht davon aus, dass „ich habe widerrufen, also stoppt jeder Zugriff sofort“ — kombinieren Sie es in wichtigen Fällen mit der Deaktivierung des Kontos und berücksichtigen Sie die Verzögerung bis zur Wirksamkeit.

Das Konto nicht sofort löschen, sondern zunächst die Anmeldung sperren — das ist die praktische Regel. Löschen Sie, bevor die Übergabe von Postfach und OneDrive abgeschlossen ist, wird die Wiederherstellung mühsam. Für diese Art unwiderruflicher Vorgänge ist es sicherer, sie in eine eigene, -WhatIf-fähige Funktion einzupacken und die Liste der Ziele vor der Ausführung zur Prüfung auszugeben (siehe „Parameterdesign und Modularisierung in PowerShell“).

8. Praktische Faustregeln (Entscheidungstabelle)

Frage Optionen Richtlinie
Modul Graph SDK / Entra PowerShell Entra bei Fokus auf Identitätsverwaltung und Migration von AzureAD; das Graph SDK für eine breite Palette an Arbeitslasten2
Installation Alles / Nur Submodule Je Submodul, um Startzeit und Abhängigkeiten gering zu halten3
Authentifizierung (interaktiv) Dem Administratorkonto überlassen / Minimale Scopes Bestandsaufnahmen benötigen nur .Read.-Berechtigungen. Die Zustimmung bleibt im Mandanten erhalten4
Authentifizierung (unbeaufsichtigt) Client-Secret / Zertifikat Zertifikat empfohlen. Ablaufverwaltung und Erneuerungsverfahren vorab festlegen6
Berechtigungsgranularität Eine App für alles / Eine App-Registrierung je Verwendungszweck Begrenzt den Schaden im Ernstfall
Auflistung Where-Object / -Filter + -All + -Property Serverseitig eingrenzen. Die abgerufene Menge bestimmt unmittelbar Geschwindigkeit und Stabilität7
Umgang mit 429 Sofort erneut versuchen / Retry-After befolgen Offizielle Empfehlung. Zuerst die Anzahl der Anfragen reduzieren8
Gefährliche Vorgänge Direkt ausführen / -WhatIf + Zielliste vorab prüfen Austrittsverarbeitung und Massenlöschung müssen die Ziele stets sichtbar machen

9. Zusammenfassung

  • MSOnline und AzureAD sind abgeschaltet. Migrationsziel ist das Microsoft Graph PowerShell SDK oder das darauf aufbauende Microsoft Entra PowerShell.
  • Microsoft.Graph ist ein Metamodul, daher installiert man in der Praxis Authentifizierung plus nur die Submodule für die genutzten Arbeitslasten.
  • Die Minimierung der Scopes ist der Grundsatz beim Verbindungsaufbau. Fordern Sie für Bestandsaufnahmen keine Schreibberechtigungen an und trennen Sie App-Registrierungen nach Verwendungszweck.
  • Unbeaufsichtigte Ausführung bedeutet App-Registrierung plus Zertifikat. Dass delegiert und App-only unterschiedliche Berechtigungen benötigen und dass Zertifikate ablaufen, sind beides typische Unfallquellen.
  • Der Datenabruf besteht aus dem Dreiklang -All (Paging), -Filter (serverseitige Eingrenzung) und -Property (Beschränkung der Felder). Bei 429 befolgen Sie Retry-After.
  • Allein das monatliche Ausführen der drei Rezepte — Bestandsaufnahme, Lizenzübersicht und Austrittsverarbeitung — reduziert die beiden häufigsten Risiken, verschwendete Lizenzen und vergessene Konten, erheblich.

Beispielcode zum Download

Der in diesem Artikel behandelte Code ist in direkt ausführbarer Form gepackt. Er umfasst den Verbindungsaufbau, das Ermitteln inaktiver Konten, die Lizenzübersicht und die Austrittsverarbeitung.

Beispielcode herunterladen (zip)

Da diese Beispiele von Windows und einem Mandanten abhängen, wurden sie nicht durch tatsächliche Ausführung verifiziert. Syntaxprüfung und statische Analyse mit PSScriptAnalyzer wurden für alle Dateien durchgeführt, bitte bestätigen Sie das Verhalten jedoch unbedingt auf Ihrer eigenen Testmaschine.

# Syntaxprüfung + statische Analyse (läuft auch unter Nicht-Windows)
./Invoke-SampleTests.ps1

Die Konfigurationswerte (Pfade, Servernamen, Mandanten-IDs usw.) sind Beispiele. Führen Sie sie nicht unverändert in einer Produktivumgebung aus — passen Sie sie an Ihre eigene Umgebung an.

Verwandte Artikel

Verwandte Beratungsbereiche

Die KomuraSoft LLC übernimmt die Migration von Microsoft-365-Betriebsskripten zu Graph, die Überprüfung von App-Registrierung und Berechtigungsdesign sowie die Automatisierung von Routinearbeiten wie Bestandsaufnahmen und Austrittsverarbeitung.

  1. Microsoft Community Hub (Microsoft Entra Blog), Action required: MSOnline and AzureAD PowerShell retirement - 2025 info and resources. Dazu, dass sowohl das MSOnline- als auch das AzureAD-PowerShell-Modul am 30. März 2024 als veraltet markiert wurden, dass die Abschaltung von MSOnline im Frühjahr 2025 mit Ende der Verfügbarkeit am 30. Mai 2025 durchgeführt wurde, dass AzureAD am 30. März 2025 aus dem Support genommen und danach abgeschaltet wurde, und dass Migrationsziele das Microsoft Graph PowerShell SDK und Microsoft Entra PowerShell sind.  2

  2. Microsoft Learn, What is Microsoft Entra PowerShell?. Dazu, dass Microsoft Entra PowerShell ein szenarioorientiertes Modul ist, das auf dem Microsoft Graph PowerShell SDK aufbaut, zu seiner Interoperabilität mit den Cmdlets des Graph PowerShell SDK und zu seinen Rückwärtskompatibilitätsoptionen zur Unterstützung der Migration vom AzureAD-Modul. Die GA-Ankündigung ist Microsoft Entra PowerShell module now generally available (März 2025).  2 3 4

  3. Microsoft Learn, Install the Microsoft Graph PowerShell SDK. Dazu, dass Microsoft.Graph ein Metamodul ist, das eine Gruppe von Submodulen enthält, zur Möglichkeit, nur die benötigten Submodule einzeln zu installieren, dazu, dass Microsoft.Graph.Authentication für die Authentifizierung zwingend erforderlich ist, sowie zu den unterstützten PowerShell-Versionen.  2 3 4

  4. Microsoft Learn, Connect-MgGraph. Zur Anforderung delegierter Berechtigungen mit -Scopes, zur reinen App-Authentifizierung mit -ClientId / -TenantId / -CertificateThumbprint, zur Prüfung der aktuellen Verbindungsinformationen mit Get-MgContext und zum Trennen mit Disconnect-MgGraph.  2 3 4 5

  5. Microsoft Learn, Find Microsoft Graph PowerShell commands and permissions. Zur Suche nach dem zugehörigen Modul, den erforderlichen Berechtigungen und der entsprechenden API eines Befehls mit Find-MgGraphCommand sowie zur Suche nach Berechtigungsnamen mit Find-MgGraphPermission.  2

  6. Microsoft Learn, Use app-only authentication with the Microsoft Graph PowerShell SDK. Zum Verfahren der App-Registrierung, der Anwendungsberechtigung und der Administratorzustimmung, zur Konfiguration der unbeaufsichtigten Authentifizierung mit einem Zertifikat und zum Unterschied zwischen delegierten Berechtigungen und Anwendungsberechtigungen.  2 3 4 5

  7. Microsoft Learn, Paging Microsoft Graph data in your app. Dazu, dass Antworten von Microsoft Graph seitenweise geliefert werden, dass die Angabe von -All im PowerShell SDK alle Seiten abruft, zur serverseitigen Eingrenzung mit -Filter / -Property (entsprechend $filter und $select) sowie zu -ConsistencyLevel eventual mit Anzahlermittlung bei fortgeschrittenen Abfragen.  2 3 4

  8. Microsoft Learn, Microsoft Graph throttling guidance. Dazu, dass ressourcenbezogene Drosselung HTTP 429 zurückgibt, zur Notwendigkeit, die im Retry-After-Header der Antwort angegebene Sekundenzahl abzuwarten, bevor erneut versucht wird, sowie zur Empfehlung, das Design so zu gestalten, dass von vornherein weniger Anfragen gestellt werden.  2 3

  9. Microsoft Learn, signInActivity resource type. Dazu, dass sowohl die Berechtigung AuditLog.Read.All als auch User.Read.All erforderlich sind, um die Eigenschaft signInActivity eines Benutzers abzurufen, zu den Lizenzanforderungen des Mandanten sowie dazu, dass lastSignInDateTime interaktive Anmeldeversuche (einschließlich Erfolg und Fehlschlag) darstellt, während lastSuccessfulSignInDateTime erfolgreiche interaktive und nicht-interaktive Anmeldungen und lastNonInteractiveSignInDateTime nicht-interaktive Anmeldungen darstellt.  2

  10. Microsoft Learn, Update user (Microsoft Graph API). Dazu, dass die für die Aktualisierung eines Benutzers erforderlichen Berechtigungen je Eigenschaft definiert sind, wobei User.EnableDisableAccount.All als Berechtigung mit dem geringsten Umfang für das Ändern von accountEnabled genannt wird und auch das umfassendere User.ReadWrite.All dies ausführen kann. Außerdem dazu, dass delegierte Szenarien zusätzlich zum passenden Scope eine Microsoft-Entra-Administratorrolle erfordern, dass Privileged Authentication Administrator die Rolle mit dem geringsten Umfang ist, die accountEnabled für alle Administratoren im Mandanten aktualisieren kann, dass allgemein eine höherrangige Administratorrolle als die des Ziels erforderlich ist, und dass auch bei reinen App-Szenarien eine höherrangige Administratorrolle für die App zugewiesen sein muss, wenn das Ziel ein Administrator ist.  2 3

  11. Microsoft Learn, user: revokeSignInSessions (Microsoft Graph API). Dazu, dass User.RevokeSessions.All als Berechtigung mit dem geringsten Umfang für das Widerrufen von Anmeldesitzungen genannt wird, dass eine Administratorzustimmung erforderlich ist, und dass sich die Ungültigmachung auf Aktualisierungstoken und Browser-Sitzungscookies bezieht, während bereits ausgestellte Zugriffstoken bis zu ihrem Ablauf weiter nutzbar bleiben können (wobei die kontinuierliche Zugriffsauswertung für eine sofortige Durchsetzung relevant ist).  2

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Kann ich das AzureAD-Modul oder das MSOnline-Modul nicht mehr verwenden?
Richtig — beide sind abgeschaltet. Die Module MSOnline und AzureAD wurden am 30. März 2024 als veraltet (deprecated) markiert; MSOnline erreichte am 30. Mai 2025 das Ende der Verfügbarkeit, und AzureAD wurde am 30. März 2025 aus dem Support genommen und danach abgeschaltet. Auch wenn Sie noch Skripte haben, die scheinbar funktionieren, können diese jederzeit aufhören zu arbeiten. Migrationsziel ist das Microsoft Graph PowerShell SDK oder das darauf aufbauende Microsoft Entra PowerShell-Modul (allgemein verfügbar seit März 2025).
Die Installation des Microsoft.Graph-Moduls ist schwergewichtig. Kann ich das verschlanken?
Ja. Microsoft.Graph ist ein Metamodul mit einer großen Zahl darunterliegender Submodule, sodass die Installation des gesamten Pakets sowohl beim Installieren als auch beim Laden viel Zeit kostet. In der Praxis ist es sinnvoll, nur die Submodule für die tatsächlich genutzten Arbeitslasten zu installieren: Microsoft.Graph.Users für die Benutzerverwaltung, Microsoft.Graph.Groups für Gruppen und das für die Authentifizierung zwingend erforderliche Microsoft.Graph.Authentication. Zu welchem Modul ein bestimmter Befehl gehört, lässt sich mit Find-MgGraphCommand ermitteln.
Ich möchte dies über die Aufgabenplanung unbeaufsichtigt ausführen, erhalte aber eine interaktive Anmeldeaufforderung.
Wechseln Sie zur reinen App-Authentifizierung mit einer App-Registrierung (Dienstprinzipal) und einem Zertifikat. Registrieren Sie eine App in Microsoft Entra ID, erteilen Sie für die benötigten Anwendungsberechtigungen die Administratorzustimmung, und übergeben Sie anschließend -ClientId, -TenantId und -CertificateThumbprint an Connect-MgGraph, um sich ohne jede Interaktion zu verbinden. Ein Zertifikat ist sicherer als ein Client-Secret, und die Verwaltung des Ablaufdatums ist eindeutiger. Legen Sie das Zertifikat im Zertifikatspeicher des ausführenden Kontos ab und legen Sie unbedingt ein Verfahren fest, um es vor Ablauf zu erneuern.
Was sollte ich bei -Scopes von Connect-MgGraph angeben?
Geben Sie nur die minimalen Berechtigungen an, die die auszuführenden Befehle tatsächlich benötigen. Was erforderlich ist, lässt sich mit Find-MgGraphPermission oder der Dokumentation des jeweiligen Befehls prüfen; für reine Lesezugriffe genügt eine Berechtigung im .Read.-Stil wie User.Read.All. Geht es um einen Bestand oder ein Audit, fordern Sie keine Schreibberechtigungen an. Einmal erteilte Zustimmung wird im Mandanten gespeichert, sodass ein „einfach mal Directory.ReadWrite.All zustimmen“ zu einem künftigen Risiko wird. Es ist sicherer, App-Registrierungen nach Verwendungszweck zu trennen und die Berechtigungen entsprechend aufzuteilen.
Wenn ich Get-MgUser gegen einen Mandanten mit vielen Benutzern verwende, bekomme ich nur einen Teil der Liste.
Weil Antworten von Microsoft Graph seitenweise (paged) geliefert werden. Mit -All werden automatisch alle Seiten durchlaufen. Zusätzlich kann eine umfangreiche Abfrage gedrosselt (throttled) werden und eine 429-Antwort liefern, daher gilt als Grundregel, mit -Property nur die benötigten Felder abzurufen und die Filterung serverseitig über OData (-Filter) statt clientseitig über Where-Object vorzunehmen. Wird nur die Anzahl benötigt, lässt sich diese über die Kombination aus -ConsistencyLevel eventual und -CountVariable ermitteln, ohne alle Datensätze abzurufen.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog