Printout Header
RSS Feed

Gesperrte Benutzer im Active Directory suchen und finden


Wir benutzen für diese Suche das Active Directory Attribut lockoutTime, in dem angegeben wird, wann der Benutzer das letzte Mal gesperrt wurde - es handelt sich hierbei um eine Interval-angabe im Microsoft Integer8 Format. Aber die Suche nach Konten, deren lockoutTime-Wert größer als Null ist, führt nicht unmittelbar zum Ziel. Denn wenn der Account nach einer Weile vom System wieder automatisch entsperrt wird, wird die lockoutTime dieses Accounts zunächst nicht auf Null gesetzt. Man muß also anhand der lockoutTime und der Domain Account Lockout Policy berechnen, ob der Account noch wirklich gesperrt ist.

Vorsicht: Gesperrte Benutzer dürfen nicht mit deaktivierten Benutzern verwechselt werden. Lesen Sie dazu auch den SelfADSI-Artikel "Unlock : Entsperren von Active Directory Benutzerkonten".

Zur allgemeinen Erläuterung von LDAP-Suchvorgängen lesen Sie das SelfADSI-Kapitel "LDAP Objekte im Verzeichnis suchen".


Alle gesperrten Benutzer-Accounts der eigenen Domäne finden


Dieses Script findet alle gesperrten Benutzern der Domäne, in der der aktuell angemeldete Benutzer Mitglied ist. Wenn die Sperre vom System automatisch wieder aufgehoben wird, dann wird der entsprechende Zeitpunkt pro Benutzer angegeben. Dazu ist anfangs das Auslesen der Sperrdauer aus dem Attribut lockoutDuration am Domänenobjekt selbst notwendig. An dieser Stelle benötigt man eine spezielle Umwandlungsfunktion des Wertes in eine entsprechende Minuten-Zeitdauer, auch später bei der Berechnung des Lockout-Zeitpunktes ist eine ähnliche Umwandlung notwendig:

ldapFilter = "(&(sAMAccountType=805306368)(lockoutTime>=1))" Set rootDSE = GetObject("LDAP://rootDSE") domainDN = rootDSE.Get("defaultNamingContext") Set objDomain = GetObject("LDAP://" & domainDN) Set interval = objDomain.lockoutDuration domainLockout = LargeIntegerToMinutes(interval) If (domainLockout > 0) then WScript.Echo "Domain lockout duration is: " & domainLockout & " minutes" Else WScript.Echo "Domain lockout duration is permanent until the Admin unlocks the accounts" End If WScript.Echo "Locked accounts:" WScript.Echo Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Open "ADSearch" Set objectList = ado.Execute("<LDAP://" & domainDN & ">;" & ldapFilter & ";distinguishedName,lockoutTime;subtree") While Not objectList.EOF If (domainLockout > 0) then dateTime = objectList.Fields("lockoutTime") lockOutTime = LargeIntegerToDate(dateTime) userLockoutLeft = domainLockout - DateDiff("n", lockOutTime, Now) If (userLockoutLeft > 0) Then WScript.Echo objectList.Fields("distinguishedName") WScript.Echo "User is locked out (for " & userLockoutLeft & " more minutes)" WScript.Echo End If Else WScript.Echo objectList.Fields("distinguishedName") End If objectList.MoveNext Wend '_______________________________________________________________________________________ [ LargeIntegerToDate ] ' ' Function LargeIntegerToDate(value) 'nimmmt einen Microsoft LargeInteger Wert (Integer8) und gibt das entsprechende Datum plus Uhrzeit zurück Set sho = CreateObject("Wscript.Shell") timeShiftValue = sho.RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias") If IsArray(timeShiftValue) Then timeShift = 0 For i = 0 To UBound(timeShiftValue) timeShift = timeShift + (timeShiftValue(i) * 256^i) Next Else timeShift = timeShiftValue End If i8High = value.HighPart i8Low = value.LowPart If (i8Low < 0) Then i8High = i8High + 1 End If If (i8High = 0) And (i8Low = 0) Then LargeIntegerToDate = #1/1/1601# Else LargeIntegerToDate = #1/1/1601# + (((i8High * 2^32) + i8Low)/600000000 - timeShift)/1440 End If End Function '_______________________________________________________________________________________ [ LargeIntegerToMinutes ] ' ' Function LargeIntegerToMinutes(value) 'nimmmt einen Microsoft LargeInteger Wert (Integer8) und gibt das entsprechende ... '... Zeitinterval in Minuten zur?ck (-1 f?r "Never") If (value.HighPart = -2147483648) And (value.LowPart = 0) then LargeIntegerToMinutes = -1 Else i8High = value.HighPart i8Low = value.LowPart If (i8Low < 0) Then i8High = i8High + 1 End If LargeIntegerToMinutes = -(((i8High * 2^32) + i8Low)/600000000) End If End Function

