WLZAdmin Posted March 1, 2011 Posted March 1, 2011 Changing _AD_Int8ToSec isn't the way to go - I will have to change _AD_IsObjectLocked.Now _AD_IsObjectLocked returns 1 and sets @error to the number of minutes until the account is unlocked.If the account has to be unlocked by an admin the function should still return 1 but set @error to -1.What doy ou think?That would be nice and far better by design!
water Posted March 1, 2011 Author Posted March 1, 2011 I can't test it here but (I hope) this will work. Could you please replace the two functions in the UDF and try again? If an account is locked and the lockout duration time is set to 0 then function _AD_IsObjectLocked returns 1 and sets @error to -1. Func _AD_IsObjectLocked($sAD_Object = @UserName) If Not _AD_ObjectExists($sAD_Object) Then Return SetError(1, 0, 0) Local $sAD_Property = "sAMAccountName" If StringMid($sAD_Object, 3, 1) = "=" Then $sAD_Property = "distinguishedName"; FQDN provided $oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sAD_Property & "=" & $sAD_Object & ");ADsPath;subtree" Local $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object Local $sAD_LDAPEntry = $oAD_RecordSet.fields(0).value Local $oAD_Object = _AD_ObjGet($sAD_LDAPEntry) ; Retrieve the COM Object for the object Local $oAD_LockoutTime = $oAD_Object.LockoutTime ; Object is not locked out If Not IsObj($oAD_LockoutTime) Then Return ; Calculate lockout time (UTC) Local $sAD_LockoutTime = _DateAdd("s", Int(_AD_LargeInt2Double($oAD_LockoutTime.LowPart, $oAD_LockoutTime.HighPart) / (10000000)), "1601/01/01 00:00:00") ; Object is not locked out If $sAD_LockoutTime = "1601/01/01 00:00:00" Then Return ; Get password info - Account Lockout Duration Local $aAD_Temp = _AD_GetPasswordInfo($sAD_Object) ; if lockout duration is 0 (= unlock manually by admin needed) then no calculation is necessary. Set @error to -1 (minutes till the account is unlocked) If $aAD_Temp[5] = 0 Then Return SetError(-1, 0, 1) ; Calculate when the lockout will be reset Local $sAD_ResetLockoutTime = _DateAdd("n", $aAD_Temp[5], $sAD_LockoutTime) ; Compare to current date/time (UTC) Local $sAD_Now = _Date_Time_GetSystemTime() $sAD_Now = _Date_Time_SystemTimeToDateTimeStr($sAD_Now, 1) If $sAD_ResetLockoutTime >= $sAD_Now Then Return SetError(_DateDiff("n", $sAD_Now, $sAD_ResetLockoutTime), 0, 1) Return EndFunc ;==>_AD_IsObjectLocked expandcollapse popupFunc _AD_GetPasswordInfo($sAD_Object = @UserName) If _AD_ObjectExists($sAD_Object) = 0 Then Return SetError(1, 0, "") If StringMid($sAD_Object, 3, 1) <> "=" Then $sAD_Object = _AD_SamAccountNameToFQDN($sAD_Object) ; sAMAccountName provided Local $iAD_Error = 0 Local $aAD_PwdInfo[12] = [11] Local $oAD_Object = ObjGet("LDAP://" & $sAD_DNSDomain) $aAD_PwdInfo[1] = Int(_AD_Int8ToSec($oAD_Object.Get("maxPwdAge"))) / 86400 ; Convert to Days $aAD_PwdInfo[2] = _AD_Int8ToSec($oAD_Object.Get("minPwdAge")) / 86400 ; Convert to Days $aAD_PwdInfo[3] = $oAD_Object.Get("pwdHistoryLength") $aAD_PwdInfo[4] = $oAD_Object.Get("minPwdLength") ; Account lockout duration: http://msdn.microsoft.com/en-us/library/ms813429.aspx Local $oAD_Temp = $oAD_Object.Get("lockoutDuration") If $oAD_Temp.HighPart = 0x7FFFFFFF And $oAD_Temp.LowPart = 0xFFFFFFFF Then $aAD_PwdInfo[5] = 0 ; Account has to be unlocked manually by an admin Else $aAD_PwdInfo[5] = _AD_Int8ToSec($oAD_Object.Get("lockoutDuration")) / 60 ; Convert to Minutes EndIf $aAD_PwdInfo[6] = $oAD_Object.Get("lockoutThreshold") $aAD_PwdInfo[7] = _AD_Int8ToSec($oAD_Object.Get("lockoutObservationWindow")) / 60 ; Convert to Minutes Local $oAD_User = _AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_Object) Local $sAD_PwdLastChanged = $oAD_User.Get("PwdLastSet") Local $iAD_UAC = $oAD_User.userAccountControl ; Has user account password been changed before? If $sAD_PwdLastChanged.LowPart = 0 And $sAD_PwdLastChanged.HighPart = 0 Then $iAD_Error = +3 $aAD_PwdInfo[8] = "1601/01/01 00:00:00" $aAD_PwdInfo[10] = "1601/01/01 00:00:00" Else ; Is user account password set to expire? If BitAND($iAD_UAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Or $aAD_PwdInfo[1] = 0 Then If BitAND($iAD_UAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Then $iAD_Error += 2 If $aAD_PwdInfo[1] = 0 Then $iAD_Error += 4 ; The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire Else Local $sAD_Temp = DllStructCreate("dword low;dword high") DllStructSetData($sAD_Temp, "Low", $sAD_PwdLastChanged.LowPart) DllStructSetData($sAD_Temp, "High", $sAD_PwdLastChanged.HighPart) ; Have to convert to SystemTime because _Date_Time_FileTimeToStr has a bug (#1638) Local $sAD_Temp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sAD_Temp)) $aAD_PwdInfo[10] = _Date_Time_SystemTimeToDateTimeStr($sAD_Temp2, 1) $aAD_PwdInfo[11] = _DateAdd("d", $aAD_PwdInfo[1], $aAD_PwdInfo[10]) ; Convert PwdlastSet and PasswordExpires from UTC to Local Time $sAD_Temp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sAD_Temp2)) $aAD_PwdInfo[8] = _Date_Time_SystemTimeToDateTimeStr($sAD_Temp2, 1) $sAD_Temp2 = _Date_Time_EncodeSystemTime(StringMid($aAD_PwdInfo[11], 6, 2), StringMid($aAD_PwdInfo[11], 9, 2), StringMid($aAD_PwdInfo[11], 1, 4), StringMid($aAD_PwdInfo[11], 12, 2), StringMid($aAD_PwdInfo[11], 15, 2), StringMid($aAD_PwdInfo[11], 18, 2)) $sAD_Temp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sAD_Temp2)) $aAD_PwdInfo[9] = _Date_Time_SystemTimeToDateTimeStr($sAD_Temp2, 1) EndIf EndIf Return SetError($iAD_Error, 0, $aAD_PwdInfo) EndFunc ;==>_AD_GetPasswordInfo 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 Â
WLZAdmin Posted March 1, 2011 Posted March 1, 2011 Thanks for the quick code change! If I change these two lines in _AD_IsObjectLocked it works! (tested with 1 and later 2 locked users) ; $oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sAD_Property & "=" & $sAD_Object & ");ADsPath;subtree" ; Local $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object Local $sAD_Query = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sAD_Property & "=" & $sAD_Object & ");ADsPath;subtree" Local $oAD_RecordSet = $oAD_Connection.Execute($sAD_Query) ; Retrieve the ADsPath for the object
water Posted March 1, 2011 Author Posted March 1, 2011 Thanks for the quick code change! If I change these two lines in _AD_IsObjectLocked it works! (tested with 1 and later 2 locked users) ; $oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sAD_Property & "=" & $sAD_Object & ");ADsPath;subtree" ; Local $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object Local $sAD_Query = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sAD_Property & "=" & $sAD_Object & ");ADsPath;subtree" Local $oAD_RecordSet = $oAD_Connection.Execute($sAD_Query) ; Retrieve the ADsPath for the object That's fine! Sorry I didn't realize that I changed the function in another place as well. I think it's time to create the package and release a new version of the UDF. 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 Â
water Posted March 1, 2011 Author Posted March 1, 2011 (edited) Version 0.43 has been released.Please test before using in production!For download please see my signature. Edited March 1, 2011 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 Â
supersonic Posted March 2, 2011 Posted March 2, 2011 Hi water! Very well done - Version 0.43 works like a charm! Greets, -supersonic.
water Posted March 2, 2011 Author Posted March 2, 2011 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 Â
gcue Posted March 2, 2011 Posted March 2, 2011 hey water - thanks for keeping this script up to date with fixes and additions.. it truly is one of the best/most useful UDFs out there in my opinion i am having some trouble with the COM error you are registering as it is conflicting with the one i am trying to register. im using some IE.au3 functions (yet another awesome UDF!) and i get console messages that say " Cannot register internal error handler, cannot trap COM errors (Use _IEErrorHandlerRegister() to register a user error handler)" if i DONT use _IEErrorHandlerRegister() but if i do use it, i get a message saying theres already a COM ERror handler already active (which is a message coming from your COM handler)
water Posted March 2, 2011 Author Posted March 2, 2011 Hi gcue,the AD UDF checks in function _AD_Open() if there is already a COM error handler installed. The AD COM error handler is only installed when no other COM error handler is installed.The AD COM error handler is uninstalled when _AD_Close() is called.If you can "serialize" your script then this problem can be solved.Check for an COM error handlerIf you find one store it in a global variableRemove the COM error handlerCall _AD_Open(). The AD COM error handler will be installedDo you AD stuffCall _AD_Close() to remove the AD COM error handlerRestore the COM error handler from the global variableCOM error handling can become complicated because AutoIt doesn't allow for multiple error handlers at the same time. 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 Â
Marcodl Posted March 4, 2011 Posted March 4, 2011 (edited) Do you think is possible, starting from AD_ListExchangeMailboxStores to get the status of each MailboxStores ( Online/Offline ) ? Edited March 4, 2011 by Marcodl
water Posted March 4, 2011 Author Posted March 4, 2011 I don't know. Unfortunately I don't get the Stores from our environment. And I have no knowledge about the information Exchange stores in the Active Directory. If you (or anyone else) can point me to a site describing the Exchange information I can extract from Active Directory I will be happy to implement whatever you need. 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 Â
Marcodl Posted March 4, 2011 Posted March 4, 2011 this is a vbs script used for monitor Exchange server --> http://gallery.technet.microsoft.com/scriptcenter/e5dd50bc-5e69-4eb9-b544-221493e12f0d my goal is to check Exchange Services and DataStores Do you think is possible to write an udf to do it ? big thx
water Posted March 4, 2011 Author Posted March 4, 2011 Most of the script is using WMI to check the Exchange server. There's only a small part using the AD to check TLOG Drive Util for every storage group. This can easily be done with the AD UDF as it is. The rest has to be converted by you. The example script is visual basic and AutoIt is basic like so this shouldn't be a big deal. 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 Â
Stephane Posted March 11, 2011 Posted March 11, 2011 I am under a big Forest and many DC/Sites are not under my control. So I needed to point only on those that I am in control, and if I wanted to have a better result of the real "Last Login", I needed all of them. But they are under multiple sites, so I had to modify your _AD_GetLastLoginDate() to accept an Array as $sAD_Site. (Don't know if I should have renamed it $aAD_Sites... ?) Let me know if there was already something for this or if I should have done it another way. Anyway, it's yours, you can include it in your code if you like, for the next version. (The Func was taken from your 2011/03/01 version) expandcollapse popupFunc _AD_GetLastLoginDateEx($sAD_User = @UserName, $sAD_Site = "") If _AD_ObjectExists($sAD_User) = 0 Then Return SetError(1, 0, 0) Local $aAD_DCList = _AD_ListDomainControllers() Local $sAD_SingleDC, $bAD_WasIn ; Delete all DCs not belonging to the specified site If IsArray($sAD_Site) Then If UBound($sAD_Site) > 0 Then For $iAD_Count1 = $aAD_DCList[0][0] To 1 Step -1 $bAD_WasIn = False For $sAD_SingleDC in $sAD_Site If $aAD_DCList[$iAD_Count1][3] = $sAD_SingleDC Then $bAD_WasIn = True Next If Not $bAD_WasIn Then _ArrayDelete($aAD_DCList, $iAD_Count1) Next $aAD_DCList[0][0] = UBound($aAD_DCList, 1) - 1 EndIf Else If $sAD_Site <> "" Then For $iAD_Count1 = $aAD_DCList[0][0] To 1 Step -1 If $aAD_DCList[$iAD_Count1][3] <> $sAD_Site Then _ArrayDelete($aAD_DCList, $iAD_Count1) Next $aAD_DCList[0][0] = UBound($aAD_DCList, 1) - 1 EndIf EndIf ; Get LastLogin from all DCs Local $aAD_Result[$aAD_DCList[0][0] + 1] Local $sAD_LDAPEntry, $oAD_Object, $oAD_RecordSet Local $iAD_Error1 = 0, $iAD_Error2 = 0 For $iCount1 = 1 To $aAD_DCList[0][0] If Ping($aAD_DCList[$iCount1][2]) = 0 Then $iAD_Error1 += 1 ContinueLoop EndIf $oAD_Command.CommandText = "<LDAP://" & $aAD_DCList[$iCount1][2] & "/" & $sAD_DNSDomain & ">;(sAMAccountName=" & $sAD_User & ");ADsPath;subtree" $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object ; -2147352567 or 0x80020009 is returned when the service is not operational If @error = -2147352567 Or $oAD_RecordSet.RecordCount = 0 Then $iAD_Error1 += 1 Else $sAD_LDAPEntry = $oAD_RecordSet.fields(0).value $oAD_Object = _AD_ObjGet($sAD_LDAPEntry) ; Retrieve the COM Object for the object $aAD_Result[$iCount1] = $oAD_Object.LastLogin ; -2147352567 or 0x80020009 is returned when the attribute "LastLogin" isn't defined on this DC If @error = -2147352567 Then $iAD_Error2 += 1 $oAD_Object.PurgePropertyList EndIf Next _ArraySort($aAD_Result, 1, 1) ; If error count equals the number of DCs then the user has never logged in If $iAD_Error2 = $aAD_DCList[0][0] Then Return SetError(2, 0, 0) Return SetError($iAD_Error1, $aAD_DCList[0][0], $aAD_Result[1]) EndFunc ;==>_AD_GetLastLoginDate Version 0.43 has been released. Please test before using in production! For download please see my signature.
Katharsis Posted March 12, 2011 Posted March 12, 2011 (edited) Thanks so much for these tools! I wish I had discovered this a long time ago. It's helping me a lot.I do have one question about _AD_GetPasswordDontExpire. I would like to use it in just a single OU, not the whole domain. However, there's no option for that, and when I try to connect with _AD_Open only specifying the OU I want, I still get a list of every account in the domain whose passwords don't expire. I'm using this format:_AD_Open("", "", "", "domain controller", "OU=TheOUIWant,OU=MainOU,DC=something,DC=com") $array = _AD_GetPasswordDontExpire()I know it's probably something I'm doing wrong. I just discovered these tools today. Edited March 12, 2011 by Katharsis
water Posted March 12, 2011 Author Posted March 12, 2011 (edited) @Stephane Thank you very much for this addition. Everything that enhances the UDF is welcome. I will include it in the next version. Edited March 12, 2011 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 Â
water Posted March 12, 2011 Author Posted March 12, 2011 @Katharsis At the moment you can't specify the OU to limit the search. I will have a look at it next week and maybe can come up with a solution. 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 Â
water Posted March 12, 2011 Author Posted March 12, 2011 (edited) @Katharsis please replace function _AD_GetpasswordDontExpire with this modified version. As first parameter pass the OU (Fully qualified domain name) where the search should start. In your case: $array = _AD_GetPasswordDontExpire("OU=TheOUIWant,OU=MainOU,DC=something,DC=com") Please test and post the results. If it works I will change more functions so that you can pass the starting point for the search: ; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_GetPasswordDontExpire ; Description ...: Returns an array of user account FQDNs where the password does not expire. ; Syntax.........: _AD_GetPasswordDontExpire([$sAD_OU = ""]) ; Parameters ....: $sAD_OU - Optional: FQDN of the OU where the search should start (default = "" = serach the whole tree) ; Return values .: Success - Array with FQDNs of user accounts for which the password does not expire ; Failure - "", sets @error to: ; |1 - No user accounts for which the password does not expire ; Author ........: Jonathan Clelland ; Modified.......: water ; Remarks .......: ; Related .......: _AD_IsPasswordExpired, _AD_GetPasswordExpired, _AD_SetPassword, _AD_DisablePasswordExpire, _AD_EnablePasswordExpire, _AD_EnablePasswordChange, _AD_DisablePasswordChange, _AD_GetPasswordInfo ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _AD_GetPasswordDontExpire($sAD_OU = "") If $sAD_OU = "" Then $sAD_OU = $sAD_DNSDomain $oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_OU & ">;(&(objectcategory=user)(userAccountControl:1.2.840.113556.1.4.803:=" & _ $ADS_UF_DONT_EXPIRE_PASSWD & "));distinguishedName;subtree" Local $oAD_RecordSet = $oAD_Command.Execute If Not IsObj($oAD_RecordSet) Or $oAD_RecordSet.RecordCount = 0 Then Return SetError(1, 0, "") Local $aAD_FQDN[$oAD_RecordSet.RecordCount + 1] $aAD_FQDN[0] = $oAD_RecordSet.RecordCount Local $iCount1 = 1 While Not $oAD_RecordSet.EOF $aAD_FQDN[$iCount1] = $oAD_RecordSet.Fields(0).Value $iCount1 += 1 $oAD_RecordSet.MoveNext WEnd Return $aAD_FQDN EndFunc ;==>_AD_GetPasswordDontExpire Edited March 12, 2011 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 Â
water Posted March 12, 2011 Author Posted March 12, 2011 (edited) @Stephane, I've modified the function a bit. You can now specifiy multiple sites as a comma separated list. No need to create an array before calling the function. If you already have an array you can easily make a string out of it using _ArrayToString($avArray , ","). The benefit is that the user calling this function does not have to switch between string and array. And yes, the code got a lot smaller. The modified function will be part of the next release. Thanks for taking the time to enhance the UDF! expandcollapse popupFunc _AD_GetLastLoginDate($sAD_User = @UserName, $sAD_Site = "") If _AD_ObjectExists($sAD_User) = 0 Then Return SetError(1, 0, 0) Local $aAD_DCList = _AD_ListDomainControllers() Local $aAD_Site, $sAD_SingleDC, $bAD_WasIn ; Delete all DCs not belonging to the specified site $aAD_Site = StringSplit($sAD_Site, ",", 2) If UBound($aAD_Site) > 0 And $aAD_Site[0] <> "" Then For $iAD_Count1 = $aAD_DCList[0][0] To 1 Step -1 $bAD_WasIn = False For $sAD_SingleDC In $aAD_Site If $aAD_DCList[$iAD_Count1][3] = $sAD_SingleDC Then $bAD_WasIn = True Next If Not $bAD_WasIn Then _ArrayDelete($aAD_DCList, $iAD_Count1) Next $aAD_DCList[0][0] = UBound($aAD_DCList, 1) - 1 EndIf ; Get LastLogin from all DCs Local $aAD_Result[$aAD_DCList[0][0] + 1] Local $sAD_LDAPEntry, $oAD_Object, $oAD_RecordSet Local $iAD_Error1 = 0, $iAD_Error2 = 0 For $iCount1 = 1 To $aAD_DCList[0][0] If Ping($aAD_DCList[$iCount1][2]) = 0 Then $iAD_Error1 += 1 ContinueLoop EndIf $oAD_Command.CommandText = "<LDAP://" & $aAD_DCList[$iCount1][2] & "/" & $sAD_DNSDomain & ">;(sAMAccountName=" & $sAD_User & ");ADsPath;subtree" $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object ; -2147352567 or 0x80020009 is returned when the service is not operational If @error = -2147352567 Or $oAD_RecordSet.RecordCount = 0 Then $iAD_Error1 += 1 Else $sAD_LDAPEntry = $oAD_RecordSet.fields(0).value $oAD_Object = _AD_ObjGet($sAD_LDAPEntry) ; Retrieve the COM Object for the object $aAD_Result[$iCount1] = $oAD_Object.LastLogin ; -2147352567 or 0x80020009 is returned when the attribute "LastLogin" isn't defined on this DC If @error = -2147352567 Then $iAD_Error2 += 1 $oAD_Object.PurgePropertyList EndIf Next _ArraySort($aAD_Result, 1, 1) ; If error count equals the number of DCs then the user has never logged in If $iAD_Error2 = $aAD_DCList[0][0] Then Return SetError(2, 0, 0) Return SetError($iAD_Error1, $aAD_DCList[0][0], $aAD_Result[1]) EndFunc ;==>_AD_GetLastLoginDate Edited March 12, 2011 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 Â
Recommended Posts