UglyBob Posted October 11, 2007 Share Posted October 11, 2007 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: CODEOn 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 More sharing options...
ptrex Posted October 11, 2007 Share Posted October 11, 2007 @UglyBob Tey this : expandcollapse popup#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 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
UglyBob Posted October 12, 2007 Author Share Posted October 12, 2007 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 More sharing options...
ptrex Posted October 12, 2007 Share Posted October 12, 2007 @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 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
UglyBob Posted October 12, 2007 Author Share Posted October 12, 2007 (edited) The VB script works fine.the results appear something like this:Day Byte 1 Byte 2 Byte 3Sun 00000001 11111111 11100000Mon 00000001 11111111 11100000Tue 00000001 11111111 11100000Wed 00011111 11111111 11100000Thu 00011111 11111111 11100000Fri 00000001 11111111 11100000Sat 00000001 11111111 111000001'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)withFor $i = 1 To 21This 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.@UglyBobDidi the VBScript return anything ?Because when I ran it, it did not on my side ?Please check if that runs OK.Regardsptrex Edited October 12, 2007 by UglyBob "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
ptrex Posted October 12, 2007 Share Posted October 12, 2007 (edited) @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 October 12, 2007 by ptrex Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
UglyBob Posted October 13, 2007 Author Share Posted October 13, 2007 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 More sharing options...
PsaltyDS Posted October 13, 2007 Share Posted October 13, 2007 (edited) 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 October 13, 2007 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 More sharing options...
UglyBob Posted October 14, 2007 Author Share Posted October 14, 2007 (edited) 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 October 14, 2007 by UglyBob "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
UglyBob Posted October 14, 2007 Author Share Posted October 14, 2007 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 FunctionHowever, 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 More sharing options...
ptrex Posted October 14, 2007 Share Posted October 14, 2007 @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 Contributions :Firewall Log Analyzer for XP - Creating COM objects without a need of DLL's - UPnP support in AU3Crystal Reports Viewer - PDFCreator in AutoIT - Duplicate File FinderSQLite3 Database functionality - USB Monitoring - Reading Excel using SQLRun Au3 as a Windows Service - File Monitor - Embedded Flash PlayerDynamic Functions - Control Panel Applets - Digital Signing Code - Excel Grid In AutoIT - Constants for Special Folders in WindowsRead data from Any Windows Edit Control - SOAP and Web Services in AutoIT - Barcode Printing Using PS - AU3 on LightTD WebserverMS LogParser SQL Engine in AutoIT - ImageMagick Image Processing - Converter @ Dec - Hex - Bin -Email Address Encoder - MSI Editor - SNMP - MIB ProtocolFinancial Functions UDF - Set ACL Permissions - Syntax HighLighter for AU3ADOR.RecordSet approach - Real OCR - HTTP Disk - PDF Reader Personal Worldclock - MS Indexing Engine - Printing ControlsGuiListView - Navigation (break the 4000 Limit barrier) - Registration Free COM DLL Distribution - Update - WinRM SMART Analysis - COM Object Browser - Excel PivotTable Object - VLC Media Player - Windows LogOnOff Gui -Extract Data from Outlook to Word & Excel - Analyze Event ID 4226 - DotNet Compiler Wrapper - Powershell_COM - New Link to comment Share on other sites More sharing options...
UglyBob Posted October 14, 2007 Author Share Posted October 14, 2007 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 More sharing options...
UglyBob Posted October 14, 2007 Author Share Posted October 14, 2007 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!!!! "My God, you're looking hideously ugly today, Ugly Bob." Link to comment Share on other sites More sharing options...
PsaltyDS Posted October 14, 2007 Share Posted October 14, 2007 ...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 More sharing options...
enaiman Posted October 14, 2007 Share Posted October 14, 2007 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 More sharing options...
UglyBob Posted October 15, 2007 Author Share Posted October 15, 2007 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. @enaimanMy 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 More sharing options...
PsaltyDS Posted October 15, 2007 Share Posted October 15, 2007 (edited) 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:expandcollapse popup#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 ;==>MyErrFuncAs 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 October 15, 2007 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 More sharing options...
PsaltyDS Posted October 15, 2007 Share Posted October 15, 2007 (edited) 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. expandcollapse popup; 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 October 15, 2007 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 More sharing options...
PsaltyDS Posted October 16, 2007 Share Posted October 16, 2007 Free bump. Need help from smart people. Helllooooo, smart people...? 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 More sharing options...
PsaltyDS Posted October 19, 2007 Share Posted October 19, 2007 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now