none
How do I get the OU where an object is located

    Domanda

  • I am particularly looking to determine the OU containing a User object.  The Get-ADUser gives a DistinguishedName but this also contains the CN.  How can I get the containing OU?  Is there any better way then extracting it?  How would I extract it, if no better way? 

    I am not familiar with PowerShell string command, but I am sure we could extract everything from the string after or including the first ",OU=".  That should avoid any "CN=Last, First" stuff we'd run into with comma delimiting, etc.

    Thanks in advance.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 12:47

Risposte

  • This will get the parent container:

    PS C:\scripts> ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent
    
    #output:
    LDAP://OU=UserAccounts,DC=contoso,DC=local
    


    Grant Ward, a.k.a. Bigteddy

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 14:50
  • I thought I'd nailed it there.  You could also do this:

     ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent -replace 'LDAP://'
    

    ...instead of substring.

    Grant Ward, a.k.a. Bigteddy

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 15:16
  • This will get the parent container:

    PS C:\scripts> ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent
    
    #output:
    LDAP://OU=UserAccounts,DC=contoso,DC=local


    Grant Ward, a.k.a. Bigteddy

    Adapting @Bigteddy's code to give me the end result I need:


    PS D:\PowerShell> $dn = "CN=Chase Roth,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local"
    PS D:\PowerShell> $ou = (([ADSI]"LDAP://$dn").parent).Substring(7) PS D:\PowerShell> $ou OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local


    This also works beautifully with the default CN=Users container:

    PS D:\PowerShell> (Get-ADUser Administrator).DistinguishedName
    CN=Administrator,CN=Users,DC=basd,DC=local
    
    PS D:\PowerShell> $dn = (Get-ADUser Administrator).DistinguishedName
    PS D:\PowerShell> $ou = (([ADSI]"LDAP://$dn").parent).substring(7)
    PS D:\PowerShell> $ou
    CN=Users,DC=basd,DC=local

    Great Job Bigteddy! 

    Unless someone can find a problem I think we've got it!


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 15:12

