none
Find domain distinguished name from string using ADSI

    Întrebare

  • Iam working on a project with a requirement of being able to search different domains using ADSI.  During the use of the script in question, the user is prompted for a domain or domain controller to search for objects on.  How do I convert the user's response into an LDAP path that can be used as a searchroot for an ADSI search?

    User Input = "contoso"
    Desired results = "LDAP://DC=contoso,DC=com"

    User Input = "domA"
    Desired results = "LDAP://DC=DomA,DC=contoso,DC=com"

    Here is the current script:

    $Domain = [Microsoft.VisualBasic.Interaction]::InputBox("Enter a domain to connect to...", "Connect to domain...", "")

    $searchroot= ?

    $properties=@('dnshostname','operatingsystem','whenchanged')
    $searcher=[adsisearcher]"(&(objectClass=computer)(name=$ComputerName))"
    $searcher.PropertiesToLoad.AddRange($Properties)
    $searcher.SearchRoot=$searchRoot
    $searcher.FindAll()


    Rich Prescott | Infrastructure Architect, Windows Engineer and PowerShell blogger | MCITP, MCTS, MCP

    Engineering Efficiency
    @Rich_Prescott
    Client System Administration tool
    AD User Creation tool
    30 octombrie 2011 23:37

Răspunsuri

  • I use the NameTranslate object to convert between NT format (NetBIOS) names and Distinguished Names. It is efficient, but a bit obscure in PowerShell. In this case:

     

    # Prompt for NetBIOS name of the domain.
    $Domain = Read-Host "Enter NetBIOS name of the domain"

    # Use the NameTranslate object.
    $objTrans = New-Object -comObject "NameTranslate"
    $objNT = $objTrans.GetType()

    # Initialize NameTranslate by locating the Global Catalog.
    $objNT.InvokeMember("Init", "InvokeMethod", $Null, $objTrans, (3, $Null))
    # Specify NetBIOS name of the domain with trailing slash.
    $objNT.InvokeMember("Set", "InvokeMethod", $Null, $objTrans, (3, "$Domain\"))
    # Retrieve Distinguished Name of the domain.
    $DNSDomain = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $objTrans, 1)

    $DNSDomain

    -----

     This assumes the domain is trusted. If necessary, you can also provide alternate credentials. You would use the InitEx method instead of Init and pass credentials.

     


    Richard Mueller - MVP Directory Services
    31 octombrie 2011 03:03

Toate mesajele

  • Your best bet would be to list the default domain that they are authenticated against as an example of what they should put in. This will minimize the chance of inaccurate information being typed in by the user. Otherwise, trying to translate what the user is typing into a distinguished name will be a challenge. Here is an example of what I have used in the past:

    $domain = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the LDAP path for the Domain or press OK to use the default domain.", 
    "Domain Query", "$(([adsisearcher]'').SearchRoot.distinguishedName)") <br/>#Your code to prepare the search 
    $properties=@('dnshostname','operatingsystem','whenchanged')
    $searcher=[adsisearcher]"(&(objectClass=computer)(name=$ComputerName))"
    $searcher.PropertiesToLoad.AddRange($Properties)
    $searcher.SearchRoot=$searchRoot
    $searcher.FindAll()<br/>#Add the search root <br/>$searcher.SearchRoot= [adsi]"LDAP://$domain"<br/>#Get the data<br/>$Results = $searcher.FindAll()
    

    Hope this helps...

    31 octombrie 2011 03:02
  • I use the NameTranslate object to convert between NT format (NetBIOS) names and Distinguished Names. It is efficient, but a bit obscure in PowerShell. In this case:

     

    # Prompt for NetBIOS name of the domain.
    $Domain = Read-Host "Enter NetBIOS name of the domain"

    # Use the NameTranslate object.
    $objTrans = New-Object -comObject "NameTranslate"
    $objNT = $objTrans.GetType()

    # Initialize NameTranslate by locating the Global Catalog.
    $objNT.InvokeMember("Init", "InvokeMethod", $Null, $objTrans, (3, $Null))
    # Specify NetBIOS name of the domain with trailing slash.
    $objNT.InvokeMember("Set", "InvokeMethod", $Null, $objTrans, (3, "$Domain\"))
    # Retrieve Distinguished Name of the domain.
    $DNSDomain = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $objTrans, 1)

    $DNSDomain

    -----

     This assumes the domain is trusted. If necessary, you can also provide alternate credentials. You would use the InitEx method instead of Init and pass credentials.

     


    Richard Mueller - MVP Directory Services
    31 octombrie 2011 03:03
  • Just supply the names in a drop down instead of asking the user to submit?

    Is every other domain except the forest root a child domain?


    Dan
    31 octombrie 2011 14:18
  • If you are going to have users pick from a list of domains, you might want to retrieve them programmatically. You can get the DN of all naming contexts known in the GC from the RootDSE object. This includes the schema and configuration contexts, so you would want to skip those. The code could be similar to:

     

    $Domain = [System.DirectoryServices.DirectoryEntry]([ADSI]"LDAP://rootDSE")
    $NCs = $Domain.Get("NamingContexts")
    ForEach ($NC In $NCs) {$NC}

    -----

    You can also retrieve the "defaultNamingContext", which is the DN of the domain in which the current user authenticated, and the "rootDomainNamingContext", which is the DN of the root domain. Finally, if needed, you can retrieve the DNS name of all known AD trees from the ADSystemInfo object. For example:

     

    $SysInfo = New-Object -ComObject "ADSystemInfo"
    $Trees = $SysInfo.GetType().InvokeMember("GetTrees", "InvokeMethod", $Null, $SysInfo, $Null)
    ForEach ($Tree In $Trees) {$Tree}

    -----

     

    From ADSystemInfo you can also retrieve "UserName", the DN of the current user, and "ComputerName", the DN of the local computer object in AD. In both of these cases, however, you would use "GetProperty" instead of "InvokeMethod" in the InvokeMember method, since they are properties rather than methods.

     


    Richard Mueller - MVP Directory Services
    31 octombrie 2011 15:16
  • Thanks everyone for your help.  One of the requirements for this project is that it work in any organization and so hard-coding domains is a no-go. I am providing the user with the option of setting certain default settings for other pieces, but creating LDAP paths is something that not all admins are comfortable with, so I want to provide them an easy way to connect to other domains.

    Richard's second suggestion would technically work in most environments, but there are some where connectivity is not the greatest between all domains in a forest and using the rootDSE to determine domains would take forever. 

    My approach is this issue is to prompt the user for the domain that they want to manage, similar to how ADUC works.  I just didn't know of a way to mimic the functionality of ADUC's domain selection.


    Rich Prescott | Infrastructure Architect, Windows Engineer and PowerShell blogger | MCITP, MCTS, MCP

    Engineering Efficiency
    @Rich_Prescott
    Client System Administration tool
    AD User Creation tool
    31 octombrie 2011 15:57