简体   繁体   中英

How do I determine if an OU exists using C#'s System.DirectoryServices.AccountManagement?

While C# and Active Directory : test if an OU exist is a useful example, C# appears to be moving away from the System.DirectoryServices functionality to System.DirectoryServices.AccountManagement as it provides a nicer and cleaner syntax.

I'm currently have some code where the only use of DirectoryEntry is to determine if an OU exists. Is it possible to determine if an OU exists without using DirectoryEntry , instead just using the Principal -based functionality?

You can't.

The documentation for the AccountManagement namespace starts off with:

The System.DirectoryServices.AccountManagement namespace provides uniform access and manipulation of user, computer, and group security principals

Note that it says nothing of OUs. They didn't design it for that.

In LDAP in general, the quickest way to test whether an object exists is to bind directly to the object. That is exactly what DirectoryEntry.Exists() does. You can see the source code here :

/// <devdoc>
/// Searches the directory store at the given path to see whether an entry exists.
/// </devdoc>        
public static bool Exists(string path)
{
    DirectoryEntry entry = new DirectoryEntry(path);
    try
    {
        entry.Bind(true);       // throws exceptions (possibly can break applications) 
        return entry.Bound;
    }
    catch (System.Runtime.InteropServices.COMException e)
    {
        if (e.ErrorCode == unchecked((int)0x80072030) ||
             e.ErrorCode == unchecked((int)0x80070003) ||   // ERROR_DS_NO_SUCH_OBJECT and path not found (not found in strict sense)
             e.ErrorCode == unchecked((int)0x800708AC))     // Group name could not be found
            return false;
        throw;
    }
    finally
    {
        entry.Dispose();
    }
}

Any other way of doing it will perform worse.

Kind of a side note: while the AccountManagement namespace makes some things easier for the developer, it comes at a cost. It always performs worse than using DirectoryEntry directly. Sometimes it's not noticeable, but if you're doing a lot of lookups, it can add up fast.

The following will test whether or not an OU exists using a PrincipalContext object.

try
{ 
    var ou = new PrincipalContext(ContextType.Domain, targetedDcUrl, container);            
    var searchPrincipal = new UserPrincipal(ou);
    var searcher = new PrincipalSearcher(searchPrincipal);

    var users = searcher.FindAll();
}
catch (PrincipalOperationException ex)
{
    Console.WriteLine("Container does not exist");
}

The accessing of the OU when searching (or any other action that requires a read/write to the domain) will cause an exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM