Logo faq-o-matic.net
Logo faq-o-matic.net

Anmeldezeiten für AD-Benutzer per Skript ausgeben

von veröffentlicht am17. März 2010, 22:15 Uhr Kurzlink http://faq-o-matic.net/?p=2181 Zitatlink
Kategorie Kategorie: Active Directory, AD: Erweiterte Abfragen, VBScript   Translate with Microsoft Translator Translate EN
Zuletzt aktualisiert: 28. Mai 2010

image Seit jeher lässt Windows zu, für einen Benutzer Anmeldezeiten zu definieren – seit Windows NT und auch jetzt in Active Directory. Darüber lässt sich festlegen, an welchen Wochentagen und zu welchen Uhrzeiten dem Benutzer die Anmeldung mit dem jeweiligen Konto gestattet ist. Nicht ganz einfach ist es allerdings, diese Zeiten auszulesen. Zwar gibt es natürlich ein GUI dafür, und auch der Kommandozeilenbefehl “net user” gibt darüber Auskunft. Das war es aber auch schon. Insbesondere per Skript ist es alles andere als bequem, an diese Daten zu kommen.

Intern speichert Windows diese Information in einem etwas hässlichen Format, nämlich als Bitmap von 168 Bits, wobei jedes Bit eine Stunde der Woche repräsentiert (24 multipliziert mit 7). Ist das Bit 1, so darf der Benutzer sich anmelden, ist es 0, so wird der Logon verweigert.

Auf der Seite von US-MVP Richard L. Mueller (www.rlmueller.net) fand ich ein VBScript, das die Daten ausliest. Es ist allerdings nicht besonders hübsch und enthält in der Fassung vom 25. 1. 2004 einen lästigen Fehler: Es geht nämlich leider nicht sauber mit internationalen Zeitzonen um.

[LogonHours.vbs – Hilltop Lab]
http://www.rlmueller.net/Programs/LogonHours.txt

Für mein AD-Dokutool José habe ich das Skript daher korrigiert, erweitert und auf meinen Bedarf angepasst, sodass es eine gut lesbare Zusammenfassung der Zeiten ausgibt (siehe Bild). Die eine oder andere hat vielleicht Verwendung dafür, daher folgt hier der Scriptcode. Kopieren, in eine VBS-Datei speichern und wie folgt aufrufen:

cscript JoseLogonHours.vbs “CN=Ellen Bogen,OU=EDV,DC=faq-o-matic,DC=net”

Sollte das Skript einen Fehler ausgeben, so kann es sein, dass dem aufrufenden Benutzer Berechtigungen fehlen. In dem Fall das CMD-Fenster für den Aufruf ausdrücklich als (Domänen-)Administrator starten bzw. mit ausreichenden Rechten anmelden.

