javascriptnode.jspowershellactive-directoryldapjs

How to translate Powershell -> JavaScript for LDAP (dn -> canonicalName) conversion function


I found a great function that takes a valid Active Directory LDAP distinguishedName (DN) string and converts it to properly formatted canonicalName (not CN) string written in PowerShell.

Because I am using ldapjs in Node.js and need to retrieve an AD object's canonicalName attribute (which is not available natively using any of the Node/AD/LDAP libraries because the attribute in question is "constructed"), it would be best for me to convert this function to pure JavaScript.

How can I take a stab at it? The original post where this code (inserted below) was referenced from can be found here: https://gallery.technet.microsoft.com/scriptcenter/Get-CanonicalName-Convert-a2aa82e5

An example input value:

'CN=Eric Paw,OU=Sales,OU=People,DC=example,DC=com'

Expected Result:

'example.com/People/Sales/Eric Paw'

(Hints: Resultant JS function should be able to handle deeply OU-nested objects! Also I'm guessing that RegEx expressions could probably help handle some parts of this pretty nicely but don't have the faintest clue how to implement that.)

function Get-CanonicalName ([string[]]$DistinguishedName) { 
    foreach ($dn in $DistinguishedName) {      
        ## Split the dn string up into it's constituent parts 
        $d = $dn.Split(',') 
        
        ## get parts excluding the parts relevant to the FQDN and trim off the dn syntax 
        $arr = (@(($d | Where-Object { $_ -notmatch 'DC=' }) | ForEach-Object { $_.Substring(3) }))  
        
        ## Flip the order of the array. 
        [array]::Reverse($arr)  
 
        ## Create and return the string representation in canonical name format of the supplied DN 
        "{0}/{1}" -f  (($d | Where-Object { $_ -match 'dc=' } | ForEach-Object { $_.Replace('DC=','') }) -join '.'), ($arr -join '/') 
    } 
}

Solution

  • Here a stab at answering my own question, hope it helps someone. Seems to work for me just fine even in the case where the distinguishedName attribute of the user has multiple CNs in the value/path.

    function formatCanonicalName( DN ) {
    
      var CN = "", DC = "", OU = "";
      DN = DN.replace("\\,", "~");
      DN.split(",").forEach(function(item) {
        switch (item.substring(0,2)) {
          case 'CN': 
            if (item.indexOf('~') > -1) { item = item.split("~")[1] + " " + item.split("~")[0]; }
            CN = item.replace("CN=", "") + "/" + CN; 
            break;
          case 'OU': 
            OU = item.replace("OU=", "") + '/' + OU; 
            break;
          case 
            'DC': DC = DC + item.replace("DC=", "") + '.'; 
            break;
        };
      }); 
      return DC.substring(0, DC.length - 1) + '/' + OU + CN.substring(0, CN.length - 1); 
    }