Inaktive AD-Konten finden und sauber deaktivieren
In jedem Active Directory sammeln sich mit der Zeit Konten, die niemand mehr nutzt: ausgeschiedene Mitarbeiter, alte Testkonten, Praktikanten von vor drei Jahren. Jedes davon ist ein mögliches Einfallstor. Hier zeige ich, wie ich solche Konten regelmäßig aufräume.
Schritt 1: Kandidaten finden
Das Modul ActiveDirectory bringt mit Search-ADAccount schon alles mit, was wir brauchen:
Import-Module ActiveDirectory
$tage = 90
$inaktiv = Search-ADAccount -AccountInactive -TimeSpan "$tage.00:00:00" -UsersOnly |
Where-Object { $_.Enabled } |
Get-ADUser -Properties LastLogonDate, Description, Department |
Select-Object Name, SamAccountName, LastLogonDate, Department, Description
$inaktiv | Sort-Object LastLogonDate | Format-Table -AutoSize
Achtung:
LastLogonDatebasiert auf dem AttributlastLogonTimestamp. Das wird nur alle 9 bis 14 Tage zwischen den Domänencontrollern repliziert. Für eine Grenze von 90 Tagen ist das völlig ausreichend, für eine Woche nicht.
Schritt 2: Ausnahmen beachten
Nicht jedes Konto ohne Anmeldung ist überflüssig. Typische Ausnahmen:
- Dienstkonten, unter denen Dienste oder geplante Aufgaben laufen
- Notfall- und Break-Glass-Konten
- Konten von Mitarbeitern in Elternzeit oder Langzeiterkrankung
Ich pflege dafür eine eigene Gruppe GG_AD_Cleanup_Ausnahmen und filtere deren Mitglieder heraus:
$ausnahmen = Get-ADGroupMember 'GG_AD_Cleanup_Ausnahmen' -Recursive |
Select-Object -ExpandProperty SamAccountName
$kandidaten = $inaktiv | Where-Object { $_.SamAccountName -notin $ausnahmen }
Schritt 3: Erst exportieren, dann handeln
Bevor irgendetwas geändert wird, landet die Liste als CSV im Archiv. So lässt sich später nachvollziehen, wer wann deaktiviert wurde.
$datum = Get-Date -Format 'yyyy-MM-dd'
$kandidaten | Export-Csv "D:\Reports\AD-Cleanup_$datum.csv" -NoTypeInformation -Encoding UTF8 -Delimiter ';'
Schritt 4: Deaktivieren und verschieben
Gelöscht wird bei mir nichts sofort. Die Konten werden deaktiviert, mit einem Vermerk versehen und in eine eigene OU verschoben. Erst nach weiteren 90 Tagen ohne Rückfrage folgt das Löschen.
$ziel = 'OU=Deaktiviert,DC=firma,DC=local'
foreach ($k in $kandidaten) {
Disable-ADAccount -Identity $k.SamAccountName -WhatIf
Set-ADUser -Identity $k.SamAccountName -Description "Deaktiviert am $datum (inaktiv > $tage Tage)" -WhatIf
Get-ADUser $k.SamAccountName | Move-ADObject -TargetPath $ziel -WhatIf
}
Mit -WhatIf zeigt PowerShell nur an, was passieren würde. Erst wenn die Ausgabe passt, entferne ich den Schalter.
Fazit
| Schritt | Zweck |
|---|---|
| Suchen | Kandidaten nach Inaktivität ermitteln |
| Filtern | Dienst- und Sonderkonten ausnehmen |
| Exportieren | Nachweis für Audit und Rückfragen |
| Deaktivieren | Risiko sofort entfernen, umkehrbar |
Als geplante Aufgabe einmal im Monat ausgeführt, bleibt das AD dauerhaft sauber, ohne dass jemand daran denken muss.