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();
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.