0

I need to run a foreach loop in DirectorySearcher.FindAll() and get the displayname property. It seems like there are memory issues with that (referred link: Memory Leak when using DirectorySearcher.FindAll()). My code is as follows:

List<string> usersList = new List<string>();
        string displayName = string.Empty;
        try
        {
            using (DirectoryEntry directoryEntry = new DirectoryEntry(ldap, userName, password))
            {
                DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
                directorySearcher.PageSize = 500;  // ADD THIS LINE HERE !
                string strFilter = "(&(objectCategory=User))";
                directorySearcher.PropertiesToLoad.Add("displayname");//first name
                directorySearcher.Filter = strFilter;
                directorySearcher.CacheResults = false;
                SearchResult result;
                var resultOne = directorySearcher.FindOne();

                using (var resultCol = directorySearcher.FindAll())
                {
                    for (int counter = 0; counter < resultCol.Count; counter++)
                    {
                        result = resultCol[counter];
                        if (result.Properties.Contains("displayname"))
                        {
                            displayName = (String)result.Properties["displayname"][0];
                            usersList.Add(displayName);
                        }
                    }
                } 
            }
        }

Is there any possible way to looping. I have also tried calling Dispose() method but it doesn't work. Any help is really appreciated.

Community
  • 1
  • 1
Shanky
  • 331
  • 1
  • 4
  • 17

2 Answers2

1

Here is a solution that I came up with for a project I'm working on that I think would work for you. My solution loops through the search results and returns the display name in a list of strings up to 20.

using (DirectorySearcher ds = new DirectorySearcher())
        {
            //My original filter
            //ds.Filter = string.Format("(|(&(objectClass=group)(|(samaccountname=*{0}*)(displayname=*{0}*)))(&(objectCategory=person)(objectClass=user)(|(samaccountname=*{0}*)(displayname=*{0}*))))", name);

            //Your Modified filter                
            ds.filter = "(objectCategory=User)"


            ds.PropertiesToLoad.Add("displayname");

            ds.SizeLimit = 20;

            SearchResultCollection result = ds.FindAll();

            List<string> names = new List<string>();

            foreach (SearchResult r in result)
            {
                var n = r.Properties["displayname"][0].ToString();
                if (!names.Contains(n))
                    names.Add(n);
            }

            return Json(names, JsonRequestBehavior.AllowGet);
        }
armstb01
  • 623
  • 8
  • 11
0

If it's not valid solution in managed code and your code depend hard on not-managed things such Active Directory i think it's good idea to move logic of directory searching to isolate such logic from your main application domain. It's way to not run against wind.

For me - better is to use outer console process, send parameters to argument string and catch StandardOutput.

It will be slower, but memory will be not leaked because it will be freed by system after console process die.

Additionally in this case u can not to make self-made ad_searcher.ex, but use standard dsquery and so on. For example:

[https://serverfault.com/questions/49405/command-line-to-list-users-in-a-windows-active-directory-group]

Another approach - usage of managed sub-domains, BUT i think it's harder and i'm not sure that all unmanaged resources will be freed.

Community
  • 1
  • 1
comdiv
  • 865
  • 7
  • 26
  • The command in the link is for local system whereas I have my AD on the server (LDAP). Any way to get that? – Shanky Sep 03 '14 at 04:17
  • As I said above - u can use your custom code but move it to isolated processes (singleton console executive with simple output), but dsquery seems to be usefull in all locations. It must be not much difference where exactly AD placed to query it from any host that is member of AD (i'm not well formed admin but it seems to be core of AD ideology). Full explanation for dsquery is here: http://technet.microsoft.com/en-us/library/cc754232.aspx – comdiv Sep 03 '14 at 05:05