dkwokgs Posted November 7, 2008 Posted November 7, 2008 (edited) Hi There, Can someone advise me how to do pull all Users "Last Logon" information and existence of a user/computer account from an OU in Active Directory? Thanks. Edited November 7, 2008 by dkwokgs
Airwolf Posted November 7, 2008 Posted November 7, 2008 I would suggest doing some reading about LDAP lookups and COM objects. For an example, take a look at the ADUC Computers OU Cleanup script linked in my signature. COM objects in AutoIt are very similar to VBS. You can populate an array based on an LDAP query and then work with the LastLogon property of each object in the array. Certifications: A+, Network+, Security+, Linux+, LPIC-1, MCSA | Languages: AutoIt, C, SQL, .NETBooks: AutoIt v3: Your Quick Guide - $7.99 - O'Reilly Media - September 2007-------->[u]AutoIt v3 Development - newbie to g33k[/u] - Coming Soon - Fate Publishing - Spring 2013UDF Libraries: SkypeCOM UDF Library | ADUC Computers OU Cleanup | Find PixelChecksumExamples: Skype COM Examples - Skype4COMLib Examples converted from VBS to AutoIt
PsaltyDS Posted November 7, 2008 Posted November 7, 2008 Hi There, Can someone advise me how to do pull all Users "Last Logon" information and existence of a user/computer account from an OU in Active Directory? Thanks. Something like this, but I can't test the UINT64 conversion right now: #include <Date.au3> Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") Global $sServer = "myserver.mydomain.com" Global $sUserPath = "cn=User Name, ou=Users, dc=mydomain, dc=com" Global $oUser, $oLastLogon, $iLastLogon ; Get user object Local $oUser = ObjGet("LDAP://" & $sServer & "/" & $sUserPath) If IsObj($oUser) Then $oLastLogon = $oUser.Get("lastLogon") ; Convert INT64 to float $iLastLogon = $oLastLogon.HighPart * (2^32) $iLastLogon += $oLastLogon.LowPart ; Convert 100ns count to seconds $iDays = Floor($iLastLogon / 10000000) ; Convert seconds since 12:00AM January 01, 1601 $sLastLogon _DateAdd("S", $iLastLogon, "1601/01/01 00:00:00") MsgBox(64, "Last Logon", "User " & $oUser.Name & " last logged on at " & $sLastLogon) Else MsgBox(16, "Error", "$oUser is not an object.") EndIf Func MyErrFunc() $HexNumber = Hex($oMyError.number, 8) MsgBox(0, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription) $g_eventerror = 1; something to check for when this function returns EndFunc ;==>MyErrFunc 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
water Posted November 7, 2008 Posted November 7, 2008 (edited) Hi dkwokgs,for AD access you could use the AD UDF which can be found at http://www.autoitscript.com/forum/index.php?showtopic=37378 or http://www.autoitscript.com/forum/index.ph...st&id=22018To check if a CN (User, Computer ...) exists in an OU I would use something like:#include <adfunctions.au3> $ou = "DC=microsoft,DC=com" ; Root of your AD If Not _ADObjectExists(<SamAccountName>) ..LASTLOGON:Be careful with the lastlogon date. Because the lastLogon attribute is not replicated in Active Directory, a different value can be stored in the copy of Active Directory on each Domain Controller.There are a lot of tools available from the internet to check the true last logon date/time. Search for "active directory true last logon".See: http://msdn.microsoft.com/en-us/library/ms676823(VS.85).aspx and http://msdn.microsoft.com/en-us/library/ms676824.aspxHTHThomas Edited November 7, 2008 by water My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Â
PsaltyDS Posted November 7, 2008 Posted November 7, 2008 (edited) I'd like to make this work in AutoIt for myself, but I hit a glitch. This works for a user that has logged in authenticated by the DC being queried: expandcollapse popup#include <Date.au3> Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") Global $sServer = "MyDC.MyDomain.com" Global $sUserPath = "cn=My User, ou=Users, dc=MyDomain, dc=com" Global $oUser, $oLastLogon, $iLastLogon = 0 ; Get user object Local $oUser = ObjGet("LDAP://" & $sServer & "/" & $sUserPath) If IsObj($oUser) Then $oLastLogon = $oUser.Get("lastLogon") If @error Then MsgBox(16, 'Debug', 'Error occured retreiving $oUser.Get("lasLogon").' & @CRLF & _ 'This attribute may not exist for this user (never logged in by this DC).') Else ; Convert IADsLargeInteger parts to 100ns count $iLastLogonHigh = $oLastLogon.HighPart $iLastLogonLow = $oLastLogon.LowPart If $iLastLogonLow < 0 Then $iLastLogonHigh += 1; Compensate for IADsLargeInteger interface error $iLastLogon = $iLastLogonHigh * 2 ^ 32 $iLastLogon += $iLastLogonLow ; Convert 100ns count to integer seconds $iSeconds = Floor($iLastLogon / 10000000) ; Convert seconds since 12:00AM January 01, 1601 to date string $sLastLogon = _DateAdd("S", $iSeconds, "1601/01/01 00:00:00") ; Display result MsgBox(64, "Last Logon", "$sLastLogon = " & $sLastLogon & " Zulu (UTC)") EndIf Else MsgBox(16, "Error", "$oUser is not an object, user may not exist.") EndIf Func MyErrFunc() MsgBox(16, "AutoIt COM Error", "AutoIt intercepted a COM Error:" & @CRLF & _ "Number is: " & Hex($oMyError.number, 8) & @CRLF & _ "Windescription is: " & $oMyError.windescription) SetError(1) EndFunc;==>MyErrFunc Note the conversion of the time code had to be updated, but looks good now. The problem is the "lastLogon" attribute seems to not exist at all if the user has never logged on (via this DC at least). So I get COM errors on those users. How would I check if "lastLogon" attribute exists for $oUser without triggering COM errors? Edit1: Removed unnecessary conversion from seconds to days. Edit2: Put back missing EndIf. Edited November 7, 2008 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
water Posted November 7, 2008 Posted November 7, 2008 (edited) Hi PsaltyDS,How would I check if "lastLogon" attribute exists for $oUser without triggering COM errors?Maybe the AD UDF would be a good place to start. See post #4 for the download links.It installs a custom error handler and returns 0 if the object or attribute doesn't exist. Check _ADDoError() and _ADGetObjectAttribute()HTHThomas Edited November 7, 2008 by water My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Â
PsaltyDS Posted November 7, 2008 Posted November 7, 2008 (edited) Hi PsaltyDS, Maybe the AD UDF would be a good place to start. See post #4 for the download links. It installs a custom error handler and returns 0 if the object or attribute doesn't exist. Check _ADDoError() and _ADGetObjectAttribute() HTH Thomas The _ADGetObjectAttribute() function will return the lastLogon attribute object, but you still need the conversion process to get a date out of it. As for my problem above, that was just me being drifty... What I thought was my test user that had never logged on was in fact a Group for test users, which is why it didn't have a lastLogon attribute. Now that I am using a real account that has never logged on, it simply returns the IADsLargeInteger equivalent of 0. To avoid getting last logon date of "1601/01/01 00:00:00" I added a catch for that condition, and it all works now: expandcollapse popup#include <Date.au3> Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") Global $sServer = "MyDC.MyDomain.com" Global $sUserPath = "cn=My User, ou=Users, dc=MyDomain, dc=com" Global $oUser, $oLastLogon, $iLastLogon = 0 ; Get user object Local $oUser = ObjGet("LDAP://" & $sServer & "/" & $sUserPath) If IsObj($oUser) Then $oLastLogon = $oUser.Get("lastLogon") If @error Then MsgBox(16, 'Debug', 'Error occured retreiving $oUser.Get("lastLogon").' & @CRLF & _ 'This attribute may not exist for this object.') Else ; Convert IADsLargeInteger parts to 100ns count $iLastLogonHigh = $oLastLogon.HighPart $iLastLogonLow = $oLastLogon.LowPart If $iLastLogonLow < 0 Then $iLastLogonHigh += 1; Compensate for IADsLargeInteger interface error $iLastLogon = $iLastLogonHigh * 2 ^ 32 $iLastLogon += $iLastLogonLow ; Check if user ever logged in If $iLastLogon = 0 Then MsgBox(64, "Last Logon", "User has never logged on.") Else ; Convert 100ns count to integer seconds $iSeconds = Floor($iLastLogon / 10000000) ; Convert seconds since 12:00AM January 01, 1601 to date string $sLastLogon = _DateAdd("S", $iSeconds, "1601/01/01 00:00:00") ; Display result MsgBox(64, "Last Logon", "$sLastLogon = " & $sLastLogon & " Zulu (UTC)") EndIf EndIf Else MsgBox(16, "Error", "$oUser is not an object, user may not exist.") EndIf Func MyErrFunc() MsgBox(16, "AutoIt COM Error", "AutoIt intercepted a COM Error:" & @CRLF & _ "Number is: " & Hex($oMyError.number, 8) & @CRLF & _ "Windescription is: " & $oMyError.windescription) SetError(1) EndFunc;==>MyErrFunc The trick way to do this would be check that $oUser was in fact a "User" type object first, but it's Friday and sunny outside and I'm losing the will to script! Edited November 7, 2008 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
supersonic Posted April 1, 2009 Posted April 1, 2009 Hello! Superb! That's what I was looking for so looong... BUT: When try running this script, I get a COM error (such an object is not availiable). My PC: XP SP3. Any ideas? Greets, -supersonic.
PsaltyDS Posted April 1, 2009 Posted April 1, 2009 Hello!Superb! That's what I was looking for so looong...BUT: When try running this script, I get a COMerror (such an object is not availiable).My PC: XP SP3.Any ideas?Greets,-supersonic.The script is for an AD domain. Are you trying to run it on a workgroup or stand-alone PC? 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
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