• Active Directory
    • AD Consulting
    • AD Design
      • Domain Name festlegen
      • Domain Struktur einrichten
      • Forest Struktur definieren
    • AD Management
    • AD Automation
      • Dynamic Access Control (DAC)
    • AD Federation Services
      • ADFS Betrieb
      • ADFS und Office365
      • ADFS und Cisco Unified Communications Manager
      • SAML und ADFS 2.0
  • Azure / M365
    • Azure AD
    • Microsoft 365 (O365)
  • Migration
    • Active Directory Migration
    • Exchange Migration
    • File Server Migration
    • Lotus Notes Migration
    • Novell Migration
  • Wissen
    • Alle Beiträge
    • Administration
    • PowerShell
    • Migration
    • Exchange
    • Tools
  • Kontakt
    • Wir über uns
    • Kontakt
  • EN
info@firstattribute.com
by FirstAttribute
Active Directory FAQActive Directory FAQ
  • Active Directory
    • AD Consulting
    • AD Design
      • Domain Name festlegen
      • Domain Struktur einrichten
      • Forest Struktur definieren
    • AD Management
    • AD Automation
      • Dynamic Access Control (DAC)
    • AD Federation Services
      • ADFS Betrieb
      • ADFS und Office365
      • ADFS und Cisco Unified Communications Manager
      • SAML und ADFS 2.0
  • Azure / M365
    • Azure AD
    • Microsoft 365 (O365)
  • Migration
    • Active Directory Migration
    • Exchange Migration
    • File Server Migration
    • Lotus Notes Migration
    • Novell Migration
  • Wissen
    • Alle Beiträge
    • Administration
    • PowerShell
    • Migration
    • Exchange
    • Tools
  • Kontakt
    • Wir über uns
    • Kontakt
  • EN

badPwdCount und badPasswordTime mit PowerShell korrekt auslesen

Sep 18, 2017 (Letztes Update) | Posted by Steve König PowerShell |

 

badPwdCount und badPasswordTime mit PowerShell korrekt auslesen

Interessant ist es für viele Administratoren, das Anmeldeverhalten ihrer Nutzer nachverfolgen zu können. Besonders, wann und wie oft sich jemand mit einem falschen Passwort versucht hat anzumelden, kann dabei Aufschluss darüber geben, ob es sich wirklich um ein vergessenes Passwort handelt, oder ob jemand versucht, mittels Brute Force oder anderer Methoden auf das Active Directory zuzugreifen.

Inhaltsverzeichnis

  • 1 Last Interactive Logon
  • 2 badPwdCount und badPasswordTime
  • 3 Die Domain-Controller abfragen
  • 4 Die richtigen Werte ausrechnen
  • 5 Die Ausgabe formatieren
  • 6 Zusammenfassung & komplettes Skript

Wenn zum Beispiel der Nutzer sich seit vier Tagen nicht mehr angemeldet hat, der letzte fehlgeschlagene Anmeldungsversuch allerdings weniger als vier Tage zurückliegen sollte, liegt die Vermutung nahe, dass hier etwas nicht stimmt und eventuell sogar ein Angriff vorliegt.

Doch wie liest man diese Daten richtig aus? Das ist leider gar nicht so einfach, wie man sich das vielleicht vorstellt. Der Grund dafür ist, dass diese Daten zwar vom Active Directory mitgeloggt werden, jedoch nicht zwischen den verschiedenen Domain Controllern in der Domäne repliziert werden.

Last Interactive Logon

Bevor es an das Skripten geht, möchte ich noch kurz auf eine Möglichkeit hinweisen, die das ganze etwas einfacher machen kann. Seit Windows Server 2008 bietet Microsoft die Option des „Last Interactive Logon“ an, um diese Anmeldeaktivitäten am Nutzer-Objekt zu loggen, die auch über mehrere DCs repliziert werden. Mehr Informationen dazu finden Sie in folgendem Technet-Artikel.

Allerdings gibt es da zwei Rahmenbedingungen, die Sie zu beachten haben: Zum einen muss Ihr Domain Functional Level mindestens auf Windows Server 2008 sein. Zum anderen werden bei der Anmeldung an einem PC in Ihrer Domäne Login Informationen über die letztens Logins angezeigt (siehe Screenshot unten). Die Funktion kann über Gruppenrichtlinien in Ihrer Domäne aktiviert werden.

badPwdCount und badPasswordTime

badPwdCount und badPasswordTime

Wenn Sie das nicht wollen, gibt es aber auch eine Möglichkeit, ohne diese Funktion auszukommen. Logon-Informationen werden vom AD bereits geloggt, und zwar in den Attributen badPwdCount (Fehlgeschlagene Anmeldeversuche) und badPasswordTime (Zeitpunkt der letzten falschen Anmeldung). Das Problem ist, diese werden nur am jeweiligen DC an das Nutzerobjekt geschrieben, an dem der Nutzer versucht hat, sich anzumelden.