Der Code

  1. ' JoseLogonHours.vbs
  2. ' VBScript program to document hours of the week when a given Active
  3. ' Directory user is allowed to logon, using the logonHours attribute.
  4. '
  5. ' Author: Nils Kaczenski, faq-o-matic.net
  6. ' Version 1.0, January 26, 2010
  7. ' ———————————————————————-
  8. ' Based on: LogonHours.vbs
  9. ' Copyright (c) 2002-2004 Richard L. Mueller, Hilltop Lab
  10. ' ———————————————————————-
  11. '
  12. ' This script is designed to be run at a command prompt, using the
  13. ' Cscript host. For example:
  14. ' cscript //nologo JoseLogonHours.vbs DistinguishedName
  15. ' DistinguishedName can be similar to:
  16. '     "cn=TestUser,ou=Sales,dc=MyDomain,dc=com"
  17. '
  18. ' You have a royalty-free right to use, modify, reproduce, and
  19. ' distribute this script file in any way you find useful, provided that
  20. ' you agree that the copyright owner above has no warranty, obligations,
  21. ' or liability for such use.
  22.  
  23. Option Explicit
  24.  
  25. Dim objShell, lngBias, strUserDN
  26. Dim objUser
  27. Dim lngBiasKey
  28.  
  29. ' Check for required argument.
  30. If (WScript.Arguments.Count = 0) Then
  31.     WScript.Echo "Error, required argument missing."
  32.     WScript.Echo "JoseLogonHours.vbs"
  33.     WScript.Echo "Program to document allowed logon hours"
  34.     WScript.Echo "Syntax:"
  35.     WScript.Echo "cscript JoseLogonHours.vbs DN"
  36.     WScript.Echo "where DN is the DistinguishedName of an AD user."
  37.     WScript.Echo "For example, DN could be:"
  38.     WScript.Echo "  cn=TestUser,ou=Sales,dc=MyDomain,dc=com"
  39.     WScript.Quit(1)
  40. End If
  41.  
  42. strUserDN = WScript.Arguments(0)
  43.  
  44. ' Bind to the specified user object with the LDAP provider.
  45. On Error Resume Next
  46. Set objUser = GetObject("LDAP://" & strUserDN)
  47. If (Err.Number <> 0) Then
  48.     On Error Goto 0
  49.     WScript.Echo "User not found in Active Directory"
  50.     WScript.Echo strUserDN
  51.     WScript.Quit(1)
  52. End If
  53. On Error Goto 0
  54.  
  55. ' Determine the time zone bias from the local registry.
  56. ' This bias does not change with Daylight Savings Time.
  57. Set objShell = CreateObject("Wscript.Shell")
  58. lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
  59.     & "TimeZoneInformation\Bias")
  60. If (UCase(TypeName(lngBiasKey)) = "LONG") Then
  61.     lngBias = lngBiasKey
  62. ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
  63.     lngBias = 0
  64.     For k = 0 To UBound(lngBiasKey)
  65.         lngBias = lngBias + (lngBiasKey(k) * 256^k)
  66.     Next
  67. End If
  68. lngBias = Round(lngBias/60)
  69. ' this is for debug use
  70. WScript.Echo "Bias (Time Zone Correction): " & lngBias
  71. WScript.Echo GetLogonHours(objUser)
  72.  
  73. Function GetLogonHours(objAccount)
  74.     Dim DayNames
  75.     Dim AllLogonHours(20)
  76.     Dim LogonHoursBits(167)
  77.     Dim LogonHours
  78.     Dim LogonHourByte, LogonHour
  79.     Dim k, Counter, LoopCounter, j, m
  80.     Dim DayOfWeek(6), DayLogon(6)
  81.     Dim DayCount, HourCount
  82.  
  83.     ' German day names (short), beginning with Sunday (US-like)
  84.     DayNames = Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
  85.  
  86.     WScript.Echo "User: " & objAccount.name
  87.  
  88.     On Error Resume Next
  89.         ' Retrieve the user's logonHours attribute.
  90.     objAccount.GetInfoEx Array("logonHours"), 0
  91.     LogonHours = objAccount.Get("logonHours")
  92.     If err.number <> 0 Then
  93.        WScript.Echo "Fehler: " & err.number & " (" & err.description & ")"
  94.        WScript.Quit
  95.         End If
  96.  
  97.     ' Populate a byte array.
  98.     For k = 1 To LenB(LogonHours)
  99.         AllLogonHours(k – 1) = AscB(MidB(LogonHours, k, 1))
  100.     Next
  101.  
  102.     ' Populate a bit array, offset by the time zone bias.
  103.     j = 0
  104.     For Each LogonHourByte In AllLogonHours
  105.         For k = 7 To 0 Step -1
  106.             m = 8*j + k – lngBias
  107.             If (m < 0) Then
  108.                 m = m + 168
  109.             End If
  110.             ' *** correction Nils Kaczenski:
  111.             ' wrap the other way as well!
  112.             If (m > 167) Then
  113.                 m = m – 168
  114.             End If
  115.             If (LogonHourByte And 2^k) Then
  116.                 LogonHoursBits(m) = 1
  117.             Else
  118.                 LogonHoursBits(m) = 0
  119.             End If
  120.         Next
  121.         j = j + 1
  122.     Next
  123.  
  124.     Counter = 0
  125.     LoopCounter = 0
  126.     DayCount = 0
  127.  
  128.     For Each LogonHour In LogonHoursBits
  129.         ' add logon hours to an array of days
  130.         DayOfWeek(DayCount) = DayOfWeek(DayCount) & LogonHour
  131.         Counter  = Counter + 1
  132.         If (Counter = 24) Then
  133.             ' this makes a full day, so check it
  134.             If DayOfWeek(DayCount) = String(24, "1") Then
  135.                 ' User may log on the whole day
  136.                 DayLogon(DayCount) = "immer"
  137.             Else
  138.                 ' User has at least one exclusion, so walk through the hours
  139.                 ' start counting at 1 so we can use the InStr 0 value
  140.                 ' (but we need to adjust this in the code)
  141.                 HourCount = 1
  142.                 Do Until HourCount = 25
  143.                     ' find times the user may not log on
  144.                     HourCount = InStr(HourCount, DayOfWeek(DayCount), "0")
  145.                     If HourCount = 0 Then
  146.                         ' no more exclusions, day complete
  147.                         HourCount = 25
  148.                     Else
  149.                         ' add beginning of exclusion time
  150.                         DayLogon(DayCount) = DayLogon(DayCount) & ", nicht " & HourCount – 1
  151.                         ' find next allowed hour
  152.                         HourCount = InStr(HourCount, DayOfWeek(DayCount), "1")
  153.                         If HourCount = 0 Then ' Or HourCount > 24
  154.                             ' no more allowed hours, day complete
  155.                             HourCount = 25
  156.                             DayLogon(DayCount) = DayLogon(DayCount) & " bis 24"
  157.                         Else
  158.                             ' add ending of exclusion time
  159.                             DayLogon(DayCount) = DayLogon(DayCount) & " bis " & HourCount – 1
  160.                             HourCount = HourCount + 1
  161.                         End If
  162.                     End If
  163.                 Loop
  164.             End If 
  165.             ' Clear the beginning of the string
  166.             If Left(DayLogon(DayCount), 2) = ", " Then DayLogon(DayCount) = Mid(DayLogon(DayCount), 3)
  167.             DayCount = DayCount + 1
  168.             Counter = 0
  169.             LoopCounter = LoopCounter + 1
  170.         End If
  171.     Next
  172.     If Join(DayOfWeek, "") = String(168, "1") Then
  173.         ' User may logon any time
  174.         GetLogonHours = "jederzeit"
  175.     ElseIf Join(DayOfWeek, "") = String(168, "0") Then
  176.         ' User may never log on
  177.         GetLogonHours = "niemals"
  178.     Else
  179.         ' Output Monday to Saturday
  180.         For DayCount = 1 To 6
  181.             GetLogonHours = GetLogonHours & DayNames(DayCount) & ": " & DayLogon(DayCount) & vbNewLine
  182.         Next
  183.         ' Outside the US, Sunday is the last day, not the first one
  184.         GetLogonHours = GetLogonHours & DayNames(0) & ": " & DayLogon(0)
  185.     End If
  186.     'WScript.Echo GetLogonHours
  187.    
  188. End Function

