How can I find what Organizational Units a computer is part of? ( Active Directory C# )
Asked Answered
C

3

8

I want to find the most specific OU my computer belongs to in C#. I have code that will get the information I need, but it doesn't feel robust and it would require complicated parsing. Are there better alternatives? Thoughts? Any help is appreciated!

Really what I want is an equivilent to the command prompt command:

dsquery computer -name COMP-HERE

But I need it in C#, which is proving to be problematic.

DirectorySearcher d = new DirectorySearcher("CN=COMP-HERE");
d.PropertiesToLoad.Add("adspath");
SearchResultCollection results = d.FindAll();
foreach (SearchResult searchResult in results) {
    foreach (string propertyKey in searchResult.Properties.PropertyNames) {
        ResultPropertyValueCollection valueCollection = searchResult.Properties[propertyKey];
        foreach (Object propertyValue in valueCollection) {
            Console.WriteLine(
            "{0}:{1}",
            propertyKey,
            propertyValue.ToString());
        }
    }
}
Console.ReadLine();
Cyndy answered 1/8, 2012 at 22:58 Comment(0)
O
4

Here's a solution using PrincipalContext and ComputerPrincipal in the System.DirectoryServices.AccountManagement namespace

string machineOU;
using (var context = new PrincipalContext(ContextType.Domain))
using (var comp = ComputerPrincipal.FindByIdentity(context, Environment.MachineName))
{
    machineOU = String.Join(",", comp.DistinguishedName.Split(',')
                                                       .SkipWhile(s => !s.StartsWith("OU="))
                                                       .ToArray());
}

The Linq treatment of the machine's distinguished name splits it into it's component elements, skips any elements before the first OU=... element, and then recombines the rest., leaving you with the distinguished name of the containing OU.

More Info

The classes in the System.DirectoryServices.AccountManagement namespace provide a fairly high-level abstraction of various type of security principals (accounts).

The PrincipalContext is basically an abstraction of the account repository. It can refer to a machine's account database (PrincipalType.Machine), an Active Directory domain or Global Catalog (PrincipalType.Domain), or an Active Directory Application partition (PrincipalType.ApplicationDirectory).

new PrincipalContext(ContextType.Domain) creates a PrincipalContext representing the local Active Directory domain.

Once we've got this context we can use the FindBy...() static methods on the various principal types (can be UserPrincipal, ComputerPrincipal or GroupPrincipal) to find the AD object we're looking for.

Oeo answered 1/8, 2012 at 23:20 Comment(6)
So my knowledge of C# and Active Directory is limited... Can you elaborate a little on what exactly this code is doing? I'm a bit confused by the PrincipalContext. Code works great though! I just want to understand it.Cyndy
Any reason for the use of SkipWhile rather than Where?Ezraezri
I can't upvote you again (actually I can't upvote you at all because I don't have enough reputation), so you'll have to live with only my thanks. You are awesome and this has been a very positive first-question-posted-experience on stack exchange for me.Cyndy
@BobVale - In this case the end result is basically the same, but for this kind of thing SkipWhile is more efficient. Where will apply the test to every element in the sequence, whereas SkipWhile only tests elements until it finds one that fails the test, and then just passes remaining elements of the sequence straight through to the output sequence.Oeo
Just thinking to be be strict to the question it's asking for OU but your answer includes the O elements and the dc elementsEzraezri
@BobVale - the elements are included because I'm returning the distinguished name (full LDAP path) of the OU.Oeo
H
0

I've done a simple search on google and found a lot of information on this. I think you are in the good direction, maybe compare your code with these links:

How to get list of Organizational Unit in Active Directory or here on stack overflow

Hayrick answered 1/8, 2012 at 23:7 Comment(1)
The first link you posted almost the opposite of what I'm trying to do (though very related). It is trying to find OU's, presumably to find things inside them. I'm trying to take a computer and find the OU that it is inside. Thank you for your prompt reply! It was unexpected.Cyndy
B
0

This is what worked for me

IEnumerable<string> machineOU;
using (var context = new PrincipalContext(ContextType.Domain))
using (var comp = ComputerPrincipal.FindByIdentity(context, Environment.MachineName))
{
  machineOU = comp.DistinguishedName.Split(',').Where(s => s.StartsWith("OU="));
}
Bannister answered 14/11, 2012 at 16:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.