Jump to content

Active Directory UDF - Help & Support (III)


Recommended Posts

If you run _AD_GetObjectProperties for the user, what's the value of property "lockouttime"?

 

locked:

lockoutTime = 2014/05/20 10:41:06

not locked:

lockoutTime = 1601/01/01 00:00:00

Edited by Tim33
Link to post
Share on other sites
  • Replies 835
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Could you please add the following function to your script and call _AD_ListDomainControllersEX instead of _AD_ListDomainControllers? The error should be gone. ; #FUNCTION# ==================

Fixed in the 1.5.0.1 version of the UDF which I uploaded today.

& stands for AND | stands for OR You are looking for groups whose name start with APZ_ OR APPL_ OR CPZ_PRD_. The syntax gets a bit more complex now: "(&(objectcategory=group)(|(na

Posted Images

How long do you lock a user?

Do you use the fine grained password policy?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

How long do you lock a user?

Do you use the fine grained password policy?

 

How long do you lock a user?

Account lockout duration: 0 minutes

Account lockout threshold: 5 invalid logon attempts

Reset account lockout counter after: 3 minutes

 

Do you use the fine grained password policy?

No

 

Edited by Tim33
Link to post
Share on other sites

Lockout duration 0 minutes means that the user has to  be unlocked by an administrator.. Is this correct?

But in this case the function should set the return value to 1 and @error to -1.

Strange.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

If you run this script, what do you get?

#include <AD.au3>

; Open Connection to the Active Directory
_AD_Open()
If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended)

; Get the password info
Global $aAD_PwdInfo[13][2] = [[12],["Maximum Password Age (days)"],["Minimum Password Age (days)"],["Enforce Password History (# of passwords remembered)"], _
        ["Minimum Password Length"],["Account Lockout Duration (minutes)"],["Account Lockout Threshold (invalid logon attempts)"],["Reset account lockout counter after (minutes)"], _
        ["Password last changed (YYYY/MM/DD HH:MM:SS local time)"],["Password expires (YYYY/MM/DD HH:MM:SS local time)"],["Password last changed (YYYY/MM/DD HH:MM:SS UTC)"], _
        ["Password expires (YYYY/MM/DD HH:MM:SS UTC)"],["Password properties"]]

Global $aTemp = _AD_GetPasswordInfo()
For $iCount = 1 To $aTemp[0]
    $aAD_PwdInfo[$iCount][1] = $aTemp[$iCount]
Next
$aAD_PwdInfo[0][0] = $aTemp[0]

_ArrayDisplay($aAD_PwdInfo, "Active Directory Functions - Example 1")

; Close Connection to the Active Directory
_AD_Close()

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

Water,

As relates to our question of slowness in Windows 8, the _AD_GetGroupMembers function returns fairly quickly, as does the _AD_GetObjectsInOU function. Is there a "hybrid" type function to allow me to GetGroupMembers and get a list of their properties all in one call?

Thanks again for all your help!!!

Link to post
Share on other sites

 

If you run this script, what do you get?

#include <AD.au3>

; Open Connection to the Active Directory
_AD_Open()
If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended)

; Get the password info
Global $aAD_PwdInfo[13][2] = [[12],["Maximum Password Age (days)"],["Minimum Password Age (days)"],["Enforce Password History (# of passwords remembered)"], _
        ["Minimum Password Length"],["Account Lockout Duration (minutes)"],["Account Lockout Threshold (invalid logon attempts)"],["Reset account lockout counter after (minutes)"], _
        ["Password last changed (YYYY/MM/DD HH:MM:SS local time)"],["Password expires (YYYY/MM/DD HH:MM:SS local time)"],["Password last changed (YYYY/MM/DD HH:MM:SS UTC)"], _
        ["Password expires (YYYY/MM/DD HH:MM:SS UTC)"],["Password properties"]]

Global $aTemp = _AD_GetPasswordInfo()
For $iCount = 1 To $aTemp[0]
    $aAD_PwdInfo[$iCount][1] = $aTemp[$iCount]
Next
$aAD_PwdInfo[0][0] = $aTemp[0]

_ArrayDisplay($aAD_PwdInfo, "Active Directory Functions - Example 1")

; Close Connection to the Active Directory
_AD_Close()

 

12|

Maximum Password Age (days)|31

Minimum Password Age (days)|1

Enforce Password History (# of passwords remembered)|6

Minimum Password Length|6

Account Lockout Duration (minutes)|-15372286728.0913

Account Lockout Threshold (invalid logon attempts)|5

Reset account lockout counter after (minutes)|3

Password last changed (YYYY/MM/DD HH:MM:SS local time)|2012/05/14 11:08:22

Password expires (YYYY/MM/DD HH:MM:SS local time)|

Password last changed (YYYY/MM/DD HH:MM:SS UTC)|2012/05/14 09:08:22

Password expires (YYYY/MM/DD HH:MM:SS UTC)|

Password properties|0

---

Lockout duration 0 minutes means that the user has to  be unlocked by an administrator.. Is this correct?

Yes

 

Edited by Tim33
Link to post
Share on other sites

Water,

As relates to our question of slowness in Windows 8, the _AD_GetGroupMembers function returns fairly quickly, as does the _AD_GetObjectsInOU function. Is there a "hybrid" type function to allow me to GetGroupMembers and get a list of their properties all in one call?

Thanks again for all your help!!!

Unfortunately not. Because you have to query two different objects: the group for the members attribute and the members for their properties.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

Lockout duration 0 minutes means that the user has to  be unlocked by an administrator.. Is this correct?

Yes

What do you get for domainControllerFunctionality, domainFunctionality and forestFunctionality when you run the _AD_ListRootDSEAttributes.au3 example script?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

I ask because I think the value for Account Lockout Duration (minutes) is quite strange (-15372286728.0913).

Maybe they added something new to the latest Windows vesion?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

What do you get for domainControllerFunctionality, domainFunctionality and forestFunctionality when you run the _AD_ListRootDSEAttributes.au3 example script?

 

domainControllerFunctionality|5

domainFunctionality|5

forestFunctionality|5

 

Link to post
Share on other sites

So this is a Windows 2012 domain. I wil check what has changed.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

What do you get written to the console when you run this exampel script:

#AutoIt3Wrapper_AU3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=Y
; *****************************************************************************
; Example 1
; Get the domain password policy and the password info for the current user
; *****************************************************************************
#include <AD.au3>

; Open Connection to the Active Directory
_AD_Open()
If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended)