Verwandte Beiträge:

  1. AD-Informationen schnell auslesen
    Neben eineAm klassischen ADSI-Skript gibt es eine relativ einfache Möglichkeit, Informationen aus dem Active Directory auszulesen. Hierzu lässt sich das...
  2. Gruppe “Prä-Windows 2000 kompatibler Zugriff” per Skript leeren
    Die Gruppe “Prä-Windows 2000 kompatibler Zugriff” ist in der ersten Version von Active Directory unter Windows 2000 eingeführt worden, um...
  3. Datum des AD-Backup per Skript herausfinden
    Möchte man das Datum herausfinden, zu dem Active Directory zuletzt gesichert wurde, so gibt es eine recht einfache Methode: Ab...
  4. Exchange Server 2003: Das Datenbanklimit per Skript setzen
    Seit dem Service Pack 2 für Exchange Server 2003 ist die Datenbankgröße der Standard Edition nicht mehr auf 16 GB...
  5. Wie kann ich für alle Benutzer ein Home-Verzeichnis anlegen?
    Dass beim Anlegen eines Benutzers automatisch ein Home-Verzeichnis (Basisordner) angelegt wird, ist kein Feature des Active Directory, sondern des Verwaltungsprogramms....

© 2005-2012 bei faq-o-matic.net. Alle Rechte an den Texten liegen bei deren Autorinnen und Autoren.

Jede Wiederveröffentlichung der Texte oder von Auszügen daraus - egal ob kommerziell oder nicht - bedarf der ausdrücklichen Genehmigung durch die jeweiligen Urheberinnen oder Urheber.

Das Impressum findet sich unter: http://www.faq-o-matic.net/impressum/

Danke, dass du faq-o-matic.net nutzt. Du hast ein einfaches Blog sehr glücklich gemacht!