Reputation: 141
I have a list of Users being returned from AD and I need to filter them to just return the Active users. This is my code, but it's not returning any users. After extensive googling, I'm at a loss as to what's missing;
public static List<Models.ToolUser> ActiveUsers()
{
int unlimitedAccess;
//string userAccountControl;
string listEntry;
string fName;
string lName;
string unlimitedAccessGroup;
//This is getting the List of Users that I need to filter
List<Models.ToolUser> activeUserList = UIDal.GetFullWindowsUserList();
try
{
string filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))";
string[] propertiesToLoad = new string[1] { "name" };
using (DirectoryEntry de = GetDirectoryEntryWithGc())
using (DirectorySearcher searcher = new DirectorySearcher(de, filter, propertiesToLoad))
using (SearchResultCollection results = searcher.FindAll())
{
foreach (SearchResult result in results)
{
unlimitedAccess = 0;
fName = result.Properties["givenName"][0].ToString();
lName = result.Properties["sn"][0].ToString();
listEntry = fName + " " + lName;
var name = result.Properties["sAMAccountName"][0].ToString();
var u = new ToolUser
{
ToolUserId = 0,
DomainAccount = result.Properties["sAMAccountName"][0].ToString(),
FirstName = fName,
LastName = lName,
LoginId = "pc-" + result.Properties["sAMAccountName"][0].ToString(),
UnlimitedAccess = unlimitedAccess > 0,
};
activeUserList.Add(u);
}
}
}
catch
{
}
return activeUserList;
}
Upvotes: 0
Views: 952
Reputation: 40898
Empty catch blocks are the devil. You should at least log the exception before continuing.
In this case, your empty catch block is hiding what's really going on. You're getting an "Index was out of range" exception here:
fName = result.Properties["givenName"][0].ToString();
Because result.Properties["givenName"]
is an empty collection (there is no element at index 0
). That's happening because of this:
string[] propertiesToLoad = new string[1] { "name" };
You are telling the search to only return the name
attribute for the objects found, but then you go on to use givenName
, sn
and sAMAccountName
. You need to tell it to return those attributes if you intend to use them:
string[] propertiesToLoad = new string[3] { "givenName", "sn", "sAMAccountName" };
That said, givenName
and sn
are not required attributes. If those attributes are empty on any of the accounts found, then they will not appear in the Properties
collection at all and you will run into the same exception again. So you should test that those attributes are actually there before trying to use them. For example, this will check and set the variables to an empty string if the attribute doesn't exist:
fName = result.Properties.Contains("givenName") ? result.Properties["givenName"][0].ToString() : "";
lName = result.Properties.Contains("sn") ? result.Properties["sn"][0].ToString() : "";
Upvotes: 1