; Get the password info
Global $aAD_PwdInfo[13][2] = [[12],["Maximum Password Age (days)"],["Minimum Password Age (days)"],["Enforce Password History (# of passwords remembered)"], _
        ["Minimum Password Length"],["Account Lockout Duration (minutes)"],["Account Lockout Threshold (invalid logon attempts)"],["Reset account lockout counter after (minutes)"], _
        ["Password last changed (YYYY/MM/DD HH:MM:SS local time)"],["Password expires (YYYY/MM/DD HH:MM:SS local time)"],["Password last changed (YYYY/MM/DD HH:MM:SS UTC)"], _
        ["Password expires (YYYY/MM/DD HH:MM:SS UTC)"],["Password properties"]]

Global $aTemp = _AD_GetPasswordInfoEX()
For $iCount = 1 To $aTemp[0]
    $aAD_PwdInfo[$iCount][1] = $aTemp[$iCount]
Next
$aAD_PwdInfo[0][0] = $aTemp[0]

_ArrayDisplay($aAD_PwdInfo, "Active Directory Functions - Example 1")

; Close Connection to the Active Directory
_AD_Close()

Func _AD_GetPasswordInfoEX($sObject = @UserName)

    If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 0, "")
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided
    Local $iError = 0
    Local $aPwdInfo[13] = [12]
    Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain)
    $aPwdInfo[1] = Int(__AD_Int8ToSec($oObject.Get("maxPwdAge"))) / 86400 ; Convert to Days
    $aPwdInfo[2] = __AD_Int8ToSec($oObject.Get("minPwdAge")) / 86400 ; Convert to Days
    $aPwdInfo[3] = $oObject.Get("pwdHistoryLength")
    $aPwdInfo[4] = $oObject.Get("minPwdLength")
    ; Account lockout duration: http://msdn.microsoft.com/en-us/library/ms813429.aspx
    Local $oTemp = $oObject.Get("lockoutDuration")
ConsoleWrite("High: " & $oTemp.HighPart & " " & Hex($oTemp.HighPart,8) & @LF)
ConsoleWrite("Low : " & $oTemp.LowPart & " " & Hex($oTemp.LowPart,8) & @LF)
    If $oTemp.HighPart = 0x7FFFFFFF And $oTemp.LowPart = 0xFFFFFFFF Then
        $aPwdInfo[5] = 0 ; Account has to be unlocked manually by an admin
    Else
        $aPwdInfo[5] = __AD_Int8ToSec($oTemp) / 60 ; Convert to Minutes
    EndIf
    $aPwdInfo[6] = $oObject.Get("lockoutThreshold")
    $aPwdInfo[7] = __AD_Int8ToSec($oObject.Get("lockoutObservationWindow")) / 60 ; Convert to Minutes
    Local $oUser = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject)
    Local $sPwdLastChanged = $oUser.Get("PwdLastSet")
    Local $iUAC = $oUser.userAccountControl
    ; Has user account password been changed before?
    If $sPwdLastChanged.LowPart = 0 And $sPwdLastChanged.HighPart = 0 Then
        $iError += 3
        $aPwdInfo[8] = "1601/01/01 00:00:00"
        $aPwdInfo[10] = "1601/01/01 00:00:00"
    Else
        Local $sTemp = DllStructCreate("dword low;dword high")
        DllStructSetData($sTemp, "Low", $sPwdLastChanged.LowPart)
        DllStructSetData($sTemp, "High", $sPwdLastChanged.HighPart)
        ; Have to convert to SystemTime because _Date_Time_FileTimeToStr has a bug (#1638)
        Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp))
        $aPwdInfo[10] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Convert PwdlastSet from UTC to Local Time
        $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
        $aPwdInfo[8] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Is user account password set to expire?
        If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Or $aPwdInfo[1] = 0 Then
            If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Then $iError += 2
            If $aPwdInfo[1] = 0 Then $iError += 4 ; The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire
        Else
            $aPwdInfo[11] = _DateAdd("d", $aPwdInfo[1], $aPwdInfo[10])
            $sTemp2 = _Date_Time_EncodeSystemTime(StringMid($aPwdInfo[11], 6, 2), StringMid($aPwdInfo[11], 9, 2), StringMid($aPwdInfo[11], 1, 4), StringMid($aPwdInfo[11], 12, 2), StringMid($aPwdInfo[11], 15, 2), StringMid($aPwdInfo[11], 18, 2))
            ; Convert PasswordExpires from UTC to Local Time
            $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
            $aPwdInfo[9] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        EndIf
    EndIf
    $aPwdInfo[12] = $oObject.Get("pwdProperties")
    Return SetError($iError, 0, $aPwdInfo)

EndFunc   ;==>_AD_GetPasswordInfo

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

 

What do you get written to the console when you run this exampel script:

#AutoIt3Wrapper_AU3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#AutoIt3Wrapper_AU3Check_Stop_OnWarning=Y
; *****************************************************************************
; Example 1
; Get the domain password policy and the password info for the current user
; *****************************************************************************
#include <AD.au3>

; Open Connection to the Active Directory
_AD_Open()
If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended)

; Get the password info
Global $aAD_PwdInfo[13][2] = [[12],["Maximum Password Age (days)"],["Minimum Password Age (days)"],["Enforce Password History (# of passwords remembered)"], _
        ["Minimum Password Length"],["Account Lockout Duration (minutes)"],["Account Lockout Threshold (invalid logon attempts)"],["Reset account lockout counter after (minutes)"], _
        ["Password last changed (YYYY/MM/DD HH:MM:SS local time)"],["Password expires (YYYY/MM/DD HH:MM:SS local time)"],["Password last changed (YYYY/MM/DD HH:MM:SS UTC)"], _
        ["Password expires (YYYY/MM/DD HH:MM:SS UTC)"],["Password properties"]]

