Ein Konto, das seit Monaten niemand nutzt, bindet eine Lizenz und behält seine Gruppenmitgliedschaften samt Freigaben. Übernimmt ein Angreifer so ein Konto, meldet sich niemand beim Helpdesk, weil es den Benutzer nicht mehr gibt. Entra ID speichert pro Konto drei Anmeldezeitstempel.
Welchen du abfragst, entscheidet, ob dein Bericht die verwaisten Konten findet oder ausgerechnet die ältesten übersieht.
Voraussetzungen
Die Anmeldeaktivität steckt in der Graph-Eigenschaft signInActivity, und Microsoft koppelt sie an eine Premium-Lizenz. Fehlt im Tenant Microsoft Entra ID P1 oder P2, quittiert Graph die Abfrage mit dem Fehler Authentication_RequestFromNonPremiumTenantOrB2CTenant ("Neither tenant is B2C or tenant doesn't have premium license"). Dein Skript bricht damit ab, bevor es eine einzige Zeile schreibt.
P1 ist in Microsoft 365 Business Premium, E3, F1 und F3 enthalten, P2 in Microsoft 365 E5. Tenants mit Business Basic oder Business Standard ohne Zusatzlizenz greifen auf den Nutzungsbericht im Microsoft 365 Admin Center zurück (Abschnitt weiter unten).
Für den Bericht brauchst du keine Schreibrechte, deshalb reicht die Rolle Reports Reader. Sie ist die Rolle mit den geringsten Rechten, die Anmeldeberichte lesen darf.
- Lizenz: Microsoft Entra ID P1 oder P2
- Rolle: Reports Reader (Security Reader, Global Reader, Security Administrator und Global Administrator funktionieren ebenfalls)
- Graph-Berechtigungen:
User.Read.AllundAuditLog.Read.All - Modul:
Microsoft.Graph.Users(aktuell 2.40.0, veröffentlicht am 16.09.2026)
Entra schreibt die Zeitstempel gebündelt. Microsoft nennt bis zu 24 Stunden Verzögerung. Für eine 90-Tage-Auswertung spielt das keine Rolle, für die Kontrolle eines Offboardings am selben Tag schon.
Den richtigen Zeitstempel wählen
signInActivity enthält drei Datumswerte, die sich in einem Punkt unterscheiden: ob ein Fehlversuch zählt.
| Eigenschaft | Was sie erfasst | Stolperfalle |
| lastSignInDateTime | letzter interaktiver Anmeldeversuch, erfolgreich oder fehlgeschlagen | Fehlversuche, etwa aus Password Spray, lassen ein ungenutztes Konto aktiv aussehen |
| lastNonInteractiveSignInDateTime | letzter Versuch eines Clients, sich im Namen des Benutzers anzumelden (Token-Erneuerung), erfolgreich oder fehlgeschlagen | nur zusammen mit dem interaktiven Wert aussagekräftig |
| lastSuccessfulSignInDateTime | letzte erfolgreiche Anmeldung, interaktiv oder nicht interaktiv | erst seit 01.12.2023 befüllt, ältere Anmeldungen hat Microsoft nicht nachgetragen |
Für einen Inaktivitätsbericht zählt lastSuccessfulSignInDateTime, weil nur dieser Wert belegt, dass jemand das Konto erfolgreich benutzt hat. Die Einschränkung steckt im Startdatum.
Ein leerer Wert bedeutet deshalb nicht "unbekannt", sondern: Seit dem 1. Dezember 2023, also seit fast drei Jahren, gab es keine erfolgreiche Anmeldung, oder es gab nie eine. Wer leere Werte aus dem Bericht filtert, wirft genau die Konten hinaus, die am längsten brachliegen.
Entra Admin Center Filter nutzen
Melde dich mit der Rolle Reports Reader am Microsoft Entra Admin Center an und öffne Entra ID > Users. Über Manage view > Edit columns fügst du mit + Add column die Spalte Last interactive sign-in time hinzu und speicherst die Ansicht.

Danach setzt du über Add filter einen Filter auf Last interactive sign-in time, wählst den Operator <= (less than or equal to) und als Datum einen Stichtag in der Vergangenheit. Für 90 Tage Inaktivität ist das der Tag heute vor 90 Tagen. Ein Datum in der Zukunft liefert dagegen jedes Konto, das sich je angemeldet hat, weil jede Anmeldung vor diesem Datum liegt. Microsoft empfiehlt eine Schwelle von 90 bis 180 Tagen, abhängig von der Organisation.


