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
-
‚ JoseLogonHours.vbs
-
‚ VBScript program to document hours of the week when a given Active
-
‚ Directory user is allowed to logon, using the logonHours attribute.
-
‚
-
‚ Author: Nils Kaczenski, faq-o-matic.net
-
‚ Version 1.0, January 26, 2010
-
‚ ———————————————————————-
-
‚ Based on: LogonHours.vbs
-
‚ Copyright (c) 2002-2004 Richard L. Mueller, Hilltop Lab
-
‚ ———————————————————————-
-
‚
-
‚ This script is designed to be run at a command prompt, using the
-
‚ Cscript host. For example:
-
‚ cscript //nologo JoseLogonHours.vbs DistinguishedName
-
‚ DistinguishedName can be similar to:
-
‚ "cn=TestUser,ou=Sales,dc=MyDomain,dc=com"
-
‚
-
‚ You have a royalty-free right to use, modify, reproduce, and
-
‚ distribute this script file in any way you find useful, provided that
-
‚ you agree that the copyright owner above has no warranty, obligations,
-
‚ or liability for such use.
-
-
Option Explicit
-
-
Dim objShell, lngBias, strUserDN
-
Dim objUser
-
Dim lngBiasKey
-
-
‚ Check for required argument.
-
If (WScript.Arguments.Count = 0) Then
-
WScript.Echo "Error, required argument missing."
-
WScript.Echo "JoseLogonHours.vbs"
-
WScript.Echo "Program to document allowed logon hours"
-
WScript.Echo "Syntax:"
-
WScript.Echo "cscript JoseLogonHours.vbs DN"
-
WScript.Echo "where DN is the DistinguishedName of an AD user."
-
WScript.Echo "For example, DN could be:"
-
WScript.Echo " cn=TestUser,ou=Sales,dc=MyDomain,dc=com"
-
WScript.Quit(1)
-
End If
-
-
strUserDN = WScript.Arguments(0)
-
-
‚ Bind to the specified user object with the LDAP provider.
-
On Error Resume Next
-
Set objUser = GetObject("LDAP://" & strUserDN)
-
If (Err.Number <> 0) Then
-
On Error Goto 0
-
WScript.Echo "User not found in Active Directory"
-
WScript.Echo strUserDN
-
WScript.Quit(1)
-
End If
-
On Error Goto 0
-
-
‚ Determine the time zone bias from the local registry.
-
‚ This bias does not change with Daylight Savings Time.
-
Set objShell = CreateObject("Wscript.Shell")
-
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
-
& "TimeZoneInformation\Bias")
-
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
-
lngBias = lngBiasKey
-
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
-
lngBias = 0
-
For k = 0 To UBound(lngBiasKey)
-
lngBias = lngBias + (lngBiasKey(k) * 256^k)
-
Next
-
End If
-
lngBias = Round(lngBias/60)
-
‚ this is for debug use
-
WScript.Echo "Bias (Time Zone Correction): " & lngBias
-
WScript.Echo GetLogonHours(objUser)
-
-
Function GetLogonHours(objAccount)
-
Dim DayNames
-
Dim AllLogonHours(20)
-
Dim LogonHoursBits(167)
-
Dim LogonHours
-
Dim LogonHourByte, LogonHour
-
Dim k, Counter, LoopCounter, j, m
-
Dim DayOfWeek(6), DayLogon(6)
-
Dim DayCount, HourCount
-
-
‚ German day names (short), beginning with Sunday (US-like)
-
DayNames = Array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
-
-
WScript.Echo "User: " & objAccount.name
-
-
On Error Resume Next
-
‚ Retrieve the user’s logonHours attribute.
-
objAccount.GetInfoEx Array("logonHours"), 0
-
LogonHours = objAccount.Get("logonHours")
-
If err.number <> 0 Then
-
WScript.Echo "Fehler: " & err.number & " (" & err.description & ")"
-
WScript.Quit
-
End If
-
-
‚ Populate a byte array.
-
For k = 1 To LenB(LogonHours)
-
AllLogonHours(k – 1) = AscB(MidB(LogonHours, k, 1))
-
Next
-
-
‚ Populate a bit array, offset by the time zone bias.
-
j = 0
-
For Each LogonHourByte In AllLogonHours
-
For k = 7 To 0 Step –1
-
m = 8*j + k – lngBias
-
If (m < 0) Then
-
m = m + 168
-
End If
-
‚ *** correction Nils Kaczenski:
-
‚ wrap the other way as well!
-
If (m > 167) Then
-
m = m – 168
-
End If
-
If (LogonHourByte And 2^k) Then
-
LogonHoursBits(m) = 1
-
Else
-
LogonHoursBits(m) = 0
-
End If
-
Next
-
j = j + 1
-
Next
-
-
Counter = 0
-
LoopCounter = 0
-
DayCount = 0
-
-
For Each LogonHour In LogonHoursBits
-
‚ add logon hours to an array of days
-
DayOfWeek(DayCount) = DayOfWeek(DayCount) & LogonHour
-
Counter = Counter + 1
-
If (Counter = 24) Then
-
‚ this makes a full day, so check it
-
If DayOfWeek(DayCount) = String(24, "1") Then
-
‚ User may log on the whole day
-
DayLogon(DayCount) = "immer"
-
Else
-
‚ User has at least one exclusion, so walk through the hours
-
‚ start counting at 1 so we can use the InStr 0 value
-
‚ (but we need to adjust this in the code)
-
HourCount = 1
-
Do Until HourCount = 25
-
‚ find times the user may not log on
-
HourCount = InStr(HourCount, DayOfWeek(DayCount), "0")
-
If HourCount = 0 Then
-
‚ no more exclusions, day complete
-
HourCount = 25
-
Else
-
‚ add beginning of exclusion time
-
DayLogon(DayCount) = DayLogon(DayCount) & ", nicht " & HourCount – 1
-
‚ find next allowed hour
-
HourCount = InStr(HourCount, DayOfWeek(DayCount), "1")
-
If HourCount = 0 Then ‚ Or HourCount > 24
-
‚ no more allowed hours, day complete
-
HourCount = 25
-
DayLogon(DayCount) = DayLogon(DayCount) & " bis 24"
-
Else
-
‚ add ending of exclusion time
-
DayLogon(DayCount) = DayLogon(DayCount) & " bis " & HourCount – 1
-
HourCount = HourCount + 1
-
End If
-
End If
-
Loop
-
End If
-
‚ Clear the beginning of the string
-
If Left(DayLogon(DayCount), 2) = ", " Then DayLogon(DayCount) = Mid(DayLogon(DayCount), 3)
-
DayCount = DayCount + 1
-
Counter = 0
-
LoopCounter = LoopCounter + 1
-
End If
-
Next
-
If Join(DayOfWeek, "") = String(168, "1") Then
-
‚ User may logon any time
-
GetLogonHours = "jederzeit"
-
ElseIf Join(DayOfWeek, "") = String(168, "0") Then
-
‚ User may never log on
-
GetLogonHours = "niemals"
-
Else
-
‚ Output Monday to Saturday
-
For DayCount = 1 To 6
-
GetLogonHours = GetLogonHours & DayNames(DayCount) & ": " & DayLogon(DayCount) & vbNewLine
-
Next
-
‚ Outside the US, Sunday is the last day, not the first one
-
GetLogonHours = GetLogonHours & DayNames(0) & ": " & DayLogon(0)
-
End If
-
‚WScript.Echo GetLogonHours
-
-
End Function
http://faq-o-matic.net/?p=2181