Trotzdem lässt sich das über PowerShell recht einfach zuverlässig auslesen. Nur können wir nicht einfach den Wert auslesen. Da die benötigten Attribute nicht repliziert werden, laufen wir in Gefahr, einen Wert von einem DC geliefert zu bekommen, der nicht aktuell ist. Daher müssen wir alle DCs in der Domäne auslesen und uns die richtigen Werte selbst heraussuchen.

Die Domain-Controller abfragen

Als erstes brauchen wir deswegen eine Liste mit allen DCs in der Domäne. Das geht ganz einfach mit dem entsprechenden CmdLet:

PowerShell
1
$dcs = Get-ADDomainController -Filter * | Select-Object name

Anschließend initialisieren wir noch die Variablen, in denen wir die Anzahl der fehlgeschlagenen Anmeldungen sowie die Anmeldungszeit speichern.

PowerShell
1
2
3
$samAccountName = "test.user"
$badpwdcount = 0
$badpwdtime = New-Object System.DateTime

Diese Art der Initialisierung bei einem DateTime-Objekt garantiert uns, dass wir den geringstmöglichen Wert bekommen. Gibt man sich die $badpwdtime Variable aus, sieht man das auch. Diesen Wert brauchen wir gleich für Vergleiche mit dem Wert, den uns das AD beim Auslesen zurückliefern wird.

Jetzt gehen wir durch unsere ausgelesenen DCs und fragen jeden einzelnen davon nach unserem Nutzer ab, den wir überprüfen wollen. Das ist, wie erwähnt, notwendig, da die beiden Eigenschaften badPwdCount und badPasswordTime zwischen verschiedenen DCs unterschiedlich sein können, da diese nicht repliziert werden.

PowerShell
1
2
3
foreach($dc in $dcs) {
   $user = Get-ADUser $samAccountName -Server $dc.name -properties badPwdCount,badPasswordTime
}

Die richtigen Werte ausrechnen

Jetzt müssen wir vergleichen. Uns interessiert die Gesamtzahl der fehlgeschlagenen Logins auf allen unseren DCs. Die kann schließlich auf einem DC „0“ sein, während Sie auf dem nächsten vielleicht „1000“ beträgt – um einmal den Extremfall als Beispiel zu nehmen. Deswegen addieren wir einfach alle ausgelesenen Werte auf unsere $badpwdcount Variable, um am Ende die Gesamtzahl zu erhalten.

PowerShell
1
2
3
4
foreach($dc in $dcs) {
   $user = Get-ADUser $samAccountName -Server $dc.name -properties badPwdCount,badPasswordTime
   $badpwdcount += $user.badPwdCount
}

Bei der Zeit des letzten fehlgeschlagenen Logins interessiert uns natürlich die aktuellste. Deswegen vergleichen wir diese mit dem aktuellen Wert in unserer $badpwdtime Variable und wenn sie größer ist, überschreiben wir diese. Da wir die Variable mit dem geringstmöglichen Datum initialisiert haben, ist erst einmal jedes Datum, dass eventuell beim Nutzer in dem Attribut steht, größer. Durch das Überschreiben vergleichen wir dann beim nächsten Durchlauf mit unserem aktuell höchsten Datum, überschreiben dieses ggf. wieder und so weiter.
Eine kleine Hürde gibt es allerdings noch: Das AD liefert das Datum im Format Int64 (bzw. Long) zurück. Damit können wir natürlich im Vergleich nichts anfangen. Aber mit der fromFileTime-Funktion der DateTime-Klasse können wir den Wert ganz einfach in das aktuelle Zeitformat konvertieren und anschließend vergleichen.

PowerShell
1
2
3
4
5
6
7
8
9
foreach($dc in $dcs) {
   $user = Get-ADUser $samAccountName -Server $dc.name -properties badPwdCount,badPasswordTime
   $badpwdcount += $user.badPwdCount
   $userBadPwdTime = [datetime]::fromFileTime($user.badPasswordTime)
 
   if($badpwdtime -lt $userBadPwdTime) {
      $badpwdtime = $userBadPwdTime
   }
}

Die Ausgabe formatieren

Um den badPwdCount müssen wir uns nicht weiter kümmern – das ist eine einfache Ganzzahl, die wir problemlos loggen können. Das Datum soll allerdings noch in einem lesbaren Format herauskommen.

Dazu überprüfen wir erst einmal, ob überhaupt ein neues Datum gefunden wurde oder ob unsere Variable noch den initialen Wert enthält. Ist das nicht der Fall, können wir mit der ToString-Funktion und einem einfachen Format-String (in diesem Fall für das in Deutschland typische Datumsformat) das Datum formatiert ausgeben lassen.

PowerShell
1
2
3
4
5
if($badpwdtime -ne (New-Object System.DateTime)) {
   $bptString = $badpwdtime.ToString("dd.MM.yyyy HH:mm:ss")
} else {
   $bptString = "-"
}

Und letztendlich lassen wir uns das Ergebnis ausgeben und schreiben es je nach Bedarf in ein Log:

