-1

I am retrieving a handful of LDAP (Active Directory) properties for about 10,000 users. I know that AD queries aren't the fastest in the world but at the 19 minute mark (almost exactly) the program stops processing and about 15 minutes after that I get the error

A device attached to the system is no longer functioning

on the DirectorySearcher.FindOne() method.

I don't think I'm doing anything weird in the code but I'm wondering if I need to re-write this to a FindAll() and then parse though that list.

searcher.Filter = "(sAMAccountName=" + u.LogonName + ")";

string[] properties = new string[]
         {
                "givenName",
                "sn",
                "displayName",
                "mail",
                "physicalDeliveryOfficeName",
                "division",
                "grpDivision"
         };

searcher.PropertiesToLoad.AddRange(properties);

SearchResult result = searcher.FindOne();

It doesn't stop on the same user every time and on the user it does stop on I've checked their attributes for anything that stands out and can't find anything out of the ordinary.

As you can imagine it gets quite tedious debugging in 35 minute increments so I'm hoping someone has seen this before or know about some hidden Active Directory connection time limit.

Thanks!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Brian Mitchell
  • 849
  • 1
  • 8
  • 24
  • Could you post the actual query? This looks like it's just looking for one user by name, which (assuming your domain controller is not literally a potato) should not take 19 minutes. – Jerry Federspiel Jul 31 '15 at 17:13
  • What happens if you tell it to grab a copy of all users from Ad in one go, rather than one at a time? – BugFinder Jul 31 '15 at 17:25
  • I actually have a List of ~10,000 users from an AD group and I'm iterating though one-at-a-time so I can populate the AD properties of each user. We have several DCs and it picks a different one each time but they are definitely not under-powered machines. I'm thinking about just doing a FindAll on all user objects but I think I'll have the same problem because the DirectorySearcher doesn't actually give you all of the properties until the code is actually trying to use it. It's like a big yield return – Brian Mitchell Jul 31 '15 at 18:02
  • Also, http://stackoverflow.com/questions/3095510/creating-a-user-in-active-directory-a-device-attached-to-the-system-is-not-func?rq=1 suggests something might be going on with samaccountname length (though in that question, the error occurred during a save and not a search...). – Jerry Federspiel Jul 31 '15 at 18:38

2 Answers2

0

Let's get your results in the biggest chunks we can. Getting results one-at-a-time is very slow. Unless you have tweaked your DC's settings, you can't get all 10,000 members at once; the default settings are to return a max of 1000 results at a time. So we'll do 26 queries, one for each letter a sAMAccountName might start with, using the * operator.

public static IEnumerable<SearchResult> DirectMembers(string nameOfMyBigGroup)
{
    var namePrefixes = "abcdefghijklmnopqrstuvwxyz".Select(c=>c.ToString());
    foreach(var namePrefix in namePrefixes) 
    {
        searcher.Filter = "(&(sAMAccountName=" + namePrefix + "*)(memberOf=" + nameOfMyBigGroup + "))";

        string[] properties = new string[]
            {
                "givenName",
                "sn",
                "displayName",
                "mail",
                "physicalDeliveryOfficeName",
                "division",
                "grpDivision"
            };

        searcher.PropertiesToLoad.AddRange(properties);

        var results = searcher.FindAll();
        foreach (var result in results) yield return result;
    }
}

EDIT: This assumes that your domain is set up such that sAMAccountName is case-insensitive, and that your users all have names whose first letters are drawn from the English alphabet. If these assumptions are not met, you'd want to do a more robust solution involving paging.

Jerry Federspiel
  • 1,504
  • 10
  • 14
-1

While I don't have a solid root cause - the problem has gone away. I haven't changed my code but when I tried it from home (on a VPN connection) the program successfully completes. It now takes 110 minutes due to the slower connection but it doesn't error out anymore.

Obviously it was something stemming from the server so I'm thinking I hit one of two possibilities.

  1. I was bombarding the DC while on the LAN and it couldn't keep up.
  2. The after-hours load on the DC is much lighter and allowing more resources to be allocated to my queries.
Brian Mitchell
  • 849
  • 1
  • 8
  • 24
  • Did I violate some code of conduct for the down votes? I figured I'd post an answer so people don't waste time on it. – Brian Mitchell Aug 01 '15 at 16:19
  • I think you may have been downvoted for giving an answer that didn't fully resolve the issue. While it's good that things are working on your end, this answer may not be very helpful to future SO users who have this (or related) problem and find this question. – Jerry Federspiel Aug 03 '15 at 15:48