Jump to content

Active Directory UDF (II)


water
 Share

Recommended Posts

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 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 comment
Share on other sites

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 by supersonic
Link to comment
Share on other sites

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 by supersonic
Link to comment
Share on other sites

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 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 comment
Share on other sites

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 by supersonic
Link to comment
Share on other sites

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 by supersonic
A more functional _AD_FixSpecialChars() will be released soon.
Link to comment
Share on other sites

water,

finally I got some working (and hopefully understandable) script code:

#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 by supersonic
Link to comment
Share on other sites

  • 2 weeks later...

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 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 comment
Share on other sites

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 by supersonic
Link to comment
Share on other sites

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 :huh:
This way you could stick with the unmodified AD UDF :)

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 comment
Share on other sites

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

  • 2 months later...

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 by AdamUL
Link to comment
Share on other sites

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 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 comment
Share on other sites

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 by AdamUL
Link to comment
Share on other sites

I will add this link to the AD wiki :)

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 comment
Share on other sites

  • 2 months later...

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 by legend
Link to comment
Share on other sites

"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 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 comment
Share on other sites

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

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 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 comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...