Jump to content

AD user - query logonhours


UglyBob
 Share

Recommended Posts

I'm working on a new AD admin console and one of the last remaining attributes I can't retrieve is the user's 'logonhours'.

I've got hold of the VB version from Microsoft:

CODE
On Error Resume Next

Dim arrLogonHoursBytes(20)

Dim arrLogonHoursBits(167)

arrDayOfWeek = Array _

("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

Set objUser = GetObject _

("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")

arrLogonHours = objUser.Get("logonHours")

For i = 1 To LenB(arrLogonHours)

WScript.Echo "length - " & LenB(arrLogonHours)

arrLogonHoursBytes(i-1) = AscB(MidB(arrLogonHours, i, 1))

' WScript.Echo "MidB returns: " & MidB(arrLogonHours, i, 1)

' WScript.Echo "arrLogonHoursBytes: " & arrLogonHoursBytes(i-1)

' wscript.echo vbcrlf

Next

intCounter = 0

intLoopCounter = 0

WScript.echo "Day Byte 1 Byte 2 Byte 3"

For Each LogonHourByte In arrLogonHoursBytes

arrLogonHourBits = GetLogonHourBits(LogonHourByte)

If intCounter = 0 Then

WScript.STDOUT.Write arrDayOfWeek(intLoopCounter) & Space(2)

intLoopCounter = intLoopCounter + 1

End If

For Each LogonHourBit In arrLogonHourBits

WScript.STDOUT.Write LogonHourBit

intCounter = 1 + intCounter

If intCounter = 8 or intCounter = 16 Then

Wscript.STDOUT.Write Space(1)

End If

If intCounter = 24 Then

WScript.echo vbCr

intCounter = 0

End If

Next

Next

Function GetLogonHourBits(x)

Dim arrBits(7)

For i = 7 to 0 Step -1

If x And 2^i Then

arrBits(i) = 1

Else

arrBits(i) = 0

End If

Next

GetLogonHourBits = arrBits

End Function

and have used the VB converter to produce an AutoIT equivalent (with some additional tweaking).

CODE

#include <array.au3>

Dim $arrLogonHoursBytes[20]

Dim $arrLogonHoursBits[167]

$arrDayOfWeek = _ArrayCreate ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

$objUser = ObjGet("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")

$arrLogonHours = $objUser.Get ("logonHours")

For $i = 1 To BinaryLen($arrLogonHours)

ConsoleWrite ( "Numbers " & BinaryLen($arrLogonHours) )

$arrLogonHoursBytes[$i-1] = Asc(BinaryMid($arrLogonHours, $i, 1))

Next

$intCounter = 0

$intLoopCounter = 0

ConsoleWrite ( "Day Byte 1 Byte 2 Byte 3" & @CRLF )

For $LogonHourByte In $arrLogonHoursBytes

$arrLogonHourBits = GetLogonHourBits($LogonHourByte)

If $intCounter = 0 Then

ConsoleWrite ( $arrDayOfWeek[$intLoopCounter] & " " )

$intLoopCounter = $intLoopCounter + 1

EndIf

For $LogonHourBit In $arrLogonHourBits

ConsoleWrite ( $LogonHourBit )

$intCounter = 1 + $intCounter

If $intCounter = 8 or $intCounter = 16 Then

ConsoleWrite ( " " )

EndIf

If $intCounter = 24 Then

ConsoleWrite (@CR)

$intCounter = 0

EndIf

Next

Next

Func GetLogonHourBits($x)

Dim $arrBits[7]

For $i = 7 to 0 Step -1

If $x And 2^$i Then

$arrBits[$i] = 1

Else

$arrBits[$i] = 0

EndIf

Next

Return $arrBits

EndFunc

however it doesn't work (though the VB version works fine). It returns an error:

: ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:

$arrBits[$i] = 0

^ ERROR

I don't think the message above is actually the problem, I think it's to do with the 'objUser.get ("logonhours") as the '$arrLogonHours' variable doesn't seem to contain anything, therefor the FOR...NEXT loop is bypasssed which in turn causes the error message.

Any help would be greatly appreciated.

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

@UglyBob

Tey this :

#include <array.au3>

Dim $arrLogonHoursBytes[21]
Dim $arrLogonHoursBits[168]
$arrDayOfWeek = _ArrayCreate ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

$objUser = ObjGet("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")
$arrLogonHours = $objUser.Get ("logonHours")

If IsObj($objUser) Then
For $i = 1 To BinaryLen($arrLogonHours)
    ConsoleWrite ( "Numbers " & BinaryLen($arrLogonHours) )
    $arrLogonHoursBytes[$i-1] = Asc(BinaryMid($arrLogonHours, $i, 1))
Next

    $intCounter = 0
    $intLoopCounter = 0
    ConsoleWrite ( "Day Byte 1 Byte 2 Byte 3" & @CRLF )
    For $LogonHourByte In $arrLogonHoursBytes
        $arrLogonHourBits = GetLogonHourBits($LogonHourByte)

    If $intCounter = 0 Then
        ConsoleWrite ( $arrDayOfWeek[$intLoopCounter] & " " )
        $intLoopCounter = $intLoopCounter + 1
    EndIf

        For $LogonHourBit In $arrLogonHourBits
            ConsoleWrite ( $LogonHourBit )
        $intCounter = 1 + $intCounter

        If $intCounter = 8 or $intCounter = 16 Then
            ConsoleWrite ( " " )
        EndIf

        If $intCounter = 24 Then
            ConsoleWrite ( @CRLF )
            $intCounter = 0
        EndIf 
    Next
Next
ConsoleWrite(  @LF)
Else 
    MsgBox(0,"Error","No good LDAP connection, Try again ... ")
Endif

Func GetLogonHourBits($x)
Dim $arrBits[8]
    For $i = 7 to 0 Step -1
        If $x And 2^$i Then
        $arrBits[$i] = 1
        Else
        $arrBits[$i] = 0
        EndIf
    Next
    Return $arrBits
EndFunc

regards

ptrex

Link to comment
Share on other sites

Thanks for the response ptrex; the script now runs, however, it doesn't return anything.

I think the whole problem relates to the binarylen command. I don't think this is the equivalent lenb command that vbasic uses. The initial FOR...NEXT loop doesn't run and therefore doesn't populate the $arrLogonHoursBytes array with anything.

I know that the $arrLogonHours variable does contain data as I'm able to copy the logonhours from one person to another. I just can't read it.

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

The VB script works fine.

the results appear something like this:

Day Byte 1 Byte 2 Byte 3

Sun 00000001 11111111 11100000

Mon 00000001 11111111 11100000

Tue 00000001 11111111 11100000

Wed 00011111 11111111 11100000

Thu 00011111 11111111 11100000

Fri 00000001 11111111 11100000

Sat 00000001 11111111 11100000

1's indicating the logon hours.

in addition, as I know that the number of bytes for the variable $arrLogonHours is 21 I ran the script by replacing:

For $i = 1 To BinaryLen($arrLogonHours)

with

For $i = 1 To 21

This seems to identify the problem with the conversion of the VB line:

arrLogonHoursBytes(i-1) = AscB(MidB(arrLogonHours, i, 1))

Either I'm misinterpreting the documentation for the functions 'AscB' and 'MidB' but I can't find any autoit equivalents.

@UglyBob

Didi the VBScript return anything ?

Because when I ran it, it did not on my side ?

Please check if that runs OK.

Regards

ptrex

Edited by UglyBob

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

@UglyBob

Indead you are on the right track.

The AU3 conversion replaced the BYTE function by a BIT functions. Which is completely differently of course.

This function returns the number of bytes from a string.

Comparable with to the LenB functions in VBScript.

$arrLogonHours = "000000011111111111100001"

ConsoleWrite(_LenB($arrLogonHours) & @LF)

Func _LenB ($sString)
    Local $sStr, $i

    For $i = 1 to StringLen (StringStripWS($sString,8)) Step 8
        $sStr += 1
    Next
    Return $sStr
EndFunc

ConsoleWrite(_AscB($arrLogonHours) & @LF)

Func _AscB ($sString)
    $sByte = StringLeft ($sString,4)
    Return $sByte
EndFunc

I am not in a domain at the moment, so I can't test if this function brings you further.

Let me know if you tested it.

regards

ptrex

Edited by ptrex
Link to comment
Share on other sites

alas Ptrex it doesn't help.

well, just like a comedian works out a joke by working backwards from the punchline I'm getting damn close to the solution:

After examining both versions of the code to find out what they're actually doing I've been working backwards from the output (as seen in the example previously).

You may have already worked this part out but I'm just explaining how the code works in order to produce the 0's and 1's (with the hope that someone will figure out the final piece of the puzzle :) )

anyhoo, here goes:

to get the final output of the example:

Day Byte 1 Byte 2 Byte 3

Sun 00000001 11111111 11100000

Mon 00000001 11111111 11100000

Tue 00000001 11111111 11100000

Wed 00011111 11111111 11100000

Thu 00011111 11111111 11100000

Fri 00000001 11111111 11100000

Sat 00000001 11111111 11100000

each byte (3 bytes per day) is a number in binary format: e.g. 00000001 = 128

this number is translated to a character '' when run via autoit or '?' when I run the VB version.

this is then translated to its binary format 0x80.

In otherwords the VB line:

arrLogonHoursBytes(i-1) = AscB(MidB(arrLogonHours, i, 1))

is basically extracting the first byte (e.g. '0x80') then converting it to string (which is the autoit equivalent of 'binarytostring') then it translates that character into its ascii code (128). This is the decimal equivalent of the first byte of the first day.

What I can't figure out is how to extract the byte in order to complete the process.

I've corrected the 'GetLogonHourBits' function as I don't believe the IF statement using the And boolean operator works. It now translates the byte into the binary format.

Hopefully that all makes sense...

as an example I've altered the autoit script slightly by using the '$arrLogonHours' variable to contain the binary code:

CODE
#include <array.au3>

Dim $arrLogonHoursBytes[21]

Dim $arrLogonHoursBits[168]

$arrDayOfWeek = _ArrayCreate ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

;$objUser = ObjGet ("LDAP://CN=joe bloggs,CN=Users,DC=company,DC=com")

;$arrLogonHours = $objUser.Get("logonHours")

$arrLogonHours = "0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07" & _

"0x80" & "0xFF" & "0x07"

$t=0

For $i = 1 To 21

$arrLogonHoursBytes[$i-1] = asc(BinaryToString(stringmid($arrLogonHours, ($i+$t), 4)))

$t += 3

Next

$intCounter = 0

$intLoopCounter = 0

ConsoleWrite ("Day Byte 1 Byte 2 Byte 3" & @CRLF )

For $LogonHourByte In $arrLogonHoursBytes

$arrLogonHourBits = GetLogonHourBits($LogonHourByte)

If $intCounter = 0 Then

ConsoleWrite ( $arrDayOfWeek[$intLoopCounter] & " " )

$intLoopCounter = $intLoopCounter + 1

EndIf

For $LogonHourBit In $arrLogonHourBits

ConsoleWrite ( $LogonHourBit )

$intCounter = 1 + $intCounter

If $intCounter = 8 or $intCounter = 16 Then

ConsoleWrite ( " " )

EndIf

If $intCounter = 24 Then

ConsoleWrite (@CR)

$intCounter = 0

EndIf

Next

Next

Func GetLogonHourBits($x)

Local $Return

Dim $arrBits[8]

For $i = 7 to 0 Step -1

If $x >= 2^$i Then

$arrBits[$i] = 1

$x = $x - 2^$i

Else

$arrBits[$i] = 0

EndIf

Next

$Return = $arrBits

Return $Return

EndFunc

in the line:

asc(BinaryToString(stringmid($arrLogonHours, ($i+$t), 4)))

the 'asc(binarytostring' commands are translating as mentioned above (from '0x80' to '' to '128'), so the question is... how do I get the bytes from the variable '$arrLogonHours'?????

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

I don't get your analysis. The hours you showed (which I take to be 0600 to 1800) look more like a 24 bit binary of 0x01FFE0 to me. With the hours simply bit encoded, with the leftmost bit for the hour 0000 to 0100, and the rightmost bit for 2300 to 2400.

I'm wondering where you got the bit reversal that 00000001 = 0x80?

If you just get the value of $arrLogonHours and display it, what do you get?

#include <array.au3>
$objUser = ObjGet("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")
$arrLogonHours = $objUser.Get ("logonHours")
If IsArray($arrLogonHours) Then
      _ArrayDisplay($arrLogonHours, "Debug: $arrLogonHours")
Else
      MsgBox(64, "Debug", "$arrLogonHours = " & $arrLogonHours)
EndIf

Wish I had a domain handy to check it out on, but I don't.

:)