Global $aTemp = _AD_GetPasswordInfoEX()
For $iCount = 1 To $aTemp[0]
    $aAD_PwdInfo[$iCount][1] = $aTemp[$iCount]
Next
$aAD_PwdInfo[0][0] = $aTemp[0]

_ArrayDisplay($aAD_PwdInfo, "Active Directory Functions - Example 1")

; Close Connection to the Active Directory
_AD_Close()

Func _AD_GetPasswordInfoEX($sObject = @UserName)

    If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 0, "")
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided
    Local $iError = 0
    Local $aPwdInfo[13] = [12]
    Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain)
    $aPwdInfo[1] = Int(__AD_Int8ToSec($oObject.Get("maxPwdAge"))) / 86400 ; Convert to Days
    $aPwdInfo[2] = __AD_Int8ToSec($oObject.Get("minPwdAge")) / 86400 ; Convert to Days
    $aPwdInfo[3] = $oObject.Get("pwdHistoryLength")
    $aPwdInfo[4] = $oObject.Get("minPwdLength")
    ; Account lockout duration: http://msdn.microsoft.com/en-us/library/ms813429.aspx
    Local $oTemp = $oObject.Get("lockoutDuration")
ConsoleWrite("High: " & $oTemp.HighPart & " " & Hex($oTemp.HighPart,8) & @LF)
ConsoleWrite("Low : " & $oTemp.LowPart & " " & Hex($oTemp.LowPart,8) & @LF)
    If $oTemp.HighPart = 0x7FFFFFFF And $oTemp.LowPart = 0xFFFFFFFF Then
        $aPwdInfo[5] = 0 ; Account has to be unlocked manually by an admin
    Else
        $aPwdInfo[5] = __AD_Int8ToSec($oTemp) / 60 ; Convert to Minutes
    EndIf
    $aPwdInfo[6] = $oObject.Get("lockoutThreshold")
    $aPwdInfo[7] = __AD_Int8ToSec($oObject.Get("lockoutObservationWindow")) / 60 ; Convert to Minutes
    Local $oUser = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject)
    Local $sPwdLastChanged = $oUser.Get("PwdLastSet")
    Local $iUAC = $oUser.userAccountControl
    ; Has user account password been changed before?
    If $sPwdLastChanged.LowPart = 0 And $sPwdLastChanged.HighPart = 0 Then
        $iError += 3
        $aPwdInfo[8] = "1601/01/01 00:00:00"
        $aPwdInfo[10] = "1601/01/01 00:00:00"
    Else
        Local $sTemp = DllStructCreate("dword low;dword high")
        DllStructSetData($sTemp, "Low", $sPwdLastChanged.LowPart)
        DllStructSetData($sTemp, "High", $sPwdLastChanged.HighPart)
        ; Have to convert to SystemTime because _Date_Time_FileTimeToStr has a bug (#1638)
        Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp))
        $aPwdInfo[10] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Convert PwdlastSet from UTC to Local Time
        $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
        $aPwdInfo[8] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Is user account password set to expire?
        If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Or $aPwdInfo[1] = 0 Then
            If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Then $iError += 2
            If $aPwdInfo[1] = 0 Then $iError += 4 ; The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire
        Else
            $aPwdInfo[11] = _DateAdd("d", $aPwdInfo[1], $aPwdInfo[10])
            $sTemp2 = _Date_Time_EncodeSystemTime(StringMid($aPwdInfo[11], 6, 2), StringMid($aPwdInfo[11], 9, 2), StringMid($aPwdInfo[11], 1, 4), StringMid($aPwdInfo[11], 12, 2), StringMid($aPwdInfo[11], 15, 2), StringMid($aPwdInfo[11], 18, 2))
            ; Convert PasswordExpires from UTC to Local Time
            $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
            $aPwdInfo[9] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        EndIf
    EndIf
    $aPwdInfo[12] = $oObject.Get("pwdProperties")
    Return SetError($iError, 0, $aPwdInfo)

EndFunc   ;==>_AD_GetPasswordInfo

 

High: -2147483648 80000000

Low : 0 00000000

Link to post
Share on other sites

So if you change line

If $oTemp.HighPart = 0x7FFFFFFF And $oTemp.LowPart = 0xFFFFFFFF Then

to

If $oTemp.HighPart = 0x80000000 And $oTemp.LowPart = 0x00000000 Then

do you get the correct result?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

So if you change line

If $oTemp.HighPart = 0x7FFFFFFF And $oTemp.LowPart = 0xFFFFFFFF Then

to

If $oTemp.HighPart = 0x80000000 And $oTemp.LowPart = 0x00000000 Then

do you get the correct result?

 

Maximum Password Age (days)|31

Minimum Password Age (days)|1

