water Posted May 17, 2019 Author Share Posted May 17, 2019 When you pass an escaped FQDN to _AD_RenameObject, function _AD_ObjectExists seems to escape the FQDN a second time which leads to an invalid FQDN. Seems we need to insert the escape function in _AD_RenameObject as well. Can you please test this modified function? _AD_RenameObjectEX("CN=geb./test,OU=Users,OU=Computers_W7,OU=GEB,OU=DE,DC=sub01,DC=domain,DC=local"), "geb.test") Func _AD_RenameObjectEX($sObject, $sCN) If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0) If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject) Local $oOU = __AD_ObjGet($oObject.Parent) ; Get the object of the OU/CN where the object resides $sCN = "CN=" & _AD_FixSpecialChars($sCN) ; escape all special characters $sObject = _AD_FixSpecialChars($sObject, 0, "/#") ; escape some special characters <== This line has been added $oOU.MoveHere("LDAP://" & $sAD_HostServer & "/" & $sObject, $sCN) If @error Then Return SetError(@error, 0, 0) Return 1 EndFunc ;==>_AD_RenameObjectEX This code is untested as I do not have write access to our AD!! My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
supersonic Posted May 20, 2019 Share Posted May 20, 2019 (edited) water, thank you - we are almost there In your _AD_RenameObjectEX() the line $sObject = _AD_FixSpecialChars($sObject, 0, "/#") is executed too late... The lines: Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject) Local $oOU = __AD_ObjGet($oObject.Parent) ; Get the object of the OU/CN where the object resides ... are already in need of an escaped object variable (in case $sObject = FQDN). That's why I placed the chars escape a bit higher: Func _AD_RenameObjectExBySupersonic($sObject, $sCN) If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0) If StringMid($sObject, 3, 1) <> "=" Then $sObject = _AD_SamAccountNameToFQDN($sObject) ; sAMAccountName provided If StringMid($sObject, 3, 1) = "=" Then $sObject = _AD_FixSpecialChars($sObject, 0, "/#") ; <<< NEW LINE <<< Local $oObject = __AD_ObjGet("LDAP://" & $sAD_HostServer & "/" & $sObject) Local $oOU = __AD_ObjGet($oObject.Parent) ; Get the object of the OU/CN where the object resides $sCN = "CN=" & _AD_FixSpecialChars($sCN) ; escape all special characters $oOU.MoveHere("LDAP://" & $sAD_HostServer & "/" & $sObject, $sCN) If @error Then Return SetError(@error, 0, 0) Return 1 EndFunc ;==>_AD_RenameObjectExBySupersonic Futhermore with If StringMid($sObject, 3, 1) = "=" Then it checks if an escape is really needed because $sObject can be a SamAccountName as well. What do you think? Edited May 20, 2019 by supersonic Link to comment Share on other sites More sharing options...
supersonic Posted May 20, 2019 Share Posted May 20, 2019 (edited) In many funtions one of the very first lines reads: If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0) That's good practice, but will lead to the same behaviour/issue _AD_RenameObject() is affected with... To me it could be more easy to extend _AD_ObjectExists() to handle an already escaped FQDN string 😄 Edited May 20, 2019 by supersonic Link to comment Share on other sites More sharing options...
water Posted May 20, 2019 Author Share Posted May 20, 2019 I just started to read about the need to escape characters again. I already tried to get my head around this subject some years ago. It can become quite complex as you can read here: https://www.rlmueller.net/CharactersEscaped.htm Right now my spare time is very limited. As I only have read access to our AD I can not create objects with special characters. So you (or someone else) would have to do all testing. As no one else has run into this problem since 2009 (when I started to work on the UDF) I think the best solution would be to simply create a custom function of _AD_RenameObject and remove _AD_ObjectExists. Maybe I will fix this bug sooner or later but for the time being this is the best I can offer. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
supersonic Posted May 20, 2019 Share Posted May 20, 2019 (edited) water, thank you for your reply - It was just a matter of time that someone came across this problem. So: It will be a pleasure to help out by testing modified/new script code. Maybe other forum members will help out, too. I think so... As for me, all the time/work we spend should keep your UDF as it is now - in a consistent/working state. And our efforts should even avoid "good workarounds". There are several solutions to this issue. One idea could be to rewrite _AD_FixSpecialChars() and _AD_ObjectExists() to handle already escaped strings. All functions benefit from it. Edited May 20, 2019 by supersonic Link to comment Share on other sites More sharing options...
supersonic Posted May 22, 2019 Share Posted May 22, 2019 (edited) water, as stated before I think modifying _AD_FixSpecialChars() [and _ AD_ObjectExists()] to handle (un-)escaped DNs same time more "elegant", I came up with this first approach - and lots of room for improvements 🙂: ; Removed. With this it is possible to unesacpe and escape within one function call. Furthermore a DN will be splitted first into its parts to ensure that only ...,XX=TextToUnEscape,... (red colored text) is transformed. I will take a closer look into _AD_ObjectExists() now. What do you think? Am I heading in the right direction? Edited May 23, 2019 by supersonic A more functional _AD_FixSpecialChars() will be released soon. Link to comment Share on other sites More sharing options...
supersonic Posted May 23, 2019 Share Posted May 23, 2019 (edited) water, finally I got some working (and hopefully understandable) script code: expandcollapse popup#include ".\..\..\AUTOIT\Include\Water\AD_01.04.11.00\AD.au3" Global $sTmp = "CN=geb. ,test,OU=Users,OU=Computers_W7,OU=GEB,OU=DE,DC=sub01,DC=domain,DC=local" _AD_Open() If (Not @error) Then Local $iTmp = _AD_RenameObjectEx($sTmp, "geb.test") MsgBox(0, "", StringFormat("@error\t\t = %s\r\n@extended\t = %s\r\nresult/return\t = %s", @error, @extended, $iTmp)) _AD_Close() EndIf ; #FUNCTION# ========================================================================================= ; Function Name: _AD_RenameObjectEx() ; Description: Renames an object within the same OU ; [https://docs.microsoft.com/de-de/windows/desktop/api/iads/nf-iads-iadscontainer-movehere/]. ; Note(s): None. ; Syntax: _AD_RenameObjectEx($sObject, $sCN) ; Parameter(s): $sObject - The object (user, group, computer [<COMPUTERNAME$>], distinguished name [CN, OU, ...]) to rename. ; $sCN - The new object name. ; Requirement(s): #Region #HEADER# ; Return Value(s): On success - Returns 1, @error = 0, @extended = 0. ; On failure - Returns 0, @extended = 0/n, @error: ; | 0 - No error. ; | 1 - '_AD_ObjectExistsEx()' failure, @extended: ; | | 0 - No error. ; | | n - '@error'. ; | 2 - '$oOU.MoveHere()' failure, @extended: ; | | 0 - No error. ; | | n - '@error'. ; Author(s): Jonathan Clelland, water, Supersonic! ; Example(s): None. ; ==================================================================================================== Func _AD_RenameObjectEx( _ $sObject, _ $sCN) Local $iReturn = 0 ; !!! ------------------------------------------------------------------------------------------------ If (StringRegExp($sObject, "(?i)^[CN=|OU=|DC=]{3}") = 1) Then ; DistinguishedName? $sObject = _AD_SamAccountNameToFQDN($sObject) ; SamAccountName provided. $sObject = _AD_FixSpecialCharsEx($sObject, 1 + 4) ; (Un-)escape all special characters. EndIf ; ---------------------------------------------------------------------------------------------------- If (_AD_ObjectExistsEx($sObject) = 1) Then Local Const $sLDAP = StringFormat("LDAP://%s/%s", $sAD_HostServer, $sObject) Local $oOU = __AD_ObjGet(__AD_ObjGet($sLDAP).Parent()) ; Get the object of the OU/CN where the object resides. $oOU.MoveHere($sLDAP, StringFormat("CN=%s", _AD_FixSpecialCharsEx(StringRegExpReplace($sCN, "(?i)^CN=", ""), 1 + 4))) ; (Un-)escape all special characters. If (Not @error) Then $iReturn = 1 Else ; Error. SetError(2, @error) EndIf $oOU = 0 ; !!! Else ; Error. SetError(1, @error) EndIf Return $iReturn EndFunc ;==>_AD_RenameObjectEx ; #FUNCTION# ========================================================================================= ; Function Name: _AD_ObjectExistsEx() ; Description: Checks if an object exists based on its name/distinguished name and opt. for a given property ; [https://www.rlmueller.net/ADOSearchTips.htm]. ; Note(s): None. ; Syntax: _AD_ObjectExistsEx([$sObject = Default [, $sProperty = Default]]) ; Parameter(s): $sObject - The object (user, group, computer [<COMPUTERNAME$>], distinguished name [CN, OU, ...]) to check for existence. ; $sProperty - The property to check with. If omitted, depending on the object type the property 'samAccountName' or 'distinguishedName' will be used. ; Requirement(s): #Region #HEADER# ; Return Value(s): On success - Returns 1, @error = 0, @extended = 0. ; On failure - Returns 0, @extended = 0/n, @error: ; | 0 - No error. ; | 1 - 'IsObj()' failure. ; | 2 - '$iRecordCount' failure (#1 [= 0]). ; | 4 - '$iRecordCount' failure (#2 [> 1]), @extended: ; | | 0 - No error. ; | | n - '$iRecordCount'. ; Author(s): Jonathan Clelland, water, Supersonic! ; Example(s): None. ; ==================================================================================================== Func _AD_ObjectExistsEx( _ $sObject = Default, _ $sProperty = Default) Local $iReturn = 0 ; !!! ------------------------------------------------------------------------------------------------ If ((IsKeyword($sObject) > 0) Or (Not StringLen($sObject)) Or ($sObject = -1)) Then $sObject = @UserName If ((IsKeyword($sProperty) > 0) Or (Not StringLen($sProperty)) Or ($sProperty = -1)) Then $sProperty = "samAccountName" If (StringRegExp($sObject, "(?i)^[CN=|OU=|DC=]{3}") = 1) Then ; DistinguishedName? $sObject = _AD_FixSpecialCharsEx($sObject, 1 + 4) ; (Un-)escape all special characters. $sProperty = "distinguishedName" EndIf EndIf ; ---------------------------------------------------------------------------------------------------- $__oAD_Command.CommandText() = StringFormat("<LDAP://%s/%s>;(%s=%s);ADSPath;Subtree", $sAD_HostServer, $sAD_DNSDomain, $sProperty, $sObject) Local $oRecordSet = $__oAD_Command.Execute() ; Try to retrieve the object property "ADSPath" ... If (IsObj($oRecordSet) = 1) Then Local Const $iRecordCount = $oRecordSet.RecordCount() If ($iRecordCount = 1) Then $iReturn = 1 ElseIf ($iRecordCount > 1) Then ; Error. SetError(4, $iRecordCount) Else ; Error. SetError(2, 0) EndIf $oRecordSet = 0 ; !!! Else ; Error. SetError(1, 0) EndIf Return $iReturn EndFunc ;==>_AD_ObjectExistsEx ; #FUNCTION# ========================================================================================= ; Function Name: _AD_FixSpecialCharsEx() ; Description: (Un-)escapes special characters in a distinguished name or LDAP filter ; [https://community.spiceworks.com/topic/444635-powershell-ad-ou-and-splitting-or-substring/], ; [https://www.autoitscript.com/forum/topic/112674-regular-expression-to-escape-characters/], ; [https://www.autoitscript.com/forum/topic/156987-escape-special-characters/], ; [https://www.autoitscript.com/forum/topic/199021-regex-only-at-startend-for-all-chars-of-group/], ; [https://www.regex101.com/], ; [https://www.rlmueller.net/CharactersEscaped.htm], ; [https://www.stackoverflow.com/questions/39794550/how-should-i-escape-commas-in-active-directory-filters/]. ; Note(s): None. ; Syntax: _AD_FixSpecialCharsEx(Const $sText [, $iOptions = Default [, $sEscapeChars = Default [, $bUnescapeBlanks = Default]]]) ; Parameter(s): $sText - The object (user, group, computer [<COMPUTERNAME$>], distinguished name [CN, OU, ...]) to rename. ; $iOptions - The instruction on how to (un-)escape - add the options together for multiple operations: ; | 0 - Do nothing. ; | 1 - Unescape. ; | 2 - Escape (default/standard). ; | 4 - Escape (LDAP filter). ; $sEscapeChars - The character set to use for (un-)escaping. ; $bUnescapeBlanks - The instruction blanks also being unescaped: ; | False - Do not unescape blanks (default/fallback/standard). ; | True - Unescape blanks. ; Requirement(s): #Region #HEADER# ; Return Value(s): On success - Returns (un-)escaped string, @error = 0, @extended = 0. ; On failure - Returns unchanged input string, @extended = 0/n, @error: ; | 0 - No error. ; | 1 - 'StringLen()' failure. ; | 2 - 'StringRegExp()' failure, @extended: ; | | 0 - No error. ; | | n - '@error'. ; | 4 - '_ArrayToString()' failure, @extended: ; | | 0 - No error. ; | | n - '@error'. ; Author(s): Jonathan Clelland, water, Supersonic! ; Example(s): None. ; ==================================================================================================== Func _AD_FixSpecialCharsEx( _ Const $sText, _ $iOptions = Default, _ $sEscapeChars = Default, _ $bUnescapeBlanks = Default) Local $sReturn = $sText ; Fallback (input = output). ; !!! ------------------------------------------------------------------------------------------------ If ((IsKeyword($iOptions) > 0) Or (Not StringLen($iOptions)) Or ($iOptions = -1)) Then $iOptions = 2 If ((IsKeyword($sEscapeChars) > 0) Or (Not StringLen($sEscapeChars)) Or ($sEscapeChars = -1)) Then $sEscapeChars = '"\/#,+<>;=' If ((IsKeyword($bUnescapeBlanks) > 0) Or (Not StringLen($bUnescapeBlanks)) Or ($bUnescapeBlanks == -1)) Then $bUnescapeBlanks = False ; ---------------------------------------------------------------------------------------------------- If (StringLen($sText) > 0) Then Local Const $bDN = (StringRegExp($sText, "(?i)^[CN=|OU=|DC=]{3}") = 1) ; DistinguishedName? Local $aText[1] = [$sText] Switch $bDN Case True $aText = StringRegExp($sText, "(?i)(?:CN|OU|DC)=.*?(?=(?<!\\),OU|,DC)|DC=.*$", 3) ; Assertion: negative look-behind. If (Not @error) Then ContinueCase ; !!! Else ; Error. SetError(2, @error) EndIf Case Else ; Case False Switch BitAND($iOptions, 1) Case 1 ; Unescape. Local $sEscapeCharsRegExp = StringStripWS($sEscapeChars, 8) ; $STR_STRIPALL Switch $bUnescapeBlanks Case True $sEscapeCharsRegExp = StringFormat(" %s", $sEscapeCharsRegExp) ContinueCase ; !!! Case Else ; Case False Local Const $aEscapeCharsRegExp = StringSplit($sEscapeCharsRegExp, "", 2) For $i = 0 To UBound($aText) - 1 Step 1 For $j In $aEscapeCharsRegExp If (Not StringRegExp($aText[$i], StringRegExpReplace($j, "(.)", "(\\\\\\$1)|(\\\\5C\\$1)"))) Then ContinueLoop (1) ; !!! $aText[$i] = StringRegExpReplace(StringRegExpReplace($aText[$i], StringFormat("\\\\5C(%s)", $j), "$1"), StringFormat("\\\\(%s)", $j), "$1") ; All occurences: '$j = ".{1}"'. Next Next EndSwitch ContinueCase ; !!! Case Else Local $bAlreadyEscaped = False Local $sPrefix = "" ; DistinguishedName. Switch BitAND($iOptions, 2) Case 2 ; Escape (default/standard). For $i = 0 To UBound($aText) - 1 Step 1 $sPrefix = ((Not $bDN) ? ("") : (StringLeft($aText[$i], 3))) $aText[$i] = $sPrefix & StringRegExpReplace(((Not $bDN) ? ($aText[$i]) : (StringMid($aText[$i], 4))), "(?<!\\)([" & $sEscapeChars & "])", "\\$1") ; Assertion: negative look-behind. Next $bAlreadyEscaped = (Not $bAlreadyEscaped) ; Toggle. ContinueCase ; !!! Case Else Switch BitAND($iOptions, 4) Case 4 ; Escape (LDAP filter). If (Not $bAlreadyEscaped) Then For $i = 0 To UBound($aText) - 1 Step 1 $sPrefix = ((Not $bDN) ? ("") : (StringLeft($aText[$i], 3))) $aText[$i] = $sPrefix & StringRegExpReplace(Execute('"' & StringRegExpReplace(((Not $bDN) ? ($aText[$i]) : (StringMid($aText[$i], 4))), "(\*|\(|\)|\\(?![[:xdigit:]]{2}))", '" & "\\" & Hex(AscW("$1"), 2) & "') & '"'), "(NUL)", "\\00") ; Several special characters must be escaped with either "\" or "\5C" when used in a LDAP search filter: $aText[$i] = $sPrefix & StringRegExpReplace(((Not $bDN) ? ($aText[$i]) : (StringMid($aText[$i], 4))), '(\,|\\|\#|\+|\<|\>|\;|\"|\=(?![[:xdigit:]]{2}))', "\\$1") $aText[$i] = $sPrefix & Execute("'" & StringRegExpReplace(((Not $bDN) ? ($aText[$i]) : (StringMid($aText[$i], 4))), "(?|^(\h*)|(\h*)$)", "' & StringReplace('$1', ' ', '\\ ') & '") & "'") Next EndIf ContinueCase ; !!! Case Else Local Const $sResult = _ArrayToString($aText, ",") If (Not @error) Then $sReturn = $sResult Else ; Error. SetError(4, @error) EndIf EndSwitch EndSwitch EndSwitch EndSwitch Else ; Error. SetError(1, 0) EndIf Return $sReturn EndFunc ;==>_AD_FixSpecialCharsEx And, yes, it is indeed a bit overcomplicated and somehow blown up Now it is possible (at least for me but I think for others, too) to rename objects with whatever formatted names and in either direction. It doesn't matter if it is already escaped or needs to be unescaped first. The current _AD_FixSpecialChars() is incomplete regarding $iOption = 3. Please read [https://stackoverflow.com/questions/39794550/how-should-i-escape-commas-in-active-directory-filters/]. Edited June 14, 2019 by supersonic Link to comment Share on other sites More sharing options...
water Posted June 4, 2019 Author Share Posted June 4, 2019 I guess you have already noticed that I started a poll to get an idea how many people use special characters in Distinguished Names. Till now only 4 members have participated and no one uses special characters. So my conclusio for the moment is: If you are happy with the solution you have created for yourself, I would just move the subject to the to-do list. If there is pressing demand by multiple users we could start working on the subject again. What do you think? My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
supersonic Posted June 5, 2019 Share Posted June 5, 2019 (edited) Haven't seen it until now... Now 5 members are participating. 🙂 I think your great UDF deserves this enhancement/improvement! And I think this is a bug because using special chars in DNs is valid and at least some functions can't handle such DNs or handling is incomplete. Using special chars in DNs is of course not sooo good or even bad practice. But sometimes it can't be avoided or it is out of your responsibility... And, yes, I could live with my "solution"... In the "near future" I have to tweak nearly all related functions to impove DN handling. My thought is to do it _once_ (togehter here in the forum) and and let others benefit, too. What do you mean with "to-do list"? I often made the experience that such lists meaning "never will be done". I can offer to do part of the testing - will be a pleasure to me! Now it is up to you. 😉 Edited June 5, 2019 by supersonic Link to comment Share on other sites More sharing options...
supersonic Posted June 11, 2019 Share Posted June 11, 2019 (edited) I reworked _AD_FixSpecialCharsEx() to make unescaping more reliable. Please see functions posted above. Edited June 14, 2019 by supersonic ... and reworked _AD_RenameObjectEx() also. Link to comment Share on other sites More sharing options...
water Posted June 14, 2019 Author Share Posted June 14, 2019 As you might have noticed only 4 users answered the poll. Only a single user uses special characters in Distinguished Names (this one is you). In regard of the low demand, my limited spare time and limited access to an AD to test I think i will not go this route. Maybe the other way round is sensible for you: remove the special characters from your objects This way you could stick with the unmodified AD UDF My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
supersonic Posted June 17, 2019 Share Posted June 17, 2019 water, thank you for your (final) statement regarding this. Your are right if time and interest matters... If you ever like to address this issue at some point in the future, please let me now. I’m still interested to help improving your UDF. BTW: Our objects are 99,99% „special-characters-free“. 🙂 But Enterprise-wide there are several ADs I don’t have write access to - respectively I am not responsible for them. As long I got a reliable/working solution for such „unavoidable circumstances“ I’m happy. Link to comment Share on other sites More sharing options...
AdamUL Posted August 28, 2019 Share Posted August 28, 2019 (edited) Hi water, I was working with the OutlookEx UDF and Distribution Lists. I was getting returns of DisplayNames and I need to covert them to FQDN. I noticed that there was an _AD_FQDNToDisplayName function in the AD UDF, but not an _AD_DisplayNameToFQDN. So I took the _AD_SamAccountNameToFQDN function and changed it to take the DisplayName. The function is below. I think this would be a nice addition to the UDF. ; #FUNCTION# ==================================================================================================================== ; Name...........: _AD_DisplayNameToFQDN ; Description ...: Returns a Fully Qualified Domain Name (FQDN) from a DisplayName. ; Syntax.........: _AD_DisplayNameToFQDN($sDisplayName) ; Parameters ....: $sDisplayName - Display name of AD object. ; Return values .: Success - Fully Qualified Domain Name (FQDN) ; Failure - "", sets @error to: ; |1 - No record returned from Active Directory. $sDisplayName not found ; |2 - More than one record found for $sDisplayName. Use _AD_GetObjectsInOU to get multiple FQDNs for DisplayName. ; Author ........: Jonathan Clelland from _AD_SamAccountNameToFQDN ; Modified.......: AdamUL, water from _AD_SamAccountNameToFQDN ; Remarks .......: The function escapes the following special characters (# and /). Commas in CN= or OU= have to be escaped by you. ; If $sDisplayName is already a FQDN then the function returns $sDisplayName unchanged and without raising an error. ; Related .......: _AD_FQDNToDisplayName ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _AD_DisplayNameToFQDN($sDisplayName) If StringMid($sDisplayName, 3, 1) = "=" Then Return $sDisplayName ; already a FQDN. Return unchanged $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(displayName=" & $sDisplayName & ");distinguishedName;subtree" Local $oRecordSet = $__oAD_Command.Execute If @error Or Not IsObj($oRecordSet) Or $oRecordSet.RecordCount = 0 Then Return SetError(1, @error, "") If $oRecordSet.RecordCount > 1 Then Return SetError(2, 0, "") Local $sFQDN = $oRecordSet.fields(0).value Return _AD_FixSpecialChars($sFQDN, 0, "/#") EndFunc ;==>_AD_DisplayNameToFQDN Updated the function to error on more than FQDN returned. Adam Edited September 3, 2019 by AdamUL Link to comment Share on other sites More sharing options...
water Posted August 28, 2019 Author Share Posted August 28, 2019 The problem with this approach is that DisplayName dos not have to be unique. So the query might return more then one DistinguishedNames. My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
AdamUL Posted September 3, 2019 Share Posted September 3, 2019 (edited) A good point about the DisplayName not needing to be unique, but in my AD at work, I have not run into this issue in my testing. It seems that the DisplayName, in our AD, is linked to the DisplayName in Exchange, and who knows what else on the back-end. This requires it to be unique in our AD. As for others, I can see where this can be an issue. I have updated the function above to error when there is more than one FQDN returned. For others interested, a good read: Uniqueness requirements for attributes and objects in Active Directory Adam Edited September 3, 2019 by AdamUL Link to comment Share on other sites More sharing options...
water Posted September 3, 2019 Author Share Posted September 3, 2019 I will add this link to the AD wiki My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
legend Posted November 25, 2019 Share Posted November 25, 2019 (edited) this function. "_AD_IsObjectDisabled" works for checking if a user is disabled, but it does not work for a machine object, is there a similar functions for checking if machine objects are disabled? and also, is there a way to get the description field of a object in AD? Edited November 25, 2019 by legend Link to comment Share on other sites More sharing options...
water Posted November 25, 2019 Author Share Posted November 25, 2019 "Does not work" is a bit general. What is the value of @error and @extended after calling the function? Sure. Use _AD_GetObjectAttribute My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
legend Posted November 25, 2019 Share Posted November 25, 2019 26 minutes ago, water said: "Does not work" is a bit general. What is the value of @error and @extended after calling the function? Sure. Use _AD_GetObjectAttribute It returns it as enabled, even though the object is disabled, and has been it for a long time, If _AD_IsObjectDisabled("FT4534") Then MsgBox(64, "Active Directory Functions", "disabled") Else MsgBox(64, "Active Directory Functions", "enabled") EndIf Link to comment Share on other sites More sharing options...
water Posted November 25, 2019 Author Share Posted November 25, 2019 The wiki is your friend A computer account needs a trailing "$": If _AD_IsObjectDisabled("FT4534$") Then My UDFs and Tutorials: Spoiler UDFs: Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki Standard UDFs: Excel - Example Scripts - Wiki Word - Wiki Tutorials: ADO - Wiki WebDriver - Wiki Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now