Edit: Found a reference: Win32_NetworkLoginProfile Class, which says:

LogonHours

Data type: string

Access type: Read-only

Qualifiers: MaxLen(147)

Times during the week when the user can log on. Each bit represents a unit of time specified by the UnitsPerWeek property. For instance, if the unit of time is hourly, the first bit (bit 0, word 0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is Sunday, 1:00 to 1:59, and so on. If this member is set to NULL, then there is no time restriction. The time is set to GMT and must be adjusted for other time zones (for example, GMT minus 8 hours for PST).

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I don't get your analysis.

I don't blame you, I have to put up with this mind of mine 24hours a day :) .

I suppose it's always a little hard to explain things in a forum without writing war&peace (whilst trying to make sense of it myself).

anyhoo, here goes (working backwards):

If you were to just view one day, then 24 hours is divided into three bytes (each byte representing 8 hours, as we all know 8 bits = 1 byte). If you were to convert each byte into decimal, e.g. Joe Bloggs is allowed to log on between 12AM and 7:59AM then this in binary is 11111111 which in decimal equals 255.

If you now take the decimal number as to represent an ascii code for a character then this would become 'ÿ'.

Still with me? ....hey you at the back wake up!

This is where I get stuck on the autoit side of the code as I don't know how to retrieve the byte that represents the 'ÿ' which was extracted using the Visual Basic midB command. I know that the command extracts the byte from a string as the Visual Basic documentation states 'The MidB function is used with byte data contained in a string'. So finally I take the assumption that the raw byte would be something like 0xFF (if you apply the autoit binary command to the character 'ÿ').

so in another example:

Allowed hours 7AM-7:59AM = 00000001 = 128 = '' = 0x80?

I know that the 0x80 is probably wrong but I do know that rest of it is correct by testing with the Visual Basic script; and that the byte which is extracted each time (using midB) display as ascii characters (as shown in my example 'ÿ').

To prove my point, run the Visual Basic script and use the commands (which appear in the first FOR...NEXT loop):

WScript.Echo "MidB returns: " & MidB(arrLogonHours, i, 1)

WScript.Echo "arrLogonHoursBytes: " & arrLogonHoursBytes(i-1)

If I use the example above (Allowed hours 7AM-7:59AM) then the first line will echo '?' (which in autoit appears as ''). This line is using the 'MidB' command.

The second line (which contains the previous result with the 'AscB' command applied to it) you get 128. The visual basic then runs the function 'GetLogonHourBits(x)' to convert the decimal into binary to represent the 8 hours. The rest of the script then places the binaries in the relevant order to display on screen as 24 hours 7 days a week.

As a crude method I am now able to run an autoit script to produce the desired results by running a cut down version of the visual basic script to return the bytes external to the au3 script via the run command. The visualB script now looks like this:

Set objUser = GetObject ("LDAP://USERFQDN")
arrLogonHours = objUser.Get("logonHours")

For i = 1 To LenB(arrLogonHours)
    WScript.STDOUT.Write AscB(MidB(arrLogonHours, i, 1))
    Wscript.Sleep 1
Next

The logonhours.au3 script now looks like this:

CODE
#include <array.au3>

#include <Constants.au3>

#include <File.au3>

Dim $arrLogonHoursBytes[21]

Dim $arrLogonHoursBits[168]

Dim $arrLogonHourBits

Dim $firstday = False ;used to re-order the days as Sunday is the first in the list (we want it to display last as it does in 'AD Users & Computers .msc').

Dim $user = "CN=Bloggs\, Joe,CN=Users,DC=company,DC=com"

Dim $username = "JBloggs"

Dim $file = "c:\scripts\userlogon.vbs"

$arrDayOfWeek = _ArrayCreate ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

GUICreate ( "Logon Hours for '" & $username & "'", 500, 220 )

GUICtrlCreateLabel ( "0 . 2 . 4 . 6 . 8 . 10 . 12 .14 . 16 . 18. 20 . 22 . 0", 80, 36, 250, 13 )

$DisplayHours = GUICtrlCreateListView ( "||||||||||||||||||||||||", 80, 50, 246, 121, -1, $LVS_EX_GRIDLINES )

GUICtrlCreateLabel ( "Monday", 39, 67, 40, 13 )

GUICtrlCreateLabel ( "Tuesday", 36, 83, 45, 13 )

GUICtrlCreateLabel ( "Wednesday", 20, 98, 58, 13 )

GUICtrlCreateLabel ( "Thursday", 32, 112, 45, 13 )

GUICtrlCreateLabel ( "Friday", 48, 126, 30, 13 )

GUICtrlCreateLabel ( "Saturday", 34, 139, 43, 13 )

GUICtrlCreateLabel ( "Sunday", 40, 153, 38, 13 )

GUICtrlCreateButton ( "OK", 350, 20, 80, 25 )

GUICtrlSetState ( -1, $GUI_DISABLE )

$LHours_BTN_Cancel = GUICtrlCreateButton ( "Cancel", 350, 50, 80, 25 )

GUICtrlCreateGroup ( "", -99, -99)

GUICtrlCreateRadio ( "Logon &Permitted", 370, 120, 140, 13)

GUICtrlSetState ( -1, $GUI_DISABLE )

GUICtrlCreateRadio ( "Logon &Denied", 370, 145, 140, 13)

GUICtrlSetState ( -1, $GUI_DISABLE )

GUICtrlCreateGroup ( "", -99, -99, 1, 1) ; close group

_ReplaceStringInFile($file, "USERFQDN", $user, 0, 1 ) ; edit the VB script to run using the selected user

$DSQuery = Run ( "cscript //Nologo c:\scripts\userlogon.vbs", "", -1, $STDOUT_CHILD) ; run the VB script to return the hours

$i = 1

While 1

$DSQuery_results = StdoutRead($DSQuery)

If @error Then ExitLoop

$arrLogonHoursBytes[$i-1] = $DSQuery_results

$i += 1

Wend

_ReplaceStringInFile($file, $user, "USERFQDN", 0, 1 ) ;reset the VB script so it can be used again.

$intCounter = 0

For $LogonHourByte In $arrLogonHoursBytes

$intCounter += 1

$arrLogonHourBits &= GetLogonHourBits($LogonHourByte)

If $intCounter = 3 Then ; Each loop needs to join three '$LogonHourByte' together to represent 24 hours

$intCounter = 0

If $firstday = False Then

$Sunday = StringTrimRight($arrLogonHourBits, 1)

$firstday = True

$arrLogonHourBits = ""

Else

GUICtrlCreateListViewItem ( StringTrimRight($arrLogonHourBits, 1), $DisplayHours )

$arrLogonHourBits = ""

EndIf

EndIf

Next

GUICtrlCreateListViewItem ( $Sunday, $DisplayHours )

; setting the width of the columns representing the hours

For $i = 0 To 23

_GUICtrlListViewSetColumnWidth ( $DisplayHours, $i, 10)

Next

GUISetState()

While 1

$msg = GUIGetMsg()

Select

Case $msg = $GUI_EVENT_CLOSE

ExitLoop

Case $msg = $LHours_BTN_Cancel

ExitLoop

EndSelect

WEnd

GUIDelete()

Exit

; --------------------------------

; FUNCTIONS

; --------------------------------

Func GetLogonHourBits($x)

Local $result

Dim $arrBits[8]

; convert each number returned by the Visual Basic script into binary (each representing 8 hours in a day)

For $i = 7 to 0 Step -1

If $x >= 2^$i Then

$arrBits[$i] = chr(149)

$x = $x - 2^$i

Else

$arrBits[$i] = " "

EndIf

Next

; now we need to reverse the array's items (representing hours) as they're the wrong way around.

For $i = 0 to 7

$result &= $arrBits[$i] & "|"

Next

Return $result

EndFunc

Edited by UglyBob

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

As you can see I execute the vbasic script using a run command and pick out the results (line by line). I added the sleep command as the results were returning too quick for the autoit script to deal with. I tried using the Visual Basic script to only run the MidB command (and use my autoit script to run the "asc" conversion) but the ascii characters returned were occasionally missed by the 'StdoutRead' command.

In addition, after a little more searching on the illustrious midB command it can be used to retrieve double-byte character sets (DBCS), also known as an "expanded 8-bit character set". Midb Function

However, this does work (albeit, as I said, rather crudely done).

...and to answer your final question regarding the '$arrLogonHours' variable you get no ouput (it does contain data I just cannot view it). This is what's frustrating as I was somewhat fumbling in the dark to begin with.

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

@UglyBob

Maybe this can help you out

$strComputer = "."
 $objWMIService = ObjGet("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")

 $colItems = $objWMIService.ExecQuery _
    ("Select * from Win32_NetworkLoginProfile")

For $objItem in $colItems
        ConsoleWrite ("Caption: " & $objItem.Caption & @CRLF)
        ConsoleWrite ("Logon Hours: " & $objItem.LogonHours & @CRLF)

Next

regards,

ptrex

Link to comment
Share on other sites

no use I'm afraid, as I'm trying to interrogate a user's profile in AD rather than someone who is currently logged on a workstation. The plan is to view the details as part of my new AD admin console and (hopefully) be able to amend the details.

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

What's more infuriating is that I was bang on the mark when I stated that the data held in 'logonhours' was something like '0x80', in fact that's exactly what it's like. After viewing the attribute of a user via ADSIedit.msc this is what I can see:

Logonhours (Syntax OctetString)

Value = 80 FF 07 80 FF 07 80 FF 07 80 FF 07 80 FF 07 80 FF 07 80 FF 07 (Set as Hexidecimal)

ARRRGGHHHHH!!!! :P:);)

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

