Tobias Schmidt
Alle Beiträge

Inaktive AD-Konten finden und sauber deaktivieren

2 Min. Lesezeit #PowerShell#Active Directory

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: LastLogonDate basiert auf dem Attribut lastLogonTimestamp. 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.