Der Portalweg hat zwei Schwächen. Er vergleicht nur den interaktiven Zeitstempel, zählt also Fehlversuche mit und meldet Benutzer als inaktiv, die seit Wochen nur über im Hintergrund erneuerte Tokens arbeiten. Und Konten ohne jeden Zeitstempel bieten dem Datumsfilter keinen Vergleichswert, sie prüfst du separat.
Für den Export gibt es zwei Varianten. Der klassische Button Download users schreibt einen festen Attributsatz ohne Anmeldedaten in die CSV. Erst die Vorschau-Variante Download users (Preview) übernimmt die Spalten deiner Ansicht und damit auch die Anmeldezeitstempel. Für einen Bericht, den du regelmäßig ziehst und archivierst, nimmst du trotzdem PowerShell, weil nur dort der Erfolgsstempel und eine reproduzierbare Logik zusammenkommen.
Konto per PowerShell prüfen
Beim Verbinden forderst du beide Scopes an. Ohne AuditLog.Read.All liefert Graph die Anmeldeaktivität nicht aus.
Connect-MgGraph -Scopes 'User.Read.All','AuditLog.Read.All'Für ein einzelnes Konto löst Graph signInActivity nur über die Objekt-ID auf. Übergibst du den UPN an -UserId und fragst die Anmeldeaktivität mit an, quittiert Graph das mit "Get By Key only supports UserId and the key has to be a valid Guid". Deshalb holst du zuerst die ID:
$user = Get-MgUser -UserId 'max.mustermann@contoso.de'
Get-MgUser -UserId $user.Id -Property id,displayName,signInActivity |
Select-Object -ExpandProperty SignInActivity |
Format-List Last*DateTime
Die Ausgabe zeigt alle drei Zeitstempel in UTC. Liegt LastSignInDateTime deutlich nach LastSuccessfulSignInDateTime, gab es danach nur noch Fehlversuche.
Alle inaktiven Konten per Skript ermitteln
Das Skript bewertet jedes Konto nach lastSuccessfulSignInDateTime. Konten ohne diesen Wert bleiben im Bericht und bekommen einen eigenen Status. KeinErfolgSeit2023 bekommt ein Konto mit Anmeldeversuchen, aber ohne erfolgreiche Anmeldung seit Beginn der Erfassung. NieAngemeldet bekommt ein Konto ganz ohne Zeitstempel.
Konten, die jünger als die Schwelle sind, überspringt das Skript, weil sonst jeder Neuzugang, der erst nächste Woche anfängt, als NieAngemeldet im Bericht steht. Microsoft nutzt eine vergleichbare Schonfrist bei den Access Reviews für inaktive Gäste und nimmt dort frisch angelegte Konten aus. Die Spalte VersuchNachStichtag markiert Konten mit Anmeldeversuchen nach dem Stichtag, aber ohne Erfolg. Auf einem Konto, das niemand mehr nutzt, deutet das auf Password Spray oder auf ein vergessenes Gerät mit altem Kennwort hin.
Die Seitengröße steht auf 500, weil Graph beim Abruf von signInActivity maximal 500 Objekte pro Seite liefert. Gegenüber dem Standard von 100 braucht ein Tenant mit 10.000 Konten damit 20 statt 100 Anfragen.
#Requires -Modules Microsoft.Graph.Users
# Voraussetzung: Connect-MgGraph -Scopes 'User.Read.All','AuditLog.Read.All'
param(
[int]$Tage = 90,
[string]$Pfad = '.\inaktive-konten.csv'
)
# Entra liefert alle Anmeldezeitstempel in UTC, deshalb rechnet der Stichtag ebenfalls in UTC
$stichtag = (Get-Date).ToUniversalTime().AddDays(-$Tage)
$eigenschaften = 'id', 'displayName', 'userPrincipalName', 'userType', 'accountEnabled',
'createdDateTime', 'onPremisesSyncEnabled', 'assignedLicenses', 'signInActivity'
# 500 ist die maximale Seitengröße, sobald signInActivity abgefragt wird
$benutzer = Get-MgUser -All -PageSize 500 -Property $eigenschaften
$ergebnis = foreach ($u in $benutzer) {
# Neue Konten bekommen eine Schonfrist, sonst erscheint jeder Neuzugang als NieAngemeldet
if ($u.CreatedDateTime -and $u.CreatedDateTime -gt $stichtag) { continue }
$aktivitaet = $u.SignInActivity
$erfolg = $aktivitaet.LastSuccessfulSignInDateTime
# Jüngster Anmeldeversuch, interaktiv oder nicht, erfolgreich oder fehlgeschlagen
$versuch = @($aktivitaet.LastSignInDateTime, $aktivitaet.LastNonInteractiveSignInDateTime) |
Where-Object { $_ } | Sort-Object -Descending | Select-Object -First 1
if ($erfolg) {
if ($erfolg -ge $stichtag) { continue } # aktiv, nicht berichten
$status = 'Inaktiv'
}
elseif ($versuch) {
# Versuche vorhanden, aber kein Erfolg seit Beginn der Erfassung am 01.12.2023
$status = 'KeinErfolgSeit2023'
}
else {
$status = 'NieAngemeldet'
}
[pscustomobject]@{
Anzeigename = $u.DisplayName
UPN = $u.UserPrincipalName
Typ = $u.UserType
Aktiviert = $u.AccountEnabled
Synchronisiert = [bool]$u.OnPremisesSyncEnabled
Lizenziert = (($u.AssignedLicenses | Measure-Object).Count -gt 0)
Status = $status
LetzterErfolg = $erfolg
LetzterVersuch = $versuch
VersuchNachStichtag = [bool]($versuch -and $versuch -ge $stichtag)
Angelegt = $u.CreatedDateTime
}
}
$ergebnis = @($ergebnis)
Write-Host ("{0} Konten geprüft, {1} ohne erfolgreiche Anmeldung seit {2:yyyy-MM-dd}" -f
@($benutzer).Count, $ergebnis.Count, $stichtag) -ForegroundColor Cyan
# Semikolon und UTF-8 mit BOM, damit Excel mit deutschen Regionseinstellungen Spalten und Umlaute sauber einliest
# PowerShell 7: utf8BOM, Windows PowerShell 5.1: UTF8
$ergebnis | Sort-Object Status, LetzterErfolg |
Export-Csv -Path $Pfad -NoTypeInformation -Delimiter ';' -Encoding utf8BOM
Speichere das Skript als Get-InaktiveKonten.ps1 und rufe es mit der gewünschten Schwelle auf:
.\Get-InaktiveKonten.ps1 -Tage 180 -Pfad .\inaktive-konten-180.csv
Treffer einordnen
Die CSV liefert Kandidaten, gelöscht wird erst nach Prüfung. Vier Spalten entscheiden, wie du mit einem Treffer umgehst.
Typ = Guest gehört in den Gastprozess, weil Gäste über Einladung und Access Reviews verwaltet werden und nicht über das Offboarding der Personalabteilung. Synchronisiert = True deaktivierst du im lokalen Active Directory. Objekte aus der Verzeichnissynchronisierung lassen sich in Entra ID nicht direkt verwalten, die Änderung muss aus dem AD DS kommen und per Sync nach oben laufen.
Aktiviert = True mit Status NieAngemeldet trifft häufig die Benutzerkonten hinter Shared Mailboxes. Microsoft verlangt, die Anmeldung für diese Konten zu blockieren und blockiert zu lassen. Ein solcher Treffer ist deshalb ein eigener Befund, unabhängig von der Inaktivität. Notfallkonten (Break Glass) melden sich planmäßig selten an und landen zuverlässig im Bericht. Nimm sie namentlich aus jeder automatischen Sperre heraus.
Für Cloud-Konten sperrst du zuerst die Anmeldung und widerrufst danach die Refresh Tokens. Genau diese Kombination beschreibt Microsoft für den Entzug von Zugriffen: Anschließend bekommt das Konto keine neuen Tokens mehr, bereits ausgestellte Access Tokens laufen nach standardmäßig einer Stunde ab. Bis der Widerruf greift, können einige Minuten vergehen.
Connect-MgGraph -Scopes 'User.Read.All','User.EnableDisableAccount.All','User.RevokeSessions.All'
Update-MgUser -UserId $user.Id -AccountEnabled:$false
Revoke-MgUserSignInSession -UserId $user.IdErst nach einer Wartefrist, in der sich niemand beschwert, entfernst du Lizenzen und löschst das Konto. Gelöschte Benutzer liegen 30 Tage im Papierkorb von Entra ID und lassen sich samt Lizenzen wiederherstellen, danach ist das Konto endgültig weg.
Ohne Entra ID P1: Nutzungsbericht im Microsoft 365 Admin Center
Ohne P1 bleibt dir der Nutzungsbericht. Öffne im Microsoft 365 Admin Center Reports > Usage, wähle unter Reports Microsoft 365 apps und dann den Tab Active users. Die Tabelle zeigt pro Benutzer das letzte Aktivitätsdatum für Exchange, OneDrive, SharePoint, Viva Engage und Microsoft Teams, auswählbar für 7, 30, 90 oder 180 Tage. Die Rolle Reports Reader reicht auch hier.