...and to answer your final question regarding the '$arrLogonHours' variable you get no ouput (it does contain data I just cannot view it). This is what's frustrating as I was somewhat fumbling in the dark to begin with.

I'm curious if you used my code to check that? I ask because I suspect it returns an array and included the IsArray() check for that reason.

At any rate, this topic is interesting and potentially useful to me, so I'll take a look on some of my own domains tomorrow. The VBScript examples seems overblown to me, and I'm itching to try it with AutoIt.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Based on the explanation found by PsaltyDs I guess you're after something like this:

Dim $week[8]
$week[1] = "00000001 11111111 11100000"
$week[2] = "00000001 11111111 11100000"
$week[3] = "00000001 11111111 11100000"
$week[4] = "00011111 11111111 11100000"
$week[5] = "00011111 11111111 11100000"
$week[6] = "00000001 11111111 11100000"
$week[7] = "00000001 11111111 11100000"

Dim $weekday[8]

For $i=1 to 7
    Dim $log_hrs[25]
    $hours = StringSplit(StringStripWS($week[$i], 8), "")
    for $j=1 to 24
        If $hours[$j] = "0" Then 
            ContinueLoop
        Else
            $log_hrs[$j] = $j&".00-"&$j+1&".00"
        EndIf
    Next
    For $k=1 to 24
        If $log_hrs[$k] <> "" Then
            $weekday[$i] &= " "&$log_hrs[$k]
        EndIf
    Next
    
