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

© 2005-2019 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!