Der Bericht misst die Nutzung der Dienste statt der Anmeldungen und hinkt 24 bis 48 Stunden hinterher. Mehr als 180 Tage Rückblick gibt er nicht her. Seit dem 1. September 2021 blendet Microsoft Benutzernamen in diesen Berichten standardmäßig anonymisiert ein. Die Klarnamen schaltet ein Global Administrator unter Settings > Org settings > Services > Reports frei, indem er Conceal user, group, and site names in all reports deaktiviert. Weil der Bericht dann Nutzungsdaten einzelner Beschäftigter zeigt, klärst du das vorher mit Datenschutz und Betriebsrat.

Suche automatisieren
Ein Bericht, den du einmal im Jahr ziehst, findet Konten, die elf Monate offen standen. Mit Microsoft Entra ID Governance oder der Entra Suite übernehmen Lifecycle Workflows diese Arbeit: Der Trigger Sign-in inactivity wertet lastSuccessfulSignInDateTime aus und startet nach der eingestellten Zahl inaktiver Tage die hinterlegten Aufgaben, etwa Send email about user inactivity, Disable user account oder Revoke all refresh tokens for user.
Für Gäste bietet dieselbe Lizenz unter ID Governance > Dashboard > Guest access governance eine Übersicht inaktiver Gäste. Access Reviews können inaktive Gäste zunächst 30 Tage blockieren und danach aus dem Tenant entfernen.
Ohne Governance-Lizenz planst du das Skript als monatliche Aufgabe mit App-Registrierung und Zertifikat. Die Application Permissions User.Read.All und AuditLog.Read.All reichen für den Lesezugriff.
Fazit
Inaktive Konten findest du in Entra ID zuverlässig, wenn du lastSuccessfulSignInDateTime abfragst und die Lücken dieses Werts kennst. Der Filter im Admin Center ist für einen schnellen Blick brauchbar, arbeitet aber mit dem interaktiven Zeitstempel. Der zählt Fehlversuche mit und blendet Benutzer aus, die nur über Token-Erneuerung aktiv sind. Ein Konto, auf das ein Angreifer per Password Spray zielt, sieht im Portal deshalb aktiver aus als ein Konto, dessen Besitzer nur noch über erneuerte Tokens arbeitet.
Der gefährlichste Fehler in Inaktivitätsskripten ist das stille Aussortieren leerer Werte. Weil Microsoft den Erfolgsstempel erst seit Dezember 2023 erfasst, markieren leere Werte die Konten mit dem längsten Stillstand: ohne erfolgreiche Anmeldung seit fast drei Jahren oder ganz ohne Anmeldung. Wer sie filtert, erzeugt einen Bericht, der sauber aussieht und die riskantesten Konten verschweigt.
Beim Aufräumen zählt die Reihenfolge. Sperren und Sitzungen widerrufen schließt die Angriffsfläche sofort, Lizenz entfernen und Löschen folgen nach einer Wartefrist, weil das 30-Tage-Fenster für die Wiederherstellung sonst schnell verstreicht. Synchronisierte Konten bearbeitest du im lokalen AD, Notfallkonten nimmst du aus jeder Automatik heraus.
Die Lizenzfrage bleibt der Haken. Ohne P1 liefert Graph keine Anmeldeaktivität, und der Nutzungsbericht ersetzt sie nur grob, weil er Dienstnutzung statt Anmeldungen misst und nach 180 Tagen endet. Wer Business Standard betreibt, sollte das beim nächsten Lizenzgespräch als Argument für Business Premium oder für P1 als Einzellizenz mitnehmen. Und wer Governance-Lizenzen hat, sollte die Suche einem Lifecycle Workflow übergeben, weil ein Workflow nicht vergisst, den Bericht zu ziehen.
Sei der Erste und starte die Diskussion mit einem hilfreichen Beitrag.
Kommentar hinterlassen
Dein Beitrag wird vor der Veröffentlichung kurz geprüft — fachlich, respektvoll und auf den Punkt ist hier genau richtig.