Next
MsgBox (0, "Logon Hours", "Sunday: "&$weekday[1]&@CRLF&"Monday: "&$weekday[2]&@CRLF&"Tuesday: "&$weekday[3]&@CRLF&"Wednesday: "&$weekday[4]&@CRLF&"Thursday: "&$weekday[5]&@CRLF&"Friday: "&$weekday[6]&@CRLF&"Saturday: "&$weekday[7])

Now it displays a msgbox and it builds the strings for each day. If this is what you're looking for then you will have to adapt the code to suit your needs.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

I'm curious if you used my code to check that? I ask because I suspect it returns an array and included the IsArray() check for that reason.

At any rate, this topic is interesting and potentially useful to me, so I'll take a look on some of my own domains tomorrow. The VBScript examples seems overblown to me, and I'm itching to try it with AutoIt.

:)

I did try out your code, but the results were as expected, nil, zip, nada, naff all.

@enaiman

My current script already does this. Your script is using a static array to read from, the only final thing I'm trying to achieve is how to get the bytes from the logonhours octetstring.

If this is any help to you PsaltyDS I've read a little further on the octetstring issue and I've found a section on 'IADs' : IADs Property Method.

...not sure if this method can be used, tried a couple of things but to no avail.

"My God, you're looking hideously ugly today, Ugly Bob."

