2014-01-03 - Version 1.4.0.0

GENERAL
=======
* Enhanced documentation
* Internal variables and parameter names have been renamed to adhere more to the standards

FIXED BUGS
==========
* If run with AutoIt < 3.3.9.2 and the script defines a COM error handler before _AD_Open is called then _AD_Open will fail with @error = 3.
  Thanks to user bartekd for pointing me to this error
* _AD_RecursiveGetMemberOf now escapes special characters in the members FQDN before the next recursion
  Thanks to lewisg for pointing me to this error
* If you try to delete an object with characters that need to be escaped in the CN then function _AD_DeleteObject will crash.
  Thanks to user bartekd for pointing me to this error
* AutoIt 3.3.10.0 and later no longer supports function _ArrayCreate. Has been removed.
* Missing $__WINAPICONSTANT_FORMAT_MESSAGE_FROM_SYSTEM constant was added

CHANGED FUNCTIONS
=================
* _AD_ErrorNotify. New option added. 4 = Enable Debugging. The COM errors will be handled (the script no longer crashes) without any output. Only needed when run with  AutoIt < 3.3.10.0
* _AD_IsMemberOf: Now allows to recursivly search contained groups too
* Functions _AD_HasFullRights, _AD_HasUnlockResetRights, _AD_HasGroupUpdateRights now call function _AD_HasRequiredRights and no longer calculate the result in the function
* _AD_FixSpecialChars: Now escapes special characters for LDAP filters too (new option 3), not just for Distinguished Names

NEW FUNCTIONS
=============
* _AD_RecursiveGetGroupMembers: Takes a group and recursively returns a list of groups and members of the group
* _AD_ChangePassword: Changes the password for the currently logged on user

-------------------------------------------------------------------------------------------------------------------------------
2012-10-12 - Version 1.3.0.0 - Downloads: 6979

GENERAL
=======
* This version should (again) run with all production and beta versions of AutoIt. It combines 1.2.0 and 1.2.2.0
  The COM error handler is activated automatically when the AutoIt version is < 3.3.9.2

-------------------------------------------------------------------------------------------------------------------------------
2012-07-28 - Version 1.2.2.0 - Downloads: 3417

GENERAL
=======
* Error checking in some functions has been extended so you get an error when permissions to access a property are missing.
  Thanks to syed23 for showing this bug. 
* Documentation enhanced

FIXED BUGS
==========
* _AD_GetObjectsInOU: If $bAD_Count = True you get 0 and @error = 3 now when no records found. Was "" and @error = 3 before
* _AD_MoveObject: Escapes special characters of CN. 
  Thanks to user paullauze for reporting this bug!
* _AD_DeleteObject: Correctly deletes OUs now
  Thanks to user geriksen73 for pointing me to this bug!

CHANGED FUNCTIONS
=================
* _AD_ErrorNotify: Added @error = 3
* _AD_GetAllOUs: Parameter $iAD_Select added. Lets you specify which objects to return: OUs, CNs or both. Default is OU.

-------------------------------------------------------------------------------------------------------------------------------
2012-03-18 - Version 1.2.1.0 - Downloads: 1416

GENERAL
=======
* Needs AutoIt beta version 3.3.9.2 or later because of the new COM error handling
* Enhanced error checking in multiple functions
* Internal variables, parameter names and functions have been renamed to adhere more to the standards

SCRIPT BREAKING CHANGES
=======================
* _AD_ListDomainControllers: New parameter $bAD_ListGC. If set to True queries the DC for a Global Catalog. 
  Now disabled for performance reasons (Default is now False, was True before)

FIXED BUGS
==========
* Fixed some documentation bugs
* _AD_GetPasswordInfo: Doesn't return property "password last set" if the users UAC is set to "password never expires". Thanks for reporting to user Turkey77

NEW FUNCTIONS
=============
* _AD_ErrorNotify: Sets or queries the debugging level and the output file. Replaces setting the global variables $iAD_Debug and $sAD_DebugFile by the user

CHANGED FUNCTIONS
=================
* _AD_CreateUser: Escapes special characters in parameter $sAD_CN now. Enhanced error checking
* _AD_ErrorHandler: Now returns @AutoItVersion, @AutoItX64, @Compiled, @OSArch and @OSVersion for easier debugging
  Stripped down to only collect error data and write to the Console, a Msgbox or a file
* _AD_GetLastLoginDate: Parameter $aAD_DCList added. Allows to pass the list of DCs as returned by function _AD_ListDomainControllers.
  Enhances performance if the function is called many times