Enforce Password History (# of passwords remembered)|6

Minimum Password Length|6

Account Lockout Duration (minutes)|0

Account Lockout Threshold (invalid logon attempts)|5

Reset account lockout counter after (minutes)|3

Password last changed (YYYY/MM/DD HH:MM:SS local time)|2012/05/14 11:08:22

Password expires (YYYY/MM/DD HH:MM:SS local time)|

Password last changed (YYYY/MM/DD HH:MM:SS UTC)|2012/05/14 09:08:22

Password expires (YYYY/MM/DD HH:MM:SS UTC)|

Password properties|0

 

Edited by Tim33
Link to post
Share on other sites

Great:

So this should give you the correct result:

#include <AD.au3>
_AD_Open()
If _AD_IsObjectLockedEX("timtest") Then
    ConsoleWrite("locked. @error = " & @error & ", @extened = " & @extended & @CRLF)
Else
    ConsoleWrite("not locked. @error = " & @error & ", @extened = " & @extended & @CRLF)
    _AD_Close()
EndIf

Func _AD_IsObjectLockedEX($sObject = @UserName)
    If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0)
    Local $sProperty = "sAMAccountName"
    If StringMid($sObject, 3, 1) = "=" Then $sProperty = "distinguishedName"; FQDN provided
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $sObject & ");ADsPath;subtree"
    Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object
    Local $sLDAPEntry = $oRecordSet.fields(0).Value
    Local $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object for the object
    Local $oLockoutTime = $oObject.LockoutTime
    ; Object is not locked out
    If Not IsObj($oLockoutTime) Then Return
    ; Calculate lockout time (UTC)
    Local $sLockoutTime = _DateAdd("s", Int(__AD_LargeInt2Double($oLockoutTime.LowPart, $oLockoutTime.HighPart) / (10000000)), "1601/01/01 00:00:00")
    ; Object is not locked out
    If $sLockoutTime = "1601/01/01 00:00:00" Then Return
    ; Get password info - Account Lockout Duration
    Local $aTemp = _AD_GetPasswordInfoEX($sObject)
    ; 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 $aTemp[5] = 0 Then Return SetError(-1, 0, 1)
    ; Calculate when the lockout will be reset
    Local $sResetLockoutTime = _DateAdd("n", $aTemp[5], $sLockoutTime)
    ; Compare to current date/time (UTC)
    Local $sNow = _Date_Time_GetSystemTime()
    $sNow = _Date_Time_SystemTimeToDateTimeStr($sNow, 1)
    If $sResetLockoutTime >= $sNow Then Return SetError(_DateDiff("n", $sNow, $sResetLockoutTime), 0, 1)
    Return
EndFunc   ;==>_AD_IsObjectLockedEX

Func _AD_GetPasswordInfoEX($sObject = @UserName)
    If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 0, "")
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided
    Local $iError = 0
    Local $aPwdInfo[13] = [12]
    Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain)
    $aPwdInfo[1] = Int(__AD_Int8ToSec($oObject.Get("maxPwdAge"))) / 86400 ; Convert to Days
    $aPwdInfo[2] = __AD_Int8ToSec($oObject.Get("minPwdAge")) / 86400 ; Convert to Days
    $aPwdInfo[3] = $oObject.Get("pwdHistoryLength")
    $aPwdInfo[4] = $oObject.Get("minPwdLength")
    ; Account lockout duration: http://msdn.microsoft.com/en-us/library/ms813429.aspx
    Local $oTemp = $oObject.Get("lockoutDuration")
    If $oTemp.HighPart = 0x80000000 And $oTemp.LowPart = 0x00000000 Then
        $aPwdInfo[5] = 0 ; Account has to be unlocked manually by an admin
    Else
        $aPwdInfo[5] = __AD_Int8ToSec($oTemp) / 60 ; Convert to Minutes
    EndIf
    $aPwdInfo[6] = $oObject.Get("lockoutThreshold")
    $aPwdInfo[7] = __AD_Int8ToSec($oObject.Get("lockoutObservationWindow")) / 60 ; Convert to Minutes
    Local $oUser = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject)
    Local $sPwdLastChanged = $oUser.Get("PwdLastSet")
    Local $iUAC = $oUser.userAccountControl
    ; Has user account password been changed before?
    If $sPwdLastChanged.LowPart = 0 And $sPwdLastChanged.HighPart = 0 Then
        $iError += 3
        $aPwdInfo[8] = "1601/01/01 00:00:00"
        $aPwdInfo[10] = "1601/01/01 00:00:00"
    Else
        Local $sTemp = DllStructCreate("dword low;dword high")
        DllStructSetData($sTemp, "Low", $sPwdLastChanged.LowPart)
        DllStructSetData($sTemp, "High", $sPwdLastChanged.HighPart)
        ; Have to convert to SystemTime because _Date_Time_FileTimeToStr has a bug (#1638)
        Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp))
        $aPwdInfo[10] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Convert PwdlastSet from UTC to Local Time
        $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
        $aPwdInfo[8] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Is user account password set to expire?
        If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Or $aPwdInfo[1] = 0 Then
            If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Then $iError += 2
            If $aPwdInfo[1] = 0 Then $iError += 4 ; The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire
        Else
            $aPwdInfo[11] = _DateAdd("d", $aPwdInfo[1], $aPwdInfo[10])
            $sTemp2 = _Date_Time_EncodeSystemTime(StringMid($aPwdInfo[11], 6, 2), StringMid($aPwdInfo[11], 9, 2), StringMid($aPwdInfo[11], 1, 4), StringMid($aPwdInfo[11], 12, 2), StringMid($aPwdInfo[11], 15, 2), StringMid($aPwdInfo[11], 18, 2))
            ; Convert PasswordExpires from UTC to Local Time
            $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
            $aPwdInfo[9] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        EndIf
    EndIf
    $aPwdInfo[12] = $oObject.Get("pwdProperties")
    Return SetError($iError, 0, $aPwdInfo)
EndFunc   ;==>_AD_GetPasswordInfoEX

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

This should work as well. Could you please test both versions?

#include <AD.au3>
_AD_Open()
If _AD_IsObjectLockedEX("timtest") Then
    ConsoleWrite("locked. @error = " & @error & ", @extened = " & @extended & @CRLF)
Else
    ConsoleWrite("not locked. @error = " & @error & ", @extened = " & @extended & @CRLF)
    _AD_Close()
EndIf

Func _AD_IsObjectLockedEX($sObject = @UserName)
    If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0)
    Local $sProperty = "sAMAccountName"
    If StringMid($sObject, 3, 1) = "=" Then $sProperty = "distinguishedName"; FQDN provided
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $sObject & ");ADsPath;subtree"
    Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object
    Local $sLDAPEntry = $oRecordSet.fields(0).Value
    Local $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object for the object
    Local $oLockoutTime = $oObject.LockoutTime
    ; Object is not locked out
    If Not IsObj($oLockoutTime) Then Return
    ; Calculate lockout time (UTC)
    Local $sLockoutTime = _DateAdd("s", Int(__AD_LargeInt2Double($oLockoutTime.LowPart, $oLockoutTime.HighPart) / (10000000)), "1601/01/01 00:00:00")
    ; Object is not locked out
    If $sLockoutTime = "1601/01/01 00:00:00" Then Return
    ; Get password info - Account Lockout Duration
    Local $aTemp = _AD_GetPasswordInfoEX($sObject)
    ; 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 $aTemp[5] = 0 Then Return SetError(-1, 0, 1)
    ; Calculate when the lockout will be reset
    Local $sResetLockoutTime = _DateAdd("n", $aTemp[5], $sLockoutTime)
    ; Compare to current date/time (UTC)
    Local $sNow = _Date_Time_GetSystemTime()
    $sNow = _Date_Time_SystemTimeToDateTimeStr($sNow, 1)
    If $sResetLockoutTime >= $sNow Then Return SetError(_DateDiff("n", $sNow, $sResetLockoutTime), 0, 1)
    Return
