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.