* _AD_GetObjectClass: Changed default for parameter $bAD_All from 0 to False (shouldn't make any difference for the user)
* _AD_GetUserGroups: Changed default for parameter $bAD_IncludePrimaryGroup from 0 to False (shouldn't make any difference for the user)
* _AD_GroupRemoveManager: Changed default for parameter $fAD_Flag from 0 to False (shouldn't make any difference for the user)
* _AD_ListDomainControllers: New parameter $bAD_ListGC. If set to True queries the DC for a Global Catalog. Disabled for performance reasons (default = False)
* _AD_Open: No longer sets @extended to 1 if a COM error handler could be established. A COM error handler is set up by _AD_ErrorNotify now
* _AD_SetGroupManagerCanModify: Set options to only update the DACL to solve this problem: http://support.microsoft.com/default.aspx?scid=kb;en-us;323749

-------------------------------------------------------------------------------------------------------------------------------
2011-12-19 - Version 1.2.0

FIXED BUGS
==========
* _AD_ErrorHandler (Internal function): A MsgBox could popup and stop a script running as a service. Was removed
* _AD_GetObjectAttribute: If a previously called function doesn't find an object (e.g. _AD_GetUserGroups returns no groups) then 
  _AD_GetObjectAttribute will not return the required attribute but set @error = 2. _AD_GetObjectAttribute might be called implicitely by another 
  function (e.g. _AD_DeleteObject to delete a user).
  Thanks to user FernandG for reporting this bug!
* _AD_FQDNToDisplayname: Strips off the first 3 characters of the displayname.
  Thanks to user thomy62 from the german forum for reporting this bug!

GENERAL
=======
* Setting the global variable $iAD_Debug writes debugging information to the console ($iAD_Debug=1), a MsgBox (=2) or a file (=3).
  When set to 3 you now can set variable $sAD_DebugFile to specify the location and name of the debug file. 
  Default: $sAD_DebugFile = @ScriptDir & "\AD_Debug.txt"

CHANGED FUNCTIONS
=================
* _AD_FQDNToDisplayname: Code rewritten. Now returns the error codes as set by function _AD_GetObjectAttribute
* _AD_GetPasswordExpired: Two new parameters have been added.
  $iAD_PasswordAge: All Users/computers with passwords older $iAD_PasswordAge days will be reported. 
    If not specified the maximum password age as returned by function _AD_GetPasswordInfo is used (default)
  $bAD_Computer: If set to True queries computer accounts, if False queries user accounts (default = False)  

MISCELLANEOUS
=============
* Some minor code changes
* Some minor documentation changes

-------------------------------------------------------------------------------------------------------------------------------
2011-09-17 - Version 1.1.0 - Downloads: 1404

FIXED BUGS
==========
* _AD_FQDNToDisplayname: Returned property "name" in previous versions. Now returns property "displayname" to match the function name
* _AD_FQDNToSamAccountName: Returned the "name" property. Was changed to return the "DisplayName" property
* _AD_GetLastADSIError: Didn't properly return the Win32 error code extracted from element[2]
* _AD_GetUserGroups: _AD_GetUserGroups(@UserName, 1) didn't return an array if the user is only a member of the primary group
  (e.g. 'Domain Users')
* _AD_RecursiveGetMemberOf: Didn't honor the $iAD_Depth parameter and therefore crashed when there was a loop in groups
* #include <Constants.au3> was not needed and removed
 
REMOVED FUNCTIONS
=================
* _AD_GetLastLDAPError: Never worked anyway
* _AD_GetGCAttributes: Replaced with _AD_GetSchemaAttributes

NEW FUNCTIONS
=============
* _AD_GetSchemaAttributes: Enumerates attributes of the AD Schema (those replicated to the Global Catalog, indexed attributes or all)
* _AD_VersionInfo: Displays an array of information about the UDF. Based on _IE_VersionInfo()

CHANGED FUNCTIONS
=================
* _AD_Open: On success @extended is set to 0 or 1 to denote if a COM error handler was initialized
* _AD_GetPasswordExpired: New parameter $bAD_NeverLoggedOn added to return user who never changed their password
* _AD_GetSchemaAttributes: Now enumerates more attributes from the AD Schema (replicated to the Global Catalog, indexed attributes or all)

SCRIPT BREAKING CHANGES
=======================
* _AD_FQDNToDisplayname: Returned property "name" in previous versions. Now returns property "displayname" to match the function name
* _AD_FQDNToSamAccountName: Returned the "name" property. Was changed to return the "DisplayName" property
* _AD_GetGCAttributes has been replaced with _AD_GetSchemaAttributes
* _AD_GetSchemaAttributes: Now a two dimensional array is returned

MISCELLANEOUS
=============
* ADS_GROUP_TYPE_ENUM Enumeration extended. $ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP and $ADS_GROUP_TYPE_LOCAL_SECURITY added
* The COM error handler now returns the UDF version information

-------------------------------------------------------------------------------------------------------------------------------
2011-06-07 - Version 1.0.0 - Downloads: 1395

GENERAL
=======
* Version number changed from 0.43 to 1.0.0. As the UDF has matured over time the first production version can be released
* The previous versions only allowed to query for objects in the domain you connect to using _AD_Open.
  When you connect to a domain controller which is a global catalog as well and you specify port 3268 then you are connected to the 
  Global Catalog and can query the whole forest
* Reworked the list of contributors. If I missed anyone please drop me a note
* I'm about to create some articles with extended information in the Wiki (still work in progress)

KNOWN BUGS: (last updated: 2011-08-14)
======================================
* _AD_RecursiveGetMemberOf: Doesn't honor the $iAD_Depth parameter. If you have a loop in your groups 
  (group A is member of group B is a member of group A) you will get error "Recursion level has been exceeded - 
  AutoIt will quit to prevent stack overflow.". A workaround is available. The bug will be fixed in the next version.
  Thanks to gcue for pointing me to this bug.
* _AD_GetUserGroups(@UserName, 1) returns no array if the user is only a member of the primary group (e.g. 'Domain Users'). 
  A workaround is available. The bug will be fixed in the next version.
  Thanks to supersonic for reporting the bug.
    
FIXED BUGS
==========
* _AD_EnablePasswordChange and _AD_DisablePasswordChange: User Suba noticed: The well known accounts SELF and EVERYONE are language dependant 
  and only worked on english systems. He provided the code to solve this problem - thanks!
* _AD_ListDomainControllers: Didn't connect to $sAD_HostServer to query the Configuration
* _AD_ListExchangeMailboxStores: Didn't connect to $sAD_HostServer to query the Configuration
* _AD_ListExchangeServers: Didn't connect to $sAD_HostServer to query the Configuration
* _AD_GetObjectProperties: Didn't set the # of columns in the returned array ($aAD_ObjectProperties[0][1] was empty)
* _AD_GetPasswordInfo: User Suba noticed: $sAD_HostServer was missing in the LDAP query
  
DOCUMENTATION CHANGES
=====================
* Some functions (_AD_GetAllOUs, _AD_ListDomainControllers, _AD_GetObjectsLocked, _AD_GetPasswordExpired, _AD_ListExchangeMailboxStores,
  _AD_GetManagedBy, _AD_GetManager, _AD_ListPrintQueues, _AD_GetAccountsExpired) returning a one-based two dimensional array had a wrong index 
  for the first element of each row. They started with 1 where 0 is correct
* Minor changes in multiple functions

NEW FUNCTIONS
=============
* _AD_GetGCAttributes: Enumerates all attributes that are replicated to the Global Catalog
  
CHANGED FUNCTIONS
=================
* _AD_DisablePasswordChange, _AD_EnablePasswordChange: The well known accounts SELF and EVERYONE now work for all languages
* _AD_FQDNToSamAccountName: If the parameter is already a SamAccountName then the function returns the parameter unchanged and without raising an error
* _AD_GetLastLoginDate: Now allows to specify a list of sites (separated by commas) to check the DCs
* _AD_GetObjectsDisabled, _AD_GetObjectsLocked, _AD_GetPasswordExpired, _AD_GetPasswordDontExpire, _AD_GetAccountsExpired:
  This functions now allow to specify a starting OU. So the functions won't search the whole domain
* _AD_GetPasswordInfo: Added password properties like DOMAIN_PASSWORD_COMPLEX etc.
* _AD_ListDomainControllers: The returned array now has a 6th element which is set to True when the Domain Controller is a Global Catalog as well.
  Connect to $sAD_HostServer to query the Configuration
* _AD_ListExchangeMailboxStores: Connect to $sAD_HostServer to query the Configuration
* _AD_ListExchangeServers: Connect to $sAD_HostServer to query the Configuration
* _AD_Open: You can connect to a specific DC in the current domain by just providing $sAD_HostServerParam (all other parameters remain blank)
* _AD_SamAccountNameToFQDN: If the parameter is already a FQDN then the function returns the parameter unchanged and without raising an error

-------------------------------------------------------------------------------------------------------------------------------
2011-03-01 - Version 0.43 - Downloads: 1214

GENERAL
=======
The $AD_Command object to execute LDAP queries has become a global variable. The default properties apply except for "Page Size" which is set to 1000
to allow an unlimited number of items to be returned by an LDAP query.
You now can set properties of this object using function _AD_SetADOProperties.
You can query properties of both the ADO command and the ADO connection object using function _AD_GetADOProperties.

KNOWN BUGS: (Last changed: 2011-03-30)
======================================
* User Suba noticed: The well known accounts SELF and EVERYONE used in functions _AD_EnablePasswordChange and _AD_DisablePasswordChange 
  only work on english systems. They are named different in other languages. A workaround is available if needed, otherwise this bug will be 
  solved in the next version.
* User Suba noticed: Under rare conditions function _AD_GetPasswordInfo can crash with "0x8007202B - A referral was returned from the server". 
  A workaround is available if needed, otherwise this will be solved in the next version.
  Update: Actually it's not a bug, it's a feature. But not handled very well by the UDF
    
FIXED BUGS
==========
* _AD_DeleteObject: Didn't work when the FQDN of the object didn't contain the string "OU="
* _AD_GetPasswordInfo: The Account Lockout Duration is correctly returned as 0. Was 15372286728.0913 because it was interpreted as a time value
* _AD_ListRootDSEAttributes (Example Script): Didn't work after changes made to the function in version 0.42
* _AD_RenameObject: Didn't work when the FQDN of the object didn't contain the string "OU="

CHANGED FUNCTIONS
=================
* _AD_FixSpecialChars: List of characters to escape/unescape extended. Is no longer an internal function and can be used by users
* _AD_IsObjectLocked: If the lockout duration is set to 0 (= the user has to be unlocked manually by an admin) then @error is set to -1
  (else it contains the number of minutes till the account gets unlocked)
* _AD_GetObjectsInOU: If parameter $fAD_Count=True then just the number of records returned by the query is returned (to improve performance)
* _AD_Open: A new flag can be passed as parameter so the function uses password encryption and/or a secure connection (SSL)

NEW FUNCTIONS
=============
* _AD_GetADOProperties: Retrieves all properties of an ADO object (Connection, Command)
* _AD_SetADOProperties: Sets properties of an ADO command object

-------------------------------------------------------------------------------------------------------------------------------
2010-12-19 - Version 0.42 - Downloads: 812

KNOWN BUGS: (Last changed: 2011-02-22)
======================================
* _AD_ListRootDSEAttributes (Example Script): Forgot to incorporate the script breaking change. Will be changed in the next version
* _AD_Open: If you specify a userid/password and get COM error "0x80020009 - The server is not operational" then please change line 159 to
    Global Const $ADS_USE_ENCRYPTION = 0x0
  _AD_Open uses ADSI flag ADS_USE_ENCRYPTION. ADS_USE_ENCRYPTION is the same as ADS_USE_SSL. They both have the value 2. 
  AD requires that the Certificate Server be installed to support SSL.
  I will have to decide if this security feature will be supported or removed from the next version
* _AD_DeleteObject and _AD_RenameObject: Don't work when the FQDN of the object doesn't contain an OU. Fixed versions can be found here
    
SCRIPT BREAKING CHANGES
=======================
* _AD_ListRootDSEAttributes: Multi valued attributes are no longer returned in a single string separated by "|" but as multiple lines in the array 

DOCUMENTATION CHANGES
=====================
* _AD_GetGroupMembers: Added remarks
* _AD_GetObjectsInOU: Documented how to use the escaping mechanism in the LDAP filter
* _AD_GetLastADSIError: Added remarks

CHANGED FUNCTIONS
=================
* _AD_GetObjectProperties: 1st parameter can now be an object so you can get the properties for a schema or configuration object as well
* _AD_ListDomainControllers: The function only lists writeable DCs (default). To query for RODC (read only DCs) you have to set flag $fAD_ListRO = TRUE.
  Now sets @error=1 if no domain controller is found
* _AD_ListRootDSEAttributes: Multi valued attributes are no longer returned in a single string separated by "|" but as multiple lines in the array
* _AD_Open: If you specify a userid/password the ADO property "Encrypt Password" ist set to true before sending the credentials

FIXED BUGS
==========
* Some functions only returned up to 1000 items due to using a M$ limit.
  Affected functions: _AD_GetAccountsExpired, _AD_GetManagedBy, _AD_GetManager, _AD_GetObjectsDisabled, _AD_GetObjectsLocked, _AD_GetPasswordDontExpire,
  _AD_GetPasswordExpired, _AD_GetUserPrimaryGroup. This functions have been be changed!
  Unlikely to be affected: _AD_ListExchangeMailboxStores and _AD_ListExchangeServers. This functions have not been changed.
* _AD_Open: Due to some bugs the bind cache wasn't used and a lot of unnecessary binds were created. This has put heavy load on the DC and sometimes
  lead to a COM error when all connections on the DC were exhausted

-------------------------------------------------------------------------------------------------------------------------------
2010-09-13 - Version 0.41 - Downloads: 1281

KNOWN BUGS: (last changed: 2010-12-18)
======================================
* The UDF doesn't use the bind cache at the moment. So a lot of unnecessary binds are done which puts heavy load on the domain controller. 
  In some cases the max. number of TCP connections is reached and the DC returns a COM error and rejects further connections until some of the 
  older connections have timed out. This bug has been solved as long as you don't provide userid/password when calling _AD_Open.
  Wait for version 0.42 (to be released in a few days) or insert after line 371:
    $oAD_RootDSE = ObjGet("LDAP://" & $sAD_HostServer & "/RootDSE") ; To guarantee a persistant binding
  The remaining bug when using credentials is under investigation!
* Some functions only return up to 1000 items due to using a M$ limit.
  Affected functions: _AD_GetAccountsExpired, _AD_GetManagedBy, _AD_GetManager, _AD_GetObjectsDisabled, _AD_GetObjectsLocked, 
  _AD_GetPasswordDontExpire, _AD_GetPasswordExpired, _AD_GetUserPrimaryGroup. This functions will be changed!
  Unlikely to be affected: _AD_ListExchangeMailboxStores and _AD_ListExchangeServers. This functions might be changed.

CHANGED FUNCTIONS
=================
* _AD_Open: No longer returns an array on error for Windows 7 and later.
  Return value is either 0 or 1
  @error is 1 to 8 (@extended set to error code received by the COM error handler (decimal))
  or the Win32 error code for Windows Vista and later (userid specified as Windows Login Name or User Principal Name).
  For the extended error information if @error > 8 you have to call function _AD_GetLastADSIError (please see _AD_Open example script)

FIXED BUGS
==========
* _AD_Open: If you used the Windows login name you got @error = 1317. Secure authentification flag was missing

NEW FUNCTIONS
=============
* _AD_GetLastADSIError: Uses the ADsGetLastError function to retrieve the calling thread's last-error code value. Is no longer an internal function

OTHER CHANGES
=============
* _AD_Open (Example Script): Enhanced for extended error information retrieval.

-------------------------------------------------------------------------------------------------------------------------------
2010-09-07 - Version 0.40 - Downloads: 106

GENERAL
=======
* A big "THANK YOU" to feeks who spent a lot of time testing and proof reading the UDF!
* Biggest change in the UDF is the error checking done in _AD_Open. Be aware that on Windows 7 an array is returned in case of an error!
* Required version of AutoIt has been set to 3.6.6.0 as the newest version of date.au3 is required. But this UDF still has a bug (#1638)
  that has to be worked around

KNOWN BUGS: (last updated: 2010-09-10)
======================================
* I have a running discussion with supersonic (see the last post of this thread) about the return values of _AD_Open. 
  Maybe the way the additional error information on Windows 7 (as an array) is returned will change in a few days with a new version of the UDF.
* _AD_Open: If you use the Windows login name you get @error = 1317. As a workaround either use the NetBIOS Login Name (DOMAIN\user) or the 
  User Principal Name (user@domain.com) or change line 381 from
    Local $oAD_Temp = $oAD_OpenDS.OpenDSObject("LDAP://" & $sAD_HostServer, $sAD_UserId, $sAD_Password, $ADS_SERVER_BIND)
  to
    Local $oAD_Temp = $oAD_OpenDS.OpenDSObject("LDAP://" & $sAD_HostServer, $sAD_UserId, $sAD_Password, BitOR($ADS_SECURE_AUTH, $ADS_SERVER_BIND))  
  
CHANGED FUNCTIONS
=================
* _AD_GetObjectClass: With an additional parameter the function now returns all classes (main plus superior classes from which the main
  class is deduced hierarchically) in an array
* _AD_MoveObject: The third parameter (Common Name = CN) was calculated by searching for "OU=" in $sAD_Object. This didn't always work.
  Now the CN is retrieved using _AD_GetObjectAttribute.
* _AD_Open: Does extended authentication checking if you provide userid/password. On Windows XP or lower you get @error=8 if the userid or
  password is invalid. On Windows 7 or later _AD_Open returns an array with additional information. This and more errors will be handled:
	525 - user not found
	52e - invalid credentials
	530 - not permitted to logon at this time
	532 - password expired
	533 - account disabled
	701 - account expired
	773 - user must reset password
  The extended error checking of previous versions with ldapsearch has beend removed.
* _AD_UnlockObject: Unlocking an object using the UAC didn't work in all cases. Now uses property "IsAccountLocked"

FIXED BUGS
==========
* _AD_CreateMailbox: The check for @error=1 was missing
* _AD_GetGroupAdmins (Example Script): Only returned the admin for the first group
* _AD_HasFullRights, _AD_HasGroupUpdateRights, _AD_HasRequiredRights, _AD_HasUnlockResetRights now process a SamAccountName as parameter
  correctly as described in the docu
* _AD_MoveObject: If the second parameter $sAD_Object didn't contain the text "OU=" then the Common Name (CN) for the moved object wasn't 
  calculated correctly and the function returned a COM error. Now the CN is retrieved using _AD_GetObjectAttribute.

NEW FUNCTIONS
=============
* _AD_EnablePasswordExpire: Sets users password to expire
* _AD_IsAccountExpired: Returns 1 if the account (user, computer) has expired
* _AD_GetAccountsExpired: Returns an array with FQDNs of expired accounts (user, computer)
* _AD_ListSchemaVersions: Returns information about the AD Schema versions
* _AD_ObjectExistsInSchema: Returns 1 if exactly one object exists for the given property in the Active Directory Schema

NEW INTERNAL FUNCTIONS
======================
* _AD_GetLastADSIError: Uses the ADsGetLastError function to retrieve the calling thread's last-error code value

REMOVED FUNCTIONS
=================
* _AD_LockObject: Does not make sense. Never worked anyway

OTHER CHANGES
=============
* _AD_CreateComputer: Extended Remarks
* _AD_CreateMailbox: Extended description
* _AD_GetObjectsInOU (Example Script): Added examples to list accounts that do expire and accounts that already have expired
* _AD_SetAccountExpire: Extended description. This function always accepted date AND time
* A lot of text changes in the functions header (thanks to feeks for proof reading!)

-------------------------------------------------------------------------------------------------------------------------------
2010-05-15 - Version 0.39 - Downloads: 1119

GENERAL
=======
* ReadMe.txt has been expanded and now contains a chapter about "How to use the Active Directory UDF"
* The example scripts have been changed so "#AutoIt3Wrapper_AU3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6" does not return any errors 
* Most changes have been done with the handling of special characters and date processing (UTC vs. local time). Please test before using!

KNOWN BUGS: (last updated: 2010-08-24)
======================================
* _AD_MoveObject: If the second parameter $sAD_Object doesn't contain the text "OU=" then the Common Name (CN) for the moved object isn't 
  calculated correctly and the function returns a COM error. As workaround please provide the Common Name as parameter three.
* I noted some problems with "old" versions of the Date UDF (function _Date_Time_SystemTimeToDateTimeStr), so please use the most current 
  version of AutoIt. I'm testing with 3.3.6.0 at the moment
* The UDF does not support the "granular password policy" feature implemented with Windows Server 2008. 
  Invalid results for all password related functions might be returned. The subject is under investigation
* Keyword "Default": You can't use the keyword "Default" to omit parameters in a function call as the UDF does not support this keyword.

CHANGED FUNCTIONS
=================
* Handling of special characters (/, # and comma) has been improved in the following functions:
  _AD_DeleteObject, _AD_FQDNToDisplayname, _AD_FQDNToSamAccountName, _AD_MoveObject, _AD_RenameObject, _AD_SamAccountNameToFQDN
* _AD_FixSpecialChars (internal function): You can now specify which characters to escape/unescape
* _AD_GetObjectsLocked: Now returns a two-dimensional array. The lockout time and minutes until the object will be unlocked are returned as well
* _AD_GetPasswordExpired: Returns a two-dimensional array. The FQDN and the expiration time in UTC and local time are returned
* _AD_GetPasswordInfo: Returns password last changes and password expires now in UTC and local time
  Sets @error=4 when the maximum password age in the domain is set to 0 (= no password expires)
* _AD_Open: Sets @error=7 which means: Parameter $sAD_PasswordParam has to be specified when $sAD_UserIdParam is specified

FIXED BUGS
==========
* _AD_DisableObject: No longer toggles the flag, sets it now
* _AD_EnableObject: No longer toggles the flag, sets it now
* _AD_FQDNToDisplayName: All commas in the FQDN were escaped - which is wrong
* _AD_FQDNToSamAccountName: All commas in the FQDN were escaped - which is wrong
* _AD_GetPasswordExpired: Now works
* _AD_IsObjectLocked: Now honors the DST - because it doesn't use it anymore. All calculations are done with UTC
* _AD_IsPasswordExpired: Now works
* _AD_ModifyAttribute: Had wrong default value for $iAD_Option in syntax description (documentation bug)
* _AD_MoveObject: Had wrong parameter name in syntax description (documentation bug)

REMOVED FUNCTIONS
=================
* _AD_CopyObject: Is not available with the LDAP and WINNT provider. Never worked anyway

-------------------------------------------------------------------------------------------------------------------------------
2010-04-05 - Version 0.38.1 - Downloads: 515

GENERAL
=======
If you call a function with a Fully Qualified Domain Name (FQDN) as parameter you as a user have to make sure that all special
characters (#, / and comma) are escaped with a preceding backslash. You can call the internal function _AD_FixSpecialChars(String,1) to escape
or _AD_FixSpecialChars(string, 0) to unescape the special characters.

KNOWN BUGS: (last updated: 2010-04-12)
======================================
* _AD_GetObjectsLocked(): Doesn't return a correct value when the lockouttime hasn't expired. The function has to be rewritten
* _AD_FQDNToSamAccountName and _AD_FQDNToDisplayName: Please remove the line
  $sAD_FQDN = _AD_FixSpecialChars($sAD_FQDN)
  from both functions. All commas in the FQDN are escaped which is wrong. Has been fixed in version 0.38.1
* _AD_IsObjectLocked: The function does not honor the DST and therefore might return a wrong result. Please insert after lines
    ; Get current bias for date calculation (including bias for DST)
    Local $aAD_Temp = _Date_Time_GetTimeZoneInformation()
    Local $iAD_CurrentBias = $aAD_Temp[1]
  this line
    If $aAD_Temp[0] = 2 Then $iAD_CurrentBias += $aAD_Temp[7]
  This should solve the problem. Will be fixed in version 0.39.

CHANGED FUNCTIONS
=================
* _AD_Close: Now sets a return code on success/error as all other functions already do
* _AD_FQDNToDisplayname: Special characters in the FQDN parameter are escaped
* _AD_FQDNToSamAccountName: Special characters in parameter $sAD_FQDN are escaped
* _AD_JoinDomain: If no credentials are passed then the credentials of _AD_Open are used if provided
* _AD_Open: Returns @error = 6 when $sAD_DNSDomainParam is specified but $sAD_HostServerParam and/or $sAD_ConfigurationParam is missing
  If you set the global variable $iAD_Debug > 0 then in case of error additional information will be displayed using ldapsearch. 
  Example:
  _AD_Open: Invalid ID-Data, Additional Information: 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece
  This tools has to be provided by you
* _AD_SetPassword: Flag $iAD_Expired has been added. If set to 1 the user has to change the password at next logon
* _AD_UnjoinDomain: If no credentials are passed then the credentials of _AD_Open are used if provided

FIXED BUGS
==========
* _AD_GetObjectsInOU: Doesn't return a result when the parameter $sAD_DataToRetrieve consists of a single value.
  $iAD_SearchScope now works for all values

NEW FUNCTIONS
=============
* _AD_UnjoinDomain. . . . . . . . Unjoins the computer from Active Directory and joins it into a local workgroup
* _AD_SetPasswordExpire . . . . . Sets user's password as expired or as not expired
* _AD_CreateMailbox . . . . . . . Creates the mailbox for a user
* _AD_DeleteMailbox . . . . . . . Deletes the mailbox from a user
* _AD_MailEnableGroup . . . . . . Enables mail for a group

-------------------------------------------------------------------------------------------------------------------------------
2010-03-04 - Version 0.37 - Downloads: 391

KNOWN BUGS: (last updated: 2010-03-28)
======================================
* _AD_GetObjectsInOU: Returns an empty array when the parameter $sAD_DataToRetrieve consists of a single value.
  As a workaround please replace $aAD_DataToRetrieve with $sAD_DataToRetrieve in line 1129, 1130 and 1133
* _AD_GetObjectsLocked(): Doesn't return a correct value when the lockouttime hasn't expired. The function has to be rewritten

CHANGED FUNCTIONS
=================
* All functions:
  If they return a string or array on success, they will return an empty string on error. Till now they returned "0":
  _AD_FQDNToDisplayname, _AD_FQDNToSamAccountName, _AD_GetAllOUs, _AD_GetGroupAdmins, _AD_GetGroupMemberOf, _AD_GetGroupMembers, 
  _AD_GetManagedBy, AD_GetManager, _AD_GetObjectAttribute, _AD_GetObjectClass, _AD_GetObjectProperties, _AD_GetObjectsDisabled,
  _AD_GetObjectsInOU, _AD_GetObjectsLocked, _AD_GetPasswordDontExpire, _AD_GetPasswordExpired, _AD_GetPasswordInfo, _AD_GetSystemInfo,
  _AD_GetUserGroups, _AD_GetUserPrimaryGroup, _AD_ListExchangeMailboxStores, _AD_ListExchangeServers, _AD_ListPrintQueues,
  _AD_RecursiveGetMemberOf, _AD_SamAccountNameToFQDN
* All functions:
  Return dates converted to local time. Till now some dates were returned as UTC
* _AD_ErrorHandler: The global variable $iAD_COMError = 2 when the specified domain either does not exist or could not be contacted
  The global variable $iAD_COMError = 6 when the RPC-Server for a WMI-call is not available
* _AD_GetLastLoginDate: Returns @error = 2 when the user has never logged in
  @error changed from -1 to 1 when the user could not be found
  Lets you specify a parameter to only query DCs that belong to this site
* _AD_GetObjectClass: Returns @error = 2 when no records are found
* _AD_GetObjectsInOU: Multi-value attributes are returned as string with the pipe character as separator
* _AD_GetObjectsLocked: Returns @error = 2 when no records are found
* _AD_GetPasswordDontExpire: Returns @error = 1 when no records are found
* _AD_GetPasswordExpired: Returns @error = 1 when no expired passwords are found
* _AD_GetSystemInfo: Returns @error = 1 when creation of object "ADSystemInfo" failed. See @extended
* _AD_GetUserPrimaryGroup: Returns @error = 2 when no records are found
* _AD_Open: Now a return code specifies if the connect to the domain was successful

FIXED BUGS
==========
* Syntax Highlighting on SciTE now works (error corrected in au3.userudfs.properties)
* _AD_IsObjectLocked: Complete rewrite. 
  It now calculates the lockout time and lockout duration and returns the number of minutes till the user gets unlocked

NEW FUNCTIONS
=============
* _AD_JoinDomain. . . . . . . . . Joins the computer to the Active Directory in a specified OU
* _AD_AddEmailAddress . . . . . . Add a SMTP email address to an Exchange-enabled account

-------------------------------------------------------------------------------------------------------------------------------
2010-02-12 - Version 0.36 - Downloads: 322

NEW
===
* An installation docu "ReadMe.txt" (just a few lines) is included.
  It explains how to "install" the files and how to make user calltips and syntax highlighting work in SciTE (see attached JPG)
* A History.txt file is included for the change history
* The docu in the UDF itself has been extended. In the header you find the functions grouped by functionality (user related, group related ...)

CHANGED FUNCTIONS
=================
* _AD_IsMemberOf and _AD_GetUserGroups: If a flag is set the function checks if the primary user group is the same as the specified group. 
  This is because the default primary group (RID=513) doesn't return a list of members
* _AD_RecursiveGetMemberOf: You can specify if the function returns the groups as SAMAccountName or FQDN

FIXED BUGS
==========
* _AD_RecursiveGetMemberOf: The function doesn't crash anymore

NEW FUNCTIONS
=============
* _AD_SetGroupManagerCanModify. . Sets the group manager to be able to modify the member list
* _AD_GroupAssignManager. . . . . Assign the user as the manager of the group
* _AD_GroupRemoveManager. . . . . Remove the group manager from a group
* _AD_SetUserPrimaryGroup . . . . Set the primary group for a user
* _AD_CreateComputer. . . . . . . Creates and enables a computer account

KNOWN BUGS
==========
* _AD_IsLocked() and _AD_GetObjectsLocked(): Don't return a correct value when the lockouttime hasn't expired. 
  The functions have to be rewritten (unfortunately this will take some time)
* au3.userudfs.properties: Syntax highlighting doesn't work. Please change the first line
  au3.keywords.udfs=_ad_close _ad_samaccountnametofqdn _ad_fqdntosamaccountname \ to
  au3.keywords.user.udfs=_ad_open _ad_close _ad_samaccountnametofqdn _ad_fqdntosamaccountname \
  
-------------------------------------------------------------------------------------------------------------------------------
2010-02-03 - Version 0.35 - Downloads: 143

KNOWN BUGS
==========
* _AD_RecursiveGetMemberOf crashes. Please change line 746
    If UBound($aAD_Groups) = 1 Then Return $aAD_Groups[0] = 0
  to
    If UBound($aAD_Groups) = 1 Then
      $aAD_Groups[0] = 0
      Return $aAD_Groups
    EndIf

SCRIPT BREAKING CHANGES
=======================
For the following functions the result is no longer returned by ByRef but by Return. That means you have to change the function call from 
"_AD_Function($Result, $Param1)" to "$Result = _AD_Function($Param1)".
  * _AD_GetGroupMemberOf
  * _AD_GetGroupMembers
  * _AD_GetObjectsDisabled
  * _AD_GetObjectsInOU
  * _AD_GetObjectsLocked
  * _AD_GetPasswordDontExpire
  * _AD_GetPasswordExpired
  * _AD_GetUsergroups
  * _AD_RecursiveGetMemberOf

CHANGED FUNCTIONS
=================
* _AD_GetObjectProperties: Lets you specify in a comma-separated list which properties to return

-------------------------------------------------------------------------------------------------------------------------------
2010-02-01 - Version 0.34 - Downloads: 39

FIXED BUGS
==========
* _AD_IsMemberOf: Returned a wrong result when run with AutoIt > 3.3.2.0. Bug #1068: 'Binary to Int' was already fixed in the UDF. 
  The fixed bug in AutoIt plus the fix in the UDF returned -1 instead of 1.
* _AD_AddUserToGroup.au3: Example didn't work. The parameters for the function call were in the wrong order.
* _AD_EnableObject: Now works
* _AD_ListExchangeMailboxStores: Crashed when calculating the indices for the array

NEW FUNCTIONS
============
* _AD_GetSystemInfo . . . . . . . Retrieves data about the local computer if it is a member of a domain
* _AD_GetManagedBy. . . . . . . . Get a list of groups that are managed by any or a specific user
* _AD_GetManager. . . . . . . . . Get a list of users that are managed by any or a specific manager
* _AD_GetGroupAdmins. . . . . . . Get a list of users that are allowed to administer a group
* _AD_GroupManagerCanModify . . . Returns 1 if the group manager can modify the member list
* _AD_ListPrintQueues . . . . . . Enumerates all PrintQueues in the AD or for the specified spooler

REMOVED FUNCTIONS (temporarily)
===============================
* _AD_CopyObject: Doesn't work at the moment. Has to be rewritten.

CHANGED FUNCTIONS
=================
* _AD_GetLastLoginDate: Checks the availability of the DCs using ping. @error holds the number of DCs that could not be reached or 
   which returned no data. @extended holds the total number of DCs.
* _AD_GetObjectProperties: GUIDs, SIDs, SAMAccountType and UserAccountControl will now be decrypted
* _AD_GetObjectsInOU: Parameter $sAD_OU - The OU to retrieve from (FQDN) - now defaults to "" which means "search the whole AD tree"
* _AD_GetUserGroups: If you set a flag it returns the Primary User Group as well
* _AD_ObjectExists: Default for parameter $sAD_Property changed to "". The function then tries to determine whether to use sAMACccountName or FQDN
* _AD_RecursiveGetMemberOf: A flag defines if the function returns the group(s) it was inherited from (default = TRUE).
   If set to FALSE a sorted array with unique entries is returned
* _AD_SetAccountExpire: Extended description how the date can be formated
* The following functions now accept a SAMAccountName or a FQDN as parameters: 
  * _AD_AddUserToGroup
  * _AD_DeleteObject
  * _AD_DisableObject
  * _AD_DisablePasswordChange
  * _AD_DisablePasswordExpire
  * _AD_EnableObject
  * _AD_EnablePasswordChange
  * _AD_GetGroupAdmins
  * _AD_GetGroupMemberOf
  * _AD_GetGroupMembers
  * _AD_GetManagedBy
  * _AD_GetManager
  * _AD_GetObjectAttribute
  * _AD_GetObjectClass
  * _AD_GetObjectProperties
  * _AD_GetPasswordInfo
  * _AD_GetUserGroups
  * _AD_GetUserPrimaryGroup
  * _AD_GroupManagerCanModify
  * _AD_HasFullRights
  * _AD_HasGroupUpdateRights
  * _AD_HasUnlockResetRights
  * _AD_HasRequiredRights
  * _AD_IsMemberOf
  * _AD_IsObjectDisabled
  * _AD_IsObjectLocked
  * _AD_IsPasswordExpired
  * _AD_LockObject
  * _AD_ModifyAttribute
  * _AD_MoveObject
  * _AD_RecursiveGetMemberOf
  * _AD_RemoveUserFromGroup
  * _AD_RenameObject
  * _AD_SetAccountExpire
  * _AD_SetPassword
  * _AD_UnlockObject
* Improved error handling in some functions

-------------------------------------------------------------------------------------------------------------------------------
2010-01-17 - Version 0.33 - Downloads: 127

FIXED BUGS
==========
* _AD_EnablePasswordChange and _AD_DisablePasswordChange should work now even for Windows 2000 (but yet untested) as the code 
  has been rewritten to sort the ACE.

CHANGED FUNCTIONS
=================
* _AD_Open: Now works with the windows login name as well. The example code has been extended.
* _AD_GetAllOUs: Now returns a two-dimensional array. For each level in the AD tree the FQDN of the OU is returned as well. 
   A separator character can be specified.
* _AD_ListDomainControllers: For each site the distinguished name (FQDN) and a list of subnets that can connect to the site is returned in addition.
* _AD_ErrorHandler: Setting the global variable $iAD_Debug to values > 0 gives you detailed information about all COM errors.

NEW FUNCTIONS
=============
* _AD_ListEchangeServers. . . . . Enumerates all Exchange Servers in the Forest
* _AD_ListEchangeMailboxStores. . Enumerates all Exchange Mailbox Stores in the Forest

KNOWN BUGS
==========
* _AD_ListRoleOwners: Gives "Object referenced outside a "With" statement." in some environments

-------------------------------------------------------------------------------------------------------------------------------
2010-01-06 - Version 0.32 - Downloads: 82

FIXED BUGS
==========
* _AD_ListRoleOwners had $sAD_HostServer missing in the LDAP queries
* _AD_MoveObject didn't work at all. The new object name (RDN) was missing
* _AD_Open now works even if the PC is no domain member
* _AD_RenameObject had $sAD_HostServer missing in the LDAP query

CHANGED FUNCTIONS
=================
* _AD_Close now resets all global variables used by the UDF
* _AD_GetLastLoginDate now sets @error=2 if at least one of the Domain Controllers can not be reached
* _AD_GetObjectsInOU now has a sort parameter that lets you specify upon which attribute the result will be sorted
* _AD_ListDomainControllers now in addition returns the distinguished name, DNS host name and site
* _AD_MoveObject now accepts a new Display Name so an object can be moved and renamed in one go
* _AD_Open sets the COM error handler only if there isn't an error handler already active

NEW FUNCTIONS
=============
* _AD_CopyObject. . . . . . . . . Copies an object within the same or to another OU
* _AD_DisableObject . . . . . . . Disables an AD object (user account, computer account)
* _AD_EnableObject. . . . . . . . Enables an AD object (user account, computer account)
* _AD_GetPasswordInfo . . . . . . Returns password information from the domain policy and the user account
* _AD_LockObject. . . . . . . . . Locks an AD object (user account, computer account)
* _AD_UnlockObject. . . . . . . . Unlocks an AD object (user account, computer account)

REMOVED FUNCTIONS
=================
* _AD_ListSites. This info is now returned by _AD_ListDomainControllers

KNOWN BUGS
==========
* _AD_ListRoleOwners: Gives "Object referenced outside a "With" statement." in some environments
* _AD_EnablePasswordChange and _AD_DisablePasswordChange: Do not work on Windows 2000 because of missing ACE sorting. 
  I think we will have to rewrite the code.

-------------------------------------------------------------------------------------------------------------------------------
2009-12-25 - Version 0.31 - Downloads: 32

NEW FUNCTIONS
=============
* _AD_SetAccountExpire. . . . . . Sets a user account expiration date or sets the date to never expire
* _AD_DisablePasswordExpire . . . Sets users password not to expire
* _AD_EnablePasswordChange. . . . Allows user ability to change their password
* _AD_DisablePasswordChange . . . Denies user ability to change their password
* _AD_ListRootDSEAttributes . . . Returns an array with the RootDSE Atributes
* _AD_ListRoleOwners. . . . . . . Returns an array with the FSMO Role Owners
* _AD_ListSites . . . . . . . . . Returns an array with all sites

CHANGED FUNCTIONS
=================
* Modified _AD_Open so you now can connect from a PC that is no domain member.

KNOWN BUGS
==========
* _AD_Open: Still does not work when you connect from a PC that is no domain member. Is solved in the next version
* _AD_ListRoleOwners: Gives "Object referenced outside a "With" statement." in some environments
* _AD_ListSites: Gives a COM error in some environments
* _AD_MoveObject: Wrong syntax. Will be changed in next version
* _AD_EnablePasswordChange and _AD_DisablePasswordChange: Do not work at all. We investigate the situation - I think we will have to rewrite the code

-------------------------------------------------------------------------------------------------------------------------------
2009-12-20 - Version 0.30 - Downloads: 40

NEW FUNCTIONS
=============
This version contains new create/update/delete functions! Be very, very careful when testing.
I have no write access to an AD so couldn't test as thorough as I would like.
Best to be used in a test environment! Use at your own risk!
Every function displays a MsgBox and warns you what it tries to do. When you accept a GUI is displayed where you can enter the required info.
When you press the action button your AD will be changed.

* _AD_CreateOU. . . . . . . . . . Creates an OU in the specified parent OU
* _AD_CreateUser. . . . . . . . . Creates a user in a particular OU
* _AD_SetPassword . . . . . . . . Sets or clears a users password
* _AD_CreateGroup . . . . . . . . Creates a group in a particular OU
* _AD_AddUserToGroup. . . . . . . Adds a user to a group
* _AD_RemoveUserFromGroup . . . . Removes a user from a group
* _AD_ModifyAttribute . . . . . . Sets the attribute of the given object to the value specified
* _AD_RenameObject. . . . . . . . Renames an object within an OU
* _AD_MoveObject. . . . . . . . . Moves an object to another OU
* _AD_DeleteObject. . . . . . . . Deletes an object from an OU

-------------------------------------------------------------------------------------------------------------------------------
2009-12-09 - Version 0.25 - Downloads: 64

CHANGES
=======
* Removed some typos
* Extended error checking in the example scripts

-------------------------------------------------------------------------------------------------------------------------------
2009-12-09 - Version 0.24 - Downloads: 4

CHANGES
=======
* Removed some typos
* _AD_Open now allows to specify alternative credentials for authentification and allows to connect to another domain

-------------------------------------------------------------------------------------------------------------------------------
2009-12-08 - Version 0.23 - Downloads: 13

CHANGES
=======
* More examples
* Removed some typos
* Renamed _AD_GetObjectDisabled to _AD_GetObjectsDisabled and _AD_GetObjectLocked to _AD_GetObjectsLocked

-------------------------------------------------------------------------------------------------------------------------------
2009-12-06 - Version 0.22 - Downloads: 13

NEW FUNCTIONS
=============
* _AD_GetUserPrimaryGroup . . . . Returns the primary group the user is assigned to
* _AD_IsObjectDisabled. . . . . . Returns 1 if the object (user account or computer) is disabled
* _AD_IsObjectLocked. . . . . . . Returns 1 if the object (user account or computer) is locked
* _AD_IsPasswordExpired . . . . . Returns 1 if the password has expired
* _AD_GetObjectsDisabled. . . . . Returns an array with disabled objects (user accounts or computers)
* _AD_GetObjectsLocked. . . . . . Returns an array with locked objects (user accounts or computers)
* _AD_GetPasswordExpired. . . . . Returns an array with users with expired password
* _AD_GetPasswordDontExpire . . . Returns an array with user accounts for which the password will not expire
* _AD_GetObjectProperties . . . . Returns an array with all properties of an object in readable form

-------------------------------------------------------------------------------------------------------------------------------
2009-12-04 - Version 0.21 - Downloads: 14

NEW FUNCTIONS
=============
* _AD_HasFullRights . . . . . . . Returns 1 if the given user has full rights over the given group or user
* _AD_HasUnlockResetRights. . . . Returns 1 if the given user has unlock and password reset rights on the object
* _AD_HasRequiredRights . . . . . Returns 1 if the given user has the required rights on the object
* _AD_HasGroupUpdateRights. . . . Returns 1 if the given user has rights to update the group membership on the object

-------------------------------------------------------------------------------------------------------------------------------
2009-12-02 - Version 0.20 - Downloads: 17

NEW FUNCTIONS
=============
* _AD_GetLastLoginDate. . . . . . Returns the last login date of a user

-------------------------------------------------------------------------------------------------------------------------------
2009-12-01 - Version 0.10 - Downloads: 15

NEW FUNCTIONS
=============
* _AD_Open. . . . . . . . . . . . Opens a connection to the Active Directory
* _AD_Close . . . . . . . . . . . Closes the connection to the Active Directory opened by _AD_Open
* _AD_SamAccountNameToFQDN. . . . Returns a Fully Qualified Domain Name from a SamAccountName
* _AD_FQDNToSamAccountName. . . . Returns the SamAccountName of a Fully Qualified Domain Name
* _AD_FQDNToDisplayname . . . . . Returns the Display Name of a Fully Qualified Domain Name
* _AD_ObjectExists. . . . . . . . Returns 1 if exactly one object exists for the given property
* _AD_GetObjectAttribute. . . . . Returns the specified attribute for the given SamAccountName
* _AD_IsMemberOf. . . . . . . . . Returns 1 if the user is a member of the group
* _AD_GetObjectClass. . . . . . . Returns the class (user, group etc.) of an object
* _AD_GetUserGroups . . . . . . . Returns an array of group names that the user is immediately a member of
* _AD_RecursiveGetMemberOf. . . . Returns a recursively searched list of groups the group/user is a member of
* _AD_GetGroupMembers . . . . . . Returns an array of the group members
* _AD_GetGroupMemberOf. . . . . . Returns a list of group membership for a group
* _AD_GetObjectsInOU. . . . . . . Returns a filtered list of objects and attributes in a given OU
* _AD_GetAllOUs . . . . . . . . . Returns the complete list of OUs in an array
* _AD_ListDomainControllers . . . Returns the names of all domain controllers in the current Domain