Home > Enterprise >  DirectoryEntry.Exist in C# taking more than 10 Sec time when AD/NT user is not present
DirectoryEntry.Exist in C# taking more than 10 Sec time when AD/NT user is not present

Time:11-25

Issue can also be triggered with the following simple application:

Stopwatch watch = new Stopwatch();
string[] userNames = {"JunkName", "DummyName"};

foreach (var name in userNames)
{
    watch.Reset();
    watch.Start();

    if (DirectoryEntry.Exists("WinNT://"   Environment.MachineName   "/"   name))
    {
        Console.WriteLine($"user {name} found in "   watch.ElapsedMilliseconds   "ms");
    }
    else
    {
        Console.WriteLine($"user {name} not found in "   watch.ElapsedMilliseconds   "ms");
    }
}

There is no proper root cause for this to tell is it Microsoft API issue or something else.

However most of the search results mention if you search for a user that does not exist, rather than return false, the DirectoryEntry.Exists method will throw an exception.

But in our sample application it is not throwing any exception.

Also I tried below few suggestions to check how much execution time these sample code takes and found these will also takes more than 11 seconds the first time.

Sample 1:

using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
{
    UserPrincipal up = UserPrincipal.FindByIdentity(pc,
                    IdentityType.SamAccountName, name);
 
    UserExists = (up != null);
}

Sample 2:

DirectoryEntry dirEntryLocalMachine =
    new DirectoryEntry("WinNT://"   Environment.MachineName   ",computer");
 
bool UserExists =
    dirEntryLocalMachine.Children.Find(userIdentity, "user") != null;

It’s just a high level suspicion that OS updates would have caused the problem, may be my assumption is wrong.

Thanks in advance

CodePudding user response:

I encoutered the same latence one day, so I wrote this function that is much faster, maybe it can help you:

    private string FindUserSID(string domain, string user)
    {
        string output;

        try
        {
            NTAccount account = new NTAccount(domain   @"\"   user);
            SecurityIdentifier s = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
            output = s.ToString();
        }
        catch (IdentityNotMappedException)
        {
            output = null;
        }

        return output;
    }
  • Related