EndFunc   ;==>_AD_IsObjectLockedEX

Func _AD_GetPasswordInfoEX($sObject = @UserName)
    If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 0, "")
    If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided
    Local $iError = 0
    Local $aPwdInfo[13] = [12]
    Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain)
    $aPwdInfo[1] = Int(__AD_Int8ToSec($oObject.Get("maxPwdAge"))) / 86400 ; Convert to Days
    $aPwdInfo[2] = __AD_Int8ToSec($oObject.Get("minPwdAge")) / 86400 ; Convert to Days
    $aPwdInfo[3] = $oObject.Get("pwdHistoryLength")
    $aPwdInfo[4] = $oObject.Get("minPwdLength")
    ; Account lockout duration: http://msdn.microsoft.com/en-us/library/ms813429.aspx
#cs
    Local $oTemp = $oObject.Get("lockoutDuration")
    If $oTemp.HighPart = 0x80000000 And $oTemp.LowPart = 0x00000000 Then
        $aPwdInfo[5] = 0 ; Account has to be unlocked manually by an admin
    Else
        $aPwdInfo[5] = __AD_Int8ToSec($oTemp) / 60 ; Convert to Minutes
    EndIf
#ce
    $aPwdInfo[5] = __AD_Int8ToSec($oObject.Get("lockoutDuration")) / 60 ; Convert to Minutes
    If $aPwdInfo[5] < 0 Or $aPwdInfo[5] > 99999 Then $aPwdInfo[5] = 0
    $aPwdInfo[6] = $oObject.Get("lockoutThreshold")
    $aPwdInfo[7] = __AD_Int8ToSec($oObject.Get("lockoutObservationWindow")) / 60 ; Convert to Minutes
    Local $oUser = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject)
    Local $sPwdLastChanged = $oUser.Get("PwdLastSet")
    Local $iUAC = $oUser.userAccountControl
    ; Has user account password been changed before?
    If $sPwdLastChanged.LowPart = 0 And $sPwdLastChanged.HighPart = 0 Then
        $iError += 3
        $aPwdInfo[8] = "1601/01/01 00:00:00"
        $aPwdInfo[10] = "1601/01/01 00:00:00"
    Else
        Local $sTemp = DllStructCreate("dword low;dword high")
        DllStructSetData($sTemp, "Low", $sPwdLastChanged.LowPart)
        DllStructSetData($sTemp, "High", $sPwdLastChanged.HighPart)
        ; Have to convert to SystemTime because _Date_Time_FileTimeToStr has a bug (#1638)
        Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp))
        $aPwdInfo[10] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Convert PwdlastSet from UTC to Local Time
        $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
        $aPwdInfo[8] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        ; Is user account password set to expire?
        If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Or $aPwdInfo[1] = 0 Then
            If BitAND($iUAC, $ADS_UF_DONT_EXPIRE_PASSWD) = $ADS_UF_DONT_EXPIRE_PASSWD Then $iError += 2
            If $aPwdInfo[1] = 0 Then $iError += 4 ; The Maximum Password Age is set to 0 in the domain. Therefore, the password does not expire
        Else
            $aPwdInfo[11] = _DateAdd("d", $aPwdInfo[1], $aPwdInfo[10])
            $sTemp2 = _Date_Time_EncodeSystemTime(StringMid($aPwdInfo[11], 6, 2), StringMid($aPwdInfo[11], 9, 2), StringMid($aPwdInfo[11], 1, 4), StringMid($aPwdInfo[11], 12, 2), StringMid($aPwdInfo[11], 15, 2), StringMid($aPwdInfo[11], 18, 2))
            ; Convert PasswordExpires from UTC to Local Time
            $sTemp2 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
            $aPwdInfo[9] = _Date_Time_SystemTimeToDateTimeStr($sTemp2, 1)
        EndIf
    EndIf
    $aPwdInfo[12] = $oObject.Get("pwdProperties")
    Return SetError($iError, 0, $aPwdInfo)
EndFunc   ;==>_AD_GetPasswordInfoEX
Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
Share on other sites

Locks great.