Link to comment
Share on other sites

OK, learned a little point the hard way: If the user doesn't have any LogonHours restrictions, then $objUser.Get("logonhours") returns a COM error number = 0x80020009! So, you need an error handler to treat that as a normal response if all hours are permitted:

#include <array.au3>

Global $oMyErrorNum, $oMyErrorDesc
$oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")

$sDomainOU = 'DC=testing,DC=domain,DC=com' 
$sUserOU = 'OU=Testing Users,OU= Users' 
$sUser = InputBox("LogonHours", "Enter user name: ")
If @error Then Exit

$objUser = ObjGet('LDAP://CN=' & $sUser & ',' & $sUserOU & ',' & $sDomainOU)
If IsObj($objUser) Then
    $arrLogonHours = $objUser.Get ("logonHours")
    If @error Then
        If @extended = 0x80020009 Then
            MsgBox(64, $sUser, "All hours permitted.")
        Else
            MsgBox(0, "", "AutoIt intercepted a COM Error !" & @CRLF & _
                    "Number is: 0x" & $oMyErrorNum & @CRLF & _
                    "Windescription is: " & $oMyErrorDesc)
        EndIf
        Exit
    Else
        If IsObj($arrLogonHours) Then
            MsgBox(64, "Object", "$arrLogonHours is an object.")
            Exit
        Else
            MsgBox(64, "Not Object", "$arrLogonHours is not an object.")
            If IsArray($arrLogonHours) Then
                _ArrayDisplay($arrLogonHours, "Debug: $arrLogonHours")
            Else
                MsgBox(64, "Debug", "$arrLogonHours = " & $arrLogonHours)
            EndIf
        EndIf
    EndIf
