C# and LDAP

G

Guest

Hello all,
I am trying to get all 'active' user details (username, firstname,
lastname) from win 2003 AD server using System.DirectoryServices. It works
fine. But it is too slow for getting all the 400 users. The following is the
code i have written.
I found that its doing s pretty quick search. But its taking quite some time
inside the 'foreach' loop to get the DirectoryEntry for each searchresult.
Any suggestions welcome! Thanks in advance.

public void GetAvailableUsers()
{
DirectorySearcher dSearcher = new DirectorySearcher("LDAP://DC=" +
ADServers[0].Code.Trim() + ",DC=" + this.domain + ",DC=ORG");
dSearcher.SearchScope = SearchScope.Subtree;

dSearcher.Filter =
"(&(objectCategory=person)(objectClass=user))";
dSearcher.PropertiesToLoad.Add("givenName");
dSearcher.PropertiesToLoad.Add("sn");
dSearcher.PropertiesToLoad.Add("sAMAccountName");

dSearcher.PropertiesToLoad.Add("userAccountControl");

SearchResultCollection sResults = dSearcher.FindAll();

try
{
int i = 0;
foreach (SearchResult sResult in
sResults)//dSearcher.FindAll())
{

DirectoryEntry dirEntry = sResult.GetDirectoryEntry();
i += 1;
if
(((((int)dirEntry.Properties["userAccountControl"].Value) & 2) == 0) &&
!(this.peakNetUsers.Contains(domain + @"\" +
dirEntry.Properties["sAMAccountName"].Value.ToString()))) //0=ENABLED
2=DISABLED
{
//add user tomy list
}

}

}
catch (Exception ex)
{
//MessageBox.Show("Critical AD Server Error : " +
ex.Message, "Critical Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);

}


}
 
J

Joshua Flanagan

If you are not updating the directory, you do not need to retrieve the
DirectoryEntry. The SearchResult object's Properties collection should
contain all of the data you need (if it doesn't, add the missing
property to your PropertiesToLoad).

Instead of:
dirEntry.Properties["userAccountControl"].Value
use:
sResult.Properties["userAccountControl"].Value

and remove the call to GetDirectoryEntry(). That should speed up things
quite a bit.
Note you cannot update the values on a SearchResult.

Joshua Flanagan
http://flimflan.com/blog


PS: Change your catch(Exception ex) to catch(COMException ex). It won't
speed things up, but it will make sure you only catch exceptions truly
caused by your AD lookup. It is good practice to only catch specific
exception types that you can handle.
 
G

Guest

Thanks for your reply.
SearchResult's property collection doesn't have prop 'Value'.
I am using framework 2.0.

Thanks.

Joshua Flanagan said:
If you are not updating the directory, you do not need to retrieve the
DirectoryEntry. The SearchResult object's Properties collection should
contain all of the data you need (if it doesn't, add the missing
property to your PropertiesToLoad).

Instead of:
dirEntry.Properties["userAccountControl"].Value
use:
sResult.Properties["userAccountControl"].Value

and remove the call to GetDirectoryEntry(). That should speed up things
quite a bit.
Note you cannot update the values on a SearchResult.

Joshua Flanagan
http://flimflan.com/blog


PS: Change your catch(Exception ex) to catch(COMException ex). It won't
speed things up, but it will make sure you only catch exceptions truly
caused by your AD lookup. It is good practice to only catch specific
exception types that you can handle.
Hello all,
I am trying to get all 'active' user details (username, firstname,
lastname) from win 2003 AD server using System.DirectoryServices. It works
fine. But it is too slow for getting all the 400 users. The following is the
code i have written.
I found that its doing s pretty quick search. But its taking quite some time
inside the 'foreach' loop to get the DirectoryEntry for each searchresult.
Any suggestions welcome! Thanks in advance.

public void GetAvailableUsers()
{
DirectorySearcher dSearcher = new DirectorySearcher("LDAP://DC=" +
ADServers[0].Code.Trim() + ",DC=" + this.domain + ",DC=ORG");
dSearcher.SearchScope = SearchScope.Subtree;

dSearcher.Filter =
"(&(objectCategory=person)(objectClass=user))";
dSearcher.PropertiesToLoad.Add("givenName");
dSearcher.PropertiesToLoad.Add("sn");
dSearcher.PropertiesToLoad.Add("sAMAccountName");

dSearcher.PropertiesToLoad.Add("userAccountControl");

SearchResultCollection sResults = dSearcher.FindAll();

try
{
int i = 0;
foreach (SearchResult sResult in
sResults)//dSearcher.FindAll())
{

DirectoryEntry dirEntry = sResult.GetDirectoryEntry();
i += 1;
if
(((((int)dirEntry.Properties["userAccountControl"].Value) & 2) == 0) &&
!(this.peakNetUsers.Contains(domain + @"\" +
dirEntry.Properties["sAMAccountName"].Value.ToString()))) //0=ENABLED
2=DISABLED
{
//add user tomy list
}

}

}
catch (Exception ex)
{
//MessageBox.Show("Critical AD Server Error : " +
ex.Message, "Critical Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);

}


}
 
W

Willy Denoyette [MVP]

Vish said:
Thanks for your reply.
SearchResult's property collection doesn't have prop 'Value'.
I am using framework 2.0.

Thanks.

Joshua is right, you should not retrieve a DirectoryEntry here, just enum
the returned search result collection like this:

try
{
int i = 0;
foreach (SearchResult sResult in sResults)//dSearcher.FindAll())
{
if
(((((int)sResult .Properties["userAccountControl"][0]) & 2) == 0) &&
!(this.peakNetUsers.Contains(domain + @"\" +
sResult.Properties["sAMAccountName"][0].ToString())))
//0=ENABLED 2=DISABLED
....

note the array indexer ([0]) notation to retrieve the first (and only)
element from the ResultPropertyValueCollection like sResult
..Properties["userAccountControl"], if this happen to contain more elements
check the Count property and act accordingly.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top