I think I will change the UDF to version 2. Because this is the only function I understand how it works ;)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.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 (NEW 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

 

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Kanashius
      This UDF can be used to draw at the Desktop Wallpaper (Windows 8+) with GDI+ without using files.
      The example runs with 60-120fps at my machine, so the speed is acceptable.
      When the script exits, the original wallpaper is restored.
      Have fun :).
      PS: The UDF uses the window between the background and the icons, so it could be used to add an own child window at the desktop. Just look at the begin of __Wallpaper_Startup ($hWorkerW).
       
      Example:
       
      WallpaperUDF.au3 WallpaperUDF Example.au3
    • By sandgre
      Wondering if you can help a teacher out.  For the last few years of remote, hybrid, and in-person teaching I've been using an AutoHotKey script that creates an inking toolbar to be used during a PowerPoint presentation.  (https://www.autohotkey.com/boards/viewtopic.php?t=79163) The annotation tools available through Ppt are woefully inadequate, and, on my machine at least, jump around all over the place - sometimes on the bottom, sometimes on the left, sometimes on the right.  It's a scavenger hunt every single time.  The inking tool is always available, and recent updates allowed for the addition of lots more colors, which I used for modeling phenomena with students. One tragic day I arrived to school to find that my district IT dep't took away access to AutoHotKey.  No more tool bar. 
      I've been trying to resurrect some programming skills from a past life. I'm working through various tutorials and help files, with the goal of recreating the toolbar in AutoIt.  I'm really needing some help to move things along though.  I've been going through your PowerPoint UDF and all of your functions seem to just relate to editing the slides. Can you point me in the direction of how to create a toolbar that accesses the annotation tools that are available during the slideshow itself? 
       
    • By kurtykurtyboy
      GuiFlatButton is a UDF to easily create regular buttons with different colors for background, foreground, border, hover, focus, etc..
      This started as an effort to change the background color of a button and eventually grew into a full UDF.
      If you've looked around forums for changing button background colors, you have probably noticed that each proposed workaround has its own set of issues/side-effects. The answers usually circle back to 'use ownerdrawn buttons' and 'not worth it'. Well, now it is possible for anyone to easily create ownerdrawn buttons - totally worth it!
      Some issues with other workarounds such as drawing with GDI+ or using a colored label as a 'button':
      Not 'real' buttons so you lose built-in functionality that windows gives to buttons Messy / inefficient code in the main while loop to check for mouse position Slow to respond to click, paint, etc... Having to deal with GUIRegisterMsg messages Not straight-forward to implement GuiFlatButton is not a workaround; it is a technique to respond to Windows' built-in owner-drawn button events.
      With minimal effort, we can now create true simple colored buttons.
      The idea is to create an owner-drawn button using GUICtrlCreateButton then subclass the GUI and controls to handle the button-specific events to paint it however we want.
      This UDF magically does all of this for us! No need to worry about event handling or main while loop logic.
       
      How to use
      It couldn't be any easier! Simply create a new button using the familiar syntax. This creates an ownerdrawn button with default colors.
      $mybutton1 = GuiFlatButton_Create("Button 1", 78, 20, 120, 40) If you want to change the background and text colors:
      GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) Advanced Usage
      Set background/text/border all at once
      GuiFlatButton_SetColors(-1, 0x0000FF, 0xFFFFFF, 0x9999FF) Set ALL colors for ALL button states! (normal, focus, hover, selected)
      Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetColorsEx(-1, $aColorsEx) Set default colors to apply to any future buttons
      ;set colors GuiFlatButton_SetDefaultColors(0x0000FF, 0xFFFFFF, 0x9999FF) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40) Set ALL color defaults
      ;set colors Local $aColorsEx = [0x0000FF, 0xFFFFFF, -2, 0x4444FF, 0xFFFFFF, 0xAAAAFF, 0x6666FF, 0xFFFFFF, 0xCCCCFF, 0x0000EE, 0xFFFFFF, 0x7777EE] GuiFlatButton_SetDefaultColorsEx($aColorsEx) ;create buttons $mybutton1 = GuiFlatButton_Create("Button 1", 12, 20, 120, 40) $mybutton2 = GuiFlatButton_Create("Button 2", 143, 20, 120, 40)  
      Available Functions
       
      Simple Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;GUI with one button Func Example() Local $hGUI, $mybutton1 $hGUI = GUICreate("GuiFlatButton Ex0", 275, 120) GUISetBkColor(0x333333) $idLabel = GUICtrlCreateLabel("Click the button", 10, 100, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) ;create new button then set the background and foreground colors $mybutton1 = GuiFlatButton_Create("Button 1", 78, 20, 120, 40) GuiFlatButton_SetBkColor(-1, 0x5555FF) GuiFlatButton_SetColor(-1, 0xFFFFFF) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $mybutton1 $i += 1 GUICtrlSetData($idLabel, $i) ConsoleWrite($i & @CRLF) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example
      Menu/Toolbar Example

      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include "GuiFlatButton.au3" Example() ;Example GUI with toolbar Func Example() Local $hGUI, $idLabel, $aButtons, $iTbSize $hGUI = GUICreate("GuiFlatButton Ex2", 300, 200) GUISetBkColor(0x444444) $idLabel = GUICtrlCreateLabel("Click a button", 10, 180, 150, 30) GUICtrlSetColor(-1, 0xFFFFFF) $aButtons = createToolbar() $iTbSize = UBound($aButtons) GUISetState(@SW_SHOW, $hGUI) Local $i = 0 Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aButtons[0] To $aButtons[$iTbSize - 1] ConsoleWrite("1") GUICtrlSetData($idLabel, GuiFlatButton_Read($iMsg)) EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example Func createToolbar() Local $aButtons[6] Local $bkColor = 0x777777 Local $textColor = 0xFFFFFF Local $borderColor = 0x999999 Local $aBtnClrs[12] = [0x777777, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x888888, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x999999, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT, 0x666666, 0xFFFFFF, $GUI_BKCOLOR_TRANSPARENT] For $i = 0 To UBound($aButtons) - 1 $aButtons[$i] = GuiFlatButton_Create("B" & $i, $i * 50, 0, 50, 17) GuiFlatButton_SetColorsEx($aButtons[$i], $aBtnClrs) Next Return $aButtons EndFunc ;==>createToolbar  
      Icon Example
      You can even easily add icons to your buttons -- just create a new button and send it an icon!

      #include <GDIPlus.au3> #include "GuiFlatButton.au3" Example() ;buttons with Icon images Func Example() ;get images for demonstration _GDIPlus_Startup() ;initialize GDI+ Local $hIcon = _WinAPI_ShellExtractIcon(@SystemDir & '\shell32.dll', 258, 24, 24) ;extract the 'Save' icon Local $hBitmap = _GDIPlus_BitmapCreateFromHICON($hIcon) ;Create Bitmap from Icon (for demonstration) Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) ;Create HBitmap from Bitmap _GDIPlus_BitmapDispose($hBitmap) ;dispose the bitmap _GDIPlus_Shutdown() ;done with GDI+ Local $hGUI = GUICreate("GuiFlatButton Ex5", 255, 400) GUISetBkColor(0xEEEEEE) ;set default colors of future buttons Local $aColorsEx = _ [0xE2E5E8, 0X000000, 0x888888, _ ; normal : Background, Text, Border 0xE2E5E8, 0X000000, 0x333333, _ ; focus : Background, Text, Border 0xE8E8E8, 0X000000, 0x666666, _ ; hover : Background, Text, Border 0xDDDDDD, 0X000000, 0xAAAAAA] ; selected : Background, Text, Border GuiFlatButton_SetDefaultColorsEx($aColorsEx) ;normal button with icon $label1 = GUICtrlCreateLabel( "$BS_TOOLBUTTON -->", 5, 10) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) Local $mybutton1 = GuiFlatButton_Create("Save", 130, 5, 50, 48, $BS_TOOLBUTTON) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybutton1), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top Local $mybuttonT = GuiFlatButton_Create("Top", 5, 65, 120, 55, $BS_TOP) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonT), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top-left Local $mybuttonTL = GuiFlatButton_Create("Top-Left", 5, 125, 120, 55, BITOR($BS_TOP, $BS_LEFT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonTL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align top-right Local $mybuttonTR = GuiFlatButton_Create("Top-Right", 5, 185, 120, 55, BITOR($BS_TOP, $BS_RIGHT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonTR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align left Local $mybuttonL = GuiFlatButton_Create("Left", 5, 245, 120, 55, $BS_LEFT) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom Local $mybuttonB = GuiFlatButton_Create("Bottom", 130, 65, 120, 55, $BS_BOTTOM) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonB), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom-left Local $mybuttonBL = GuiFlatButton_Create("Bottom-Left", 130, 125, 120, 55, BITOR($BS_BOTTOM, $BS_LEFT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonBL), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align bottom-right Local $mybuttonBR = GuiFlatButton_Create("Bottom-Right", 130, 185, 120, 55, BITOR($BS_BOTTOM, $BS_RIGHT)) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonBR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) ;align right Local $mybuttonR = GuiFlatButton_Create("Right", 130, 245, 120, 55, $BS_RIGHT) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonR), $BM_SETIMAGE, $IMAGE_ICON, $hIcon)) GuiFlatButton_SetState($mybuttonR, $GUI_DISABLE ) ;disabled Local $mybuttonDisable = GuiFlatButton_Create("Disabled", 130, 310, 120, 55, $BS_TOOLBUTTON) _WinAPI_DeleteObject(_SendMessage(GUICtrlGetHandle($mybuttonDisable), $BM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)) GuiFlatButton_SetState($mybuttonDisable, $GUI_DISABLE ) ;clean up! _WinAPI_DestroyIcon( $hIcon ) _WinAPI_DeleteObject( $hHBitmap ) GUISetState(@SW_SHOW, $hGUI) Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop EndSwitch Sleep(10) WEnd GUIDelete() EndFunc ;==>Example  
      I'm sure there are some use-cases I've forgotten, so feedback is welcome!
       
      Download the latest UDF and several more examples:
      Update 2022-05-25
      GuiFlatButton_20220525.zip
      Fixed issue, buttons disappear when a GUI containing a child window with WS_EX_MDICHILD extended style is moved
      Update 2022-05-24
      Fixed issue releasing subclassing when GUI is deleted but program is not closed
      Fixed occasional white background flicker
      Added function GuiFlatButton_GetPos
      Update 2021-01-02
      Fixed bug, not drawing correctly after deleting GUI with GUIDelete()
      Fixed bug, changing default colors changed all buttons, even previously created buttons
      Made some internal functions more efficient
      Update 2019-04-14
      Fixed bug, not showing pressed down state when clicking rapidly
      Added Icon/Bitmap support!
      Added function GuiFlatButton_SetPos to change the position and/or size of a button
      Update 2019-02-09
      Added 2 new functions to set the button colors globally for all future buttons.
      GuiFlatButton_SetDefaultColors 
      GuiFlatButton_SetDefaultColorsEx

      Credits to:
      Melba23 (UDF template)
      LarsJ (general subclassing code)
      4ggr35510n (TrackMouseEvent example)
      binhnx (disable dragging with $WS_EX_CONTROLPARENT)
      GUIRegisterMsg in AutoIt Help (owner-draw button example)
      funkey (_WinAPI_DrawState example)
      GuiFlatButton_20190414.zip GuiFlatButton20210102.zip
      GuiFlatButton_20220524.zip
    • By Hermes
      Hi, I am struggling in setting the value of a textarea based on the value of clipboard (that contains a long web page source codes). If I use _WD_SetElementValue, it freezes after some time, or appears to be pressing tab and goes out of focus. I can also use send keys but i need the script to run in the background.
      Here is the full script:
      #Include "Chrome.au3" #Include "wd_core.au3" #Include "wd_helper.au3" #Include "WinHttp.au3" #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> #include <Array.au3> #include <AutoItConstants.au3> #include <WinAPIFiles.au3> #include <GDIPlus.au3> #include <Excel.au3> Local $sDesiredCapabilities, $sSession SetupChrome() _WD_Startup() $sSession = _WD_CreateSession($sDesiredCapabilities) _WD_LoadWait($sSession) _WD_Navigate($sSession, "http://demo.borland.com/testsite/stadyn_largepagewithimages.html") _WD_LoadWait($sSession) Global $sSource = _WD_GetSource($sSession) Local $Paste = ClipPut($sSource) Local $sData = ClipGet() Local $aArray = 0, _ $iOffset = 1 While 1 $aArray = StringRegExp($sData, '(?s)<p>.*</p>', $STR_REGEXPARRAYMATCH, $iOffset) If @error Then ExitLoop $iOffset = @extended For $i = 0 To UBound($aArray) - 1 Local $Paste = ClipPut($aArray[$i]) Local $sRegExData = ClipGet() ;MsgBox(0, "", "$sRegExData = " & $sRegExData) Next WEnd _WD_Navigate($sSession, "https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_textarea_placeholder") _WD_WaitElement($sSession, $_WD_LOCATOR_ByCSSSelector, "iframe#iframeResult") Local $sElement1 = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "iframe#iframeResult") _WD_FrameEnter($sSession, $sElement1) _WD_WaitElement($sSession, $_WD_LOCATOR_ByXPath, "//html/body/textarea") $textarea = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//html/body/textarea") _WD_ElementAction($sSession, $textarea, 'click') ;WD SetElementValue(SsSession, Stextarea, $sRegExData) <-- I can do this but the focus goes out, or the browser freezes _WD_FrameLeave($sSession) sleep(2000) Send("^v") _WD_LoadWait($sSession) _WD_Shutdown() Func SetupChrome() _WD_Option('Driver', 'chromedriver.exe') _WD_Option('Port', 9515) _WD_Option('DriverParams', '--log-path="' & @ScriptDir & '\chrome.log"') $sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["start-maximized","disable-infobars"]}}}}' EndFunc ;==>SetupChrome Can someone help me please, or re-direct me to the right path? TIA!
    • By Hermes
      Hi, I am trying to select elements in print page (dialog window) for a specific web page. But when trying to do so, it looks like it does not allow me to do it.
      So far, this is what I have:
      _WD_WaitElement($sSession, $_WD_LOCATOR_ByCSSSelector, "body") Local $mainpagebody = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "body") _WD_HighlightElement($sSession, $mainpagebody, 2) _WD_WaitElement($sSession, $_WD_LOCATOR_ByCSSSelector, "img.print-button") Local $printbutton = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "img.print-button") _WD_ElementAction($sSession, $printbutton, 'click') _WD_LoadWait($sSession) Sleep(3000) _WD_WaitElement($sSession, $_WD_LOCATOR_ByCSSSelector, "body") Local $printpagebody = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "body") _WD_HighlightElement($sSession, $printpagebody, 2) The script above highlights the main web page "body" element, then clicks a tag to print a specific part of the page, then it will open a print page window where i am trying to highlight the body of that print page - but it looks like it is dropping from the session because it opens up another chrome page chrome://print.
       
      Below is the output log:
      __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"body"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}} _WD_WaitElement ==> Success __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"body"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}} __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/execute/sync; $sData={"script":"arguments[0].style='background: #FFFF66; border-radius: 5px; padding-left: 3px;'; return true;", "args":[{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}]} __WD_Post: StatusCode=200; ResponseText={"value":true}... _WD_ExecuteScript: {"value":true}... __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"img.print-link"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"eb9e4673-4dec-4d4c-be6a-b7967743394b"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"eb9e4673-4dec-4d4c-be6a-b7967743394b"}} _WD_WaitElement ==> Success __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"img.print-link"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"eb9e4673-4dec-4d4c-be6a-b7967743394b"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"eb9e4673-4dec-4d4c-be6a-b7967743394b"}} __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element/eb9e4673-4dec-4d4c-be6a-b7967743394b/click; $sData={"id":"eb9e4673-4dec-4d4c-be6a-b7967743394b"} __WD_Post: StatusCode=200; ResponseText={"value":null}... _WD_ElementAction: {"value":null}... __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/execute/sync; $sData={"script":"arguments[0].style='background: #FFFF66; border-radius: 5px; padding-left: 3px;'; return true;", "args":[{"element-6066-11e4-a52e-4f735466cecf":"eb9e4673-4dec-4d4c-be6a-b7967743394b"}]} __WD_Post: StatusCode=200; ResponseText={"value":true}... _WD_ExecuteScript: {"value":true}... __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/execute/sync; $sData={"script":"return document.readyState", "args":[]} __WD_Post: StatusCode=500; ResponseText={"value":{"error":"script timeout","message":"script timeout\n (Session info: chrome=92.0.4515.107)... __WD_Post ==> Webdriver Exception: {"value":{"error":"script timeout","message":"script timeout\n (Session info: chrome=92.0.4515.107)","stacktrace":"Backtrace:\n\tOrdinal0 [0x00C63733+2504499]\n\tOrdinal0 [0x00BFC401+2081793]\n\tOrdinal0 [0x00B024F0+1058032]\n\tOrdinal0 [0x00B55685+1398405]\n\tOrdinal0 [0x00B45E83+1334915]\n\tOrdinal0 [0x00B54CDB+1395931]\n\tOrdinal0 [0x00B45D4B+1334603]\n\tOrdinal0 [0x00B222B4+1188532]\n\tOrdinal0 [0x00B23149+1192265]\n\tGetHandleVerifier [0x00DDFB8C+1512252]\n\tGetHandleVerifier [0x00E8B0DF+2214031]\n\tGetHandleVerifier [0x00CE4BC3+484211]\n\tGetHandleVerifier [0x00CE3E69+480793]\n\tOrdinal0 [0x00C0218D+2105741]\n\tOrdinal0 [0x00C066E8+2123496]\n\tOrdinal0 [0x00C06827+2123815]\n\tOrdinal0 [0x00C0FB73+2161523]\n\tBaseThreadInitThunk [0x75EB62C4+36]\n\tRtlSubscribeWnfStateChangeNotification [0x77C11B69+1081]\n\tRtlSubscribeWnfStateChangeNotification [0x77C11B34+1028]\n"}} _WD_ExecuteScript: {"value":{"error":"script timeout","message":"script timeout\n (Session info: chrome=92.0.4515.107)... _WD_ExecuteScript ==> Webdriver Exception: HTTP status = 500 _WD_LoadWait ==> Webdriver Exception __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"body"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}} _WD_WaitElement ==> Success __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/element; $sData={"using":"css selector","value":"body"} __WD_Post: StatusCode=200; ResponseText={"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}}... _WD_FindElement: {"value":{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}} __WD_Post: URL=HTTP://127.0.0.1:9515/session/cd08704233a965ccbaf9292e8692c3e4/execute/sync; $sData={"script":"arguments[0].style='background: #FFFF66; border-radius: 5px; padding-left: 3px;'; return true;", "args":[{"element-6066-11e4-a52e-4f735466cecf":"91a394f0-004c-480d-aedf-52e2b30233c6"}]} __WD_Post: StatusCode=200; ResponseText={"value":true}... _WD_ExecuteScript: {"value":true}...  
      Is it even possible to select elements in print page?

×
×
  • Create New...