Tutte le risposte

  • So I have figured out 2 different ways:

    $ou = $dn.Substring($dn.IndexOf(",OU=")+1)

        and/or

    $ou = $dn.Substring($dn.IndexOf("OU="))

    Are there better ways to do this?  Will this be reliable?  Not sure if I am missing anything obvious...


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 13:06
  • On the Get-QADUser there are 2 attributes returned that you could use:

    ParentContainer (i.e. contoso.com/Depts/Finance)

    ParentContainerDN (i.e. OU=Finance, OU=Depts, DC=contoso, DC=com)

    • Proposto come risposta Andy E Stewart martedì 26 giugno 2012 13:08
    • Proposta come risposta annullata Chase Roth martedì 26 giugno 2012 13:33
    martedì 26 giugno 2012 13:08
  • I am a Windows Server 2008 R2 domain.  I don't have Get-QADUser.  That is not built in I am assuming?  It sure would be nice to have that built into the stock Get-ADUser command.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.


    • Modificato Chase Roth martedì 26 giugno 2012 13:14
    martedì 26 giugno 2012 13:14
  • This one is a bit better, because it accepts wildcards:

    $user = Read-Host 'Enter samAccountName for user'
    Get-ADUser -Filter 'samAccountName -like $user' |  ForEach-Object { 
        $DN = $_.distinguishedname -split ',' 
        $container = $DN[1..($DN.count -1)] -join ','
        Write-Host "User $($dn[0] -replace 'CN=') located here: $container"
        }


    Grant Ward, a.k.a. Bigteddy

    martedì 26 giugno 2012 13:22
  • That is how I would do it.  Unfortunately, I know of no command that will just give you the OU, you have to extrapolate it from the DN.  Quest tools work well, just as Andy points out, and has alot of functionality that the AD cmdlets do not have, but it just means you will have to install something else instead of using the available options.

    Edit - The first one is what I would use, the comma would not be necessary.

    martedì 26 giugno 2012 13:23
  • I am a Windows Server 2008 R2 domain.  I don't have Get-QADUser.  That is not built in I am assuming?  It sure would be nice to have that built into the stock Get-ADUser command.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.


    How about this? I wasnt sure if I interpreted your problem correctly. From the output you can easy fatch the location where he is located :)

                 $Sam = "string"
               
                $ADSearcher = New-Object DirectoryServices.DirectorySearcher
                $ADSearcher.SearchRoot = [adsi]'LDAP://OU=test,OU=test,DC=test,DC=test,DC=com'
                $ADSearcher.Filter = "(&(objectCategory=person)(sAMAccountName=$sam))"
                $ADResult = $ADSearcher.FindAll()
               
                $adresult | ForEach-Object {$_.properties} | ForEach-Object {$_.distinguishedname}



    Regards / Freundliche Grüsse King Julien






    martedì 26 giugno 2012 13:24
  • Something like this?

    $user = Read-Host 'Enter samAccountName for user'
    Get-ADUser -Filter 'samAccountName -eq $user' |  ForEach-Object { 
        $DN = $_.distinguishedname -split ',' 
        $container = $DN[1..($DN.count -1)] -join ','
        Write-Host "User $user located here: $container"
        }


    Grant Ward, a.k.a. Bigteddy

    This would break if my DN was "CN=Roth, Chase,OU=Users,DC=domain,DC=com" as it would return " Chase,OU=Users,DC=domain,DC=com" would it not?  Am I missing something in there?  Shown below:

    PS D:\PowerShell> Get-ADUser flast | fl DistinguishedName
    
    DistinguishedName : CN=Last\, First M.,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local
    
    PS D:\PowerShell> $user = Read-Host 'Enter samAccountName for user'
    Enter samAccountName for user: flast
    
    PS D:\PowerShell> Get-ADUser -Filter 'samAccountName -eq $user' |  ForEach-Object {
    >>     $DN = $_.distinguishedname -split ','
    >>     $container = $DN[1..($DN.count -1)] -join ','
    >>     Write-Host "User $user located here: $container"
    >>     }
    >>
    User flast located here:  First M.,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local
    PS D:\PowerShell>
    

    I think the SubString and IndexOf seem to be the way to go without installing the Quest tools.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 13:27
  • That is how I would do it.  Unfortunately, I know of no command that will just give you the OU, you have to extrapolate it from the DN.  Quest tools work well, just as Andy points out, and has alot of functionality that the AD cmdlets do not have, but it just means you will have to install something else instead of using the available options.

    Edit - The first one is what I would use, the comma would not be necessary.

    Neither of them return the ',' (comma).  The '+1' makes it return just the 'OU=...' but I figured it added one more layer of complexity, for lack of a better term, to make sure it started at the right place.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 13:29
  • How about this? I wasnt sure if I interpreted your problem correctly. From the output you can easy fatch the location where he is located :)

                 $Sam = "string"
               
                $ADSearcher = New-Object DirectoryServices.DirectorySearcher
                $ADSearcher.SearchRoot = [adsi]'LDAP://OU=test,OU=test,DC=test,DC=test,DC=com'
                $ADSearcher.Filter = "(&(objectCategory=person)(sAMAccountName=$sam))"
                $ADResult = $ADSearcher.FindAll()
               
                $adresult | ForEach-Object {$_.properties} | ForEach-Object {$_."msrtcsip-primaryhomeserver"}



    Regards / Freundliche Grüsse King Julien

    This looks like it would work, but more complicated and additional binds to AD since my scripts will already be using "Import-Module ActiveDirectory".  Thanks for the alternate method though.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 13:33
  • How about this? I wasnt sure if I interpreted your problem correctly. From the output you can easy fatch the location where he is located :)

                 $Sam = "string"
               
                $ADSearcher = New-Object DirectoryServices.DirectorySearcher
                $ADSearcher.SearchRoot = [adsi]'LDAP://OU=test,OU=test,DC=test,DC=test,DC=com'
                $ADSearcher.Filter = "(&(objectCategory=person)(sAMAccountName=$sam))"
                $ADResult = $ADSearcher.FindAll()
               
                $adresult | ForEach-Object {$_.properties} | ForEach-Object {$_."msrtcsip-primaryhomeserver"}



    Regards / Freundliche Grüsse King Julien

    This looks like it would work, but more complicated and additional binds to AD since my scripts will already be using "Import-Module ActiveDirectory".  Thanks for the alternate method though.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    I've edited it, wrote the wrong property in the last foreach loop :)

    Why dont you use regex for retrieving the OU? Once you got the DN that should be no problem.


    Regards / Freundliche Grüsse King Julien


    martedì 26 giugno 2012 13:34
  • Why dont you use regex for retrieving the OU?


    Regards / Freundliche Grüsse King Julien

    How would that be done?  Could you provide the same code?  It would need to be sure to take into account CN names that could be "Roth, Chase" or "Chase Roth, Jr." or etc. 

    So SubString() and IndexOf() method or Regex?  Which method is better?  Which method uses less processing, if being done over thousands of users?


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 13:39
  • Why dont you use regex for retrieving the OU?


    Regards / Freundliche Grüsse King Julien

    How would that be done?  Could you provide the same code?  It would need to be sure to take into account CN names that could be "Roth, Chase" or "Chase Roth, Jr." or etc. 

    So SubString() and IndexOf() method or Regex?  Which method is better?  Which method uses less processing, if being done over thousands of users?


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    I will get back to you, now with an example from your side its easier :)


    Regards / Freundliche Grüsse King Julien








    martedì 26 giugno 2012 13:41
  • @King Julien:  I don't see the point of your regex code.  It did not extract the OU information from the fully qualified DN. How do I use that...doesn;t your code just match if a 'CN=' is present?  Edit:  Oh you changed the code, but I still don't get it.  Going with other post.  Thanks though.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.


    • Modificato Chase Roth martedì 26 giugno 2012 13:49 previous user edited their post
    martedì 26 giugno 2012 13:48
  • @King Julien:  I don't see the point of your regex code.  It did not extract the OU information from the fully qualified DN. How do I use that...doesn;t your code just match if a 'CN=' is present?  Edit:  Oh you changed the code, but I still don't get it.  Going with other post.  Thanks though.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.


    $dn -match '=(\w+\s\w+)'

    $matches[1]

    here we go, try that ^^

    This matches the sam that consists of two words (required) and is seperated by a space (required).

    (This just works if a CN= is present which usually should be)


    Regards / Freundliche Grüsse King Julien







    martedì 26 giugno 2012 13:53
  • $dn -match '=(\w+\s\w+)'

    $matches[1]

    here we go, try that ^^

    This matches the sam that consists of two words (required) and is seperated by a space (required).

    (This just works if a CN= is present which usually should be)

    You are misunderstanding.  I want the OU not the CN.  Here is the Output of your code:

    PS D:\PowerShell> $dn ="CN=Chase Roth,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local"
    
    PS D:\PowerShell> $dn -match '=(\w+\s\w+)'
    True
    
    PS D:\PowerShell> $matches[1]
    Chase Roth

    I want to get the OU:

    PS D:\PowerShell> $dn = "CN=Chase Roth,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local"
    
    PS D:\PowerShell> $dn.Substring($dn.IndexOf(",OU=")+1)
    OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local
    
    PS D:\PowerShell> $dn.Substring($dn.IndexOf("OU="))
    OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local
    


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 14:32
  • Thanks to EVERYONE that contributed! 

    I am going to go with what I feel is the simplest and seems to be most effective.

    $ou = $dn.Substring($dn.IndexOf("OU="))


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 14:37
  • Thanks to EVERYONE that contributed! 

    I am going to go with what I feel is the simplest and seems to be most effective.

    $ou = $dn.Substring($dn.IndexOf("OU="))


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    This will break on the default Users container, which is a CN:

    CN=Users,DC=Contoso,DC=com


    Grant Ward, a.k.a. Bigteddy

    martedì 26 giugno 2012 14:41
  • This will get the parent container:

    PS C:\scripts> ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent
    
    #output:
    LDAP://OU=UserAccounts,DC=contoso,DC=local
    


    Grant Ward, a.k.a. Bigteddy

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 14:50
  • $ou = $dn.Substring($dn.IndexOf("OU="))


    This will break on the default Users container, which is a CN:

    CN=Users,DC=Contoso,DC=com


    Grant Ward, a.k.a. Bigteddy

    Luckily I don't have actual users in the CN=Users but you're right!  It will break it.  I'd like to solve the issue for everyone that may hit this post in the future. 

    How about regex to grab the 2nd "CN=" or first "OU=" and everything after that?  Maybe even the 2nd "=" sign.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 14:52
  • $dn ="CN=Chase Roth,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local"
    
    $ou = $dn.Substring($dn.IndexOf("OU="))
    $cn= $dn.Substring(0,$dn.IndexOf("OU=")-1)
    $name = $cn.Substring($cn.IndexOf("=")+1)
    
    $ou
    $cn
    $name



    Life is short, Enjoy it now. Cyreli

    martedì 26 giugno 2012 14:56
  • This will get the parent container:

    PS C:\scripts> ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent
    
    #output:
    LDAP://OU=UserAccounts,DC=contoso,DC=local


    Grant Ward, a.k.a. Bigteddy

    Adapting @Bigteddy's code to give me the end result I need:


    PS D:\PowerShell> $dn = "CN=Chase Roth,OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local"
    PS D:\PowerShell> $ou = (([ADSI]"LDAP://$dn").parent).Substring(7) PS D:\PowerShell> $ou OU=DIS,OU=Employee,OU=BASD-Users,DC=basd,DC=local


    This also works beautifully with the default CN=Users container:

    PS D:\PowerShell> (Get-ADUser Administrator).DistinguishedName
    CN=Administrator,CN=Users,DC=basd,DC=local
    
    PS D:\PowerShell> $dn = (Get-ADUser Administrator).DistinguishedName
    PS D:\PowerShell> $ou = (([ADSI]"LDAP://$dn").parent).substring(7)
    PS D:\PowerShell> $ou
    CN=Users,DC=basd,DC=local

    Great Job Bigteddy! 

    Unless someone can find a problem I think we've got it!


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 15:12
  • I thought I'd nailed it there.  You could also do this:

     ([adsi]"LDAP://CN=Sam Willow,OU=UserAccounts,DC=contoso,DC=local").parent -replace 'LDAP://'
    

    ...instead of substring.

    Grant Ward, a.k.a. Bigteddy

    • Contrassegnato come risposta Chase Roth martedì 26 giugno 2012 15:19
    martedì 26 giugno 2012 15:16
  • Great job everyone.  Thanks for all the suggestions, even those that were not doing what the thread was about as they may come in handy in the future!


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 15:25
  • I am a Windows Server 2008 R2 domain.  I don't have Get-QADUser.  That is not built in I am assuming?  It sure would be nice to have that built into the stock Get-ADUser command.


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.


    Quest Software's AD tools are great stuff.  And free, even for work use.  Their PowerGUI Pro editor is pretty darned good, too.  And for the record, I don't work there

    martedì 26 giugno 2012 19:07
  • Quest Software's AD tools are great stuff.  And free, even for work use.  Their PowerGUI Pro editor is pretty darned good, too.  And for the record, I don't work there

    Where do they get installed?  Client workstation or on a Server?  Domain Controller?


    Find this post helpful? Does this post answer your question? Be sure to mark it appropriately to help others find answers to their searches.

    martedì 26 giugno 2012 19:09