Alle gesperrten Benutzer-Accounts finden - Kurzversion 1


Die kürzere Variante, die jedoch einen zusätzlichen Bindvorgang direkt mit jedem zu prüfenden Account beinhaltet - es wird hier keine Zeitangabe über die Dauer der Sperrung ausgegeben und deswegen werden die Konvertierungsfunktionen für die Integer8-Werte nicht benötigt. Allerdings müssen wir hier jeden Benutzer über den ADSI WinNT-Provider verbinden, um die API-Property IsAccountLocked zu prüfen, und dafür brauchen wir den NetBIOS-Namen der Domäne - er wird durch die Benutzung des ADSystemInfo COM Objektes am Anfang des Scripts ermittelt:

Const ADS_UF_LOCKOUT = 16 ldapFilter = "(&(sAMAccountType=805306368)(lockoutTime>=1))" Set rootDSE = GetObject("LDAP://rootDSE") domainDN = rootDSE.Get("defaultNamingContext") Set aio = CreateObject("ADSystemInfo") domainNETBios = aio.DomainShortName WScript.Echo "Locked accounts:" WScript.Echo Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Open "ADSearch" Set objectList = ado.Execute("<LDAP://" & domainDN & ">;" & ldapFilter & ";distinguishedName,samAccountName;subtree") While Not objectList.EOF userLogonName = domainNETBios & "/" & objectList.Fields("samAccountName") Set user = GetObject("WinNT://" & userLogonName) 'Syntax=>   WinNT://domain/user  if (user.IsAccountLocked) then WScript.Echo objectList.Fields("distinguishedName") End if objectList.MoveNext Wend

Alle gesperrten Benutzer-Accounts finden - Kurzversion 2 (>Windows 2003)


Eine Abwandlung der kurzen Variante, die allerdings nur in Umgebungen ab Windows 2003 funktioniert: Man muß hier das Attribut msDS-User-Account-Control-Computed auslesen (es ist ein Constructed Attribut und läßt sich nicht direkt bei der Suche verwenden) und überprüfen, ob in dessen Bitfeld das Flag UF_LOCKOUT (16) gesetzt ist.

Const ADS_UF_LOCKOUT = 16 ldapFilter = "(&(sAMAccountType=805306368)(lockoutTime>=1))" Set rootDSE = GetObject("LDAP://rootDSE") domainDN = rootDSE.Get("defaultNamingContext") WScript.Echo "Locked accounts:" WScript.Echo Set ado = CreateObject("ADODB.Connection") ado.Provider = "ADSDSOObject" ado.Open "ADSearch" Set objectList = ado.Execute("<LDAP://" & domainDN & ">;" & ldapFilter & ";ADSPath,distinguishedName;subtree") While Not objectList.EOF Set user = GetObject(objectList.Fields("ADSPath")) user.GetInfoEx Array("msDS-User-Account-Control-Computed"), 0 flags = user.Get("msDS-User-Account-Control-Computed") if (flags and ADS_UF_LOCKOUT) then WScript.Echo objectList.Fields("distinguishedName") End if objectList.MoveNext Wend