Else
    MsgBox(16, "Error", "Error getting user object.")
    Exit
EndIf

Func MyErrFunc()
    $oMyErrorNum = $oMyError.number
    $oMyErrorDesc = $oMyError.windescription
    
    ; something to check for when this function returns
    ; @error = 1, @extended = 32bit error number
    SetError(1, $oMyError.number)
EndFunc   ;==>MyErrFunc

As you said earlier, $arrLogonHours is not an object, therefore not a collection, and also not an array or string or any kind of integer that AutoIt would auto-convert to a string. Now that I'm past that stupid "Normal" COM error, I'll keep trying to figure out what it IS.

:)

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Adding the COM error handler to ptrex's code, plus modifying it to run compiled (required to run it on my domain where AutoIt is not installed), I get BinaryLen($arrLogonHours) = 0 every time. Still don't know what we are getting back into $arrLogonHours.

:)

; ptrex version
#include <array.au3>

Global $oMyErrorNum, $oMyErrorDesc, $sMsg = ""
$oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")

Dim $arrLogonHoursBytes[21]
Dim $arrLogonHoursBits[168]
$arrDayOfWeek = _ArrayCreate("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

$sUser = InputBox("LogonHours", "Input user name: ")
If @error Then Exit

$objUser = ObjGet("LDAP://CN=" & $sUser & ",OU=Testing Users,OU=Users,DC=testing,DC=domain,DC=com")
If IsObj($objUser) Then
    $arrLogonHours = $objUser.Get ("logonHours")
    If @error Then
        If @extended = 0x80020009 Then
            MsgBox(64, $sUser, "All hours permitted.")
        Else
            MsgBox(0, "", "AutoIt intercepted a COM Error !" & @CRLF & _
                    "Number is: 0x" & $oMyErrorNum & @CRLF & _
                    "Windescription is: " & $oMyErrorDesc)
        EndIf
        Exit
    Else
        MsgBox(64, "Debug", "BinaryLen($arrLogonHours) = " & BinaryLen($arrLogonHours))
        For $i = 1 To BinaryLen($arrLogonHours)
            $sMsg &= "Numbers " & BinaryLen($arrLogonHours)
            $arrLogonHoursBytes[$i - 1] = Asc(BinaryMid($arrLogonHours, $i, 1))
        Next

        $intCounter = 0
        $intLoopCounter = 0
        $sMsg &= "Day Byte 1 Byte 2 Byte 3" & @CRLF
        For $LogonHourByte In $arrLogonHoursBytes
            $arrLogonHourBits = GetLogonHourBits($LogonHourByte)

            If $intCounter = 0 Then
                $sMsg &= $arrDayOfWeek[$intLoopCounter] & " " 
                $intLoopCounter = $intLoopCounter + 1
            EndIf

            For $LogonHourBit In $arrLogonHourBits
                $sMsg &= $LogonHourBit
                $intCounter = 1 + $intCounter

                If $intCounter = 8 Or $intCounter = 16 Then
                    $sMsg &= " " 
                EndIf

                If $intCounter = 24 Then
                    $sMsg &= @CRLF
                    $intCounter = 0
                EndIf
            Next
        Next
        $sMsg &= @LF
        MsgBox(64, "LogonHours", $sMsg)
    EndIf
Else
    MsgBox(0, "Error", "No good LDAP connection, Try again ... ")
EndIf

Func GetLogonHourBits($x)
    Dim $arrBits[8]
    For $i = 7 To 0 Step - 1
        If $x And 2 ^ $i Then
            $arrBits[$i] = 1
        Else
            $arrBits[$i] = 0
        EndIf
    Next
    Return $arrBits
EndFunc   ;==>GetLogonHourBits

Func MyErrFunc()
    $oMyErrorNum = $oMyError.number
    $oMyErrorDesc = $oMyError.windescription
    
    ; something to check for when this function returns
    ; @error = 1, @extended = 32bit error number
    SetError(1, $oMyError.number)
EndFunc   ;==>MyErrFunc
Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Yet another bump...

Anybody have an idea how to figure out the $arrLogonHours variable? If VBScript can work it, then surely AutoIt can...?

<_<

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...