PowerShell
1
Write-Host("User: " + $samAccountName + "- Failed logons: " + $badpwdcount + " - Last failed attempt: " + $bptString)

Zusammenfassung & komplettes Skript

Zusammengefasst haben wir also folgendes gemacht:

  • Liste aller DCs ausgeben lassen
  • Denselben Nutzer von jedem DC abgerufen
  • Den badPwdCount am jeweiligen DC ausgelesen und aufaddiert
  • Die badPasswordTime ausgelesen und abgespeichert, wenn sie größer als die letzte ausgelesene Zeit war

Zum Abschluss noch einmal das komplette Skript zum Kopieren und Einfügen:

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$dcs = Get-ADDomainController -Filter * | Select-Object name
$samAccountName = "test.user"
$badpwdcount = 0
$badpwdtime = New-Object System.DateTime
 
foreach($dc in $dcs) {
   $user = Get-ADUser $samAccountName -Server $dc.name -properties badPwdCount,badPasswordTime
   $badpwdcount += $user.badPwdCount
 
   $userBadPwdTime = [datetime]::fromFileTime($user.badPasswordTime)
 
   if($badpwdtime -lt $userBadPwdTime) {
      $badpwdtime = $userBadPwdTime
   }
}
 
if($badpwdtime -ne (New-Object System.DateTime)) {
   $bptString = $badpwdtime.ToString("dd.MM.yyyy HH:mm:ss")
} else {
   $bptString = "-"
}
 
Write-Host("User: " + $samAccountName + "- Failed logons: " + $badpwdcount + " - Last failed attempt: " + $bptString)

 


 

FirstAttribute AG

 
FirstAttribute AG – Ihr Microsoft Consulting Partner

Wir unterstützen Sie bei PowerShell Scripting Fragen. 
Nehmen Sie Kontakt zu uns auf.
  

 

Artikel weiterempfehlen:
  • teilen
  • tweeten
  • sharen
  • xingen
  • mailen
Artikel erstellt am: 03.07.2017
Tags: badPasswordTimebadPwdCountBrute ForceLast Interactive LoginLogon
1

Leave a Reply

<p>Danke für Ihre Anregungen, Fragen und Hinweise.<br/>Infos zum <a href="https://www.active-directory-faq.dekontakt/">Datenschutz</a></p>
Cancel Reply

FirstWare IDM-Portal im Test: IT-Administrator 08-2022

 

ADFAQ-FirstAttribute

Wer schreibt ?

Team der FirstAttribute AG

Consultants und Entwickler der FirstAttribute arbeiten seit mehr als 20 Jahren in IAM- und Cloud-Transition-Projekten.
Zusammen verfügen Sie über einen wertvollen Erfahrungsschatz im Bereich Active Directory und Azure AD und teilen diesen auf Active Directory FAQ.

Neueste Artikel

  • 8 Tipps für mehr Sicherheit in Active Directory und Backups von AD
  • Azure AD Custom Security Attributes ermöglichen flexible Berechtigungsstrukturen
  • Dateiberechtigungen in MS Teams und SharePoint Online verwalten – So funktioniert es
  • AD-Gruppen in Microsoft Teams verwenden – Dynamische Gruppen in der Praxis
  • Verbindung zwischen Microsoft 365 und SharePoint Online zu Azure AD

Unsere IAM-Lösungen

Ihre IAM-Lösung: FirstWare IDM-Portal

 

my-IAM für Cloud Identity Management in Microsoft Teams

Kontakt aufnehmen

Sie haben eine Frage oder Anmerkung? Schicken Sie uns schnell eine Nachricht.

Nachricht senden
Jetzt AD Tasks vereinfachen und delegieren: FirstWare IDM-Portal

Folgen Sie uns

Kontakt

  • FirstAttribute AG
  • Am Büchele 18, 86928 Hofstetten, Germany
  • +49 89 215 442 400
  • https://www.firstattribute.com

Schlagwörter

.Net ACL Active Directory AD LDS AD Objekt Azure AD Berechtigung Cloud cmdlets Delegation Domain Controller dynamicgroup dynamische Gruppen Exchange Exchange-Ordner Exchange-Postfach Exchange Migration Federation FirstWare Get-Mailbox Global Catalog Group Policy Gruppen Gruppenmitgliedschaft IDM-Portal LDAP m365 Microsoft Azure Migration New-ADUser Novell NTFS Office 365 PowerShell QMM QMM AD QMM Exchange Quest Migration Manager Schema Set-ADUser SID SID History Update Windows 10 Windows Server 2012 R2

Neueste Kommentare

  • activedirectoryfaq.com sharepoint login - infoslist bei Windows 365 und Azure AD verstehen in Theorie und Praxis
  • Domäne Letzte Anmeldung - ObenGesichert.com bei LastLogon vs. LastLogonTimestamp
  • Teams Code Zur Anmeldung - ObenGesichert.com bei Authentifizierung für MS Teams in hybriden Netzwerken
Login
Impressum
Datenschutzerklärung

© 2023 · Active-Directory-FAQ by firstattribute.com

Prev Next