8

I am using System.DirectoryServices.AccountManagement.dll to deal with Active Directory to get all the users in the "Domain Users" group.

This is returning all the users in the domain but I need to get just the enabled ones.

Here is some sample code:

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

PrincipalContext pcContext = GetPrincipalContext();

GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext,
                               IdentityType.Name,
                               "Domain Users");

foreach (Principal user in grp.GetMembers(true).OfType<UserPrincipal>())
{
    if (user.Enabled != false)
    {
        users.Add(user.Name);
    }
}

Other groups work fine, but when the group is "Domain Users", the value of the Enabled property is false for all users. This makes it impossible to distinguish between enabled and disabled users without doing a further query for each user.

Mickey
  • 943
  • 1
  • 19
  • 41
Moutasim Momani
  • 149
  • 2
  • 3
  • 7
  • Do you only need the account name? Is there a requirement to use the AccountManagement namespace? Do you do anything with the UserPrincipal object other than store the name? I only ask because your requirements may be better served using the DirectoryServices namespace and the DirectorySearcher with an LDAP Filter as something like: (&(objectclass=user)(memberOf=CN=Domain Users,dc=company,dc=com)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) Which would return all users in that group that are enabled. – randcd Aug 12 '13 at 18:35
  • 1
    randcd: I would prefer to use the AM namespace since it provides a very clean API. I could certainly use LDAP, but then everything becomes much more complicated (especially in the case where users are only a member of Domain Users because it's their primary group, since it's not listed in `memberOf` in that case). – RobSiklos Aug 13 '13 at 19:26
  • The "Principal" in the ForEach loop should actually be "UserPrincipal" - "Enabled" is not a method or property accessible on a Princpal object. At least not in .net 4.6.1. This can all be done with the System.DirectoryServices.AccountManagement namespace. – DtechNet Dec 19 '16 at 22:04

3 Answers3

1

UserPrinciple objects have a bool Enabled property for this.

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal_properties.aspx

// Add this to GetUserDetails
objUserDetails.EmployeeId = UserPrinical.EmployeeId;


// Then condition the add to only add enabled
if (objUserDetails.Enabled) {
    objUserDetails.Add(GetUserDetails(p.Name));
}
Joe Petrini
  • 489
  • 1
  • 3
  • 12
  • This does not solve the problem, since the `Enabled` property doesn't seem to be populated properly when the group being queried is "Domain Users" – RobSiklos Aug 09 '13 at 15:23
1

A method around this problem could be to first search for Enabled Users using the PrincipalSearcher class and then use the Principal's method of IsMemberOf()

List<string> users = List<string>();
PrincipalContext pcContext = GetPrincipalContext();
GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, IdentityType.Name, "Domain Users");
UserPrincipal searchFilter = new UserPrincipal(pcContext){ Enabled = true }
PrincipalSearcher searcher = new PrincipalSearcher(searchFilter);
PrincipalSearchResult<Principal> results = searcher.FindAll();
foreach (Principal user in results)
    if (user.IsMemberOf(grp))
        users.Add(user.SamAccountName);
Hive
  • 193
  • 1
  • 4
  • 17
0

There's a remark on the MSDN page of the Enabled property saying :

If the principal has not been persisted in the store, this property returns null. After the principal is persisted, the default enabled setting depends on the store. The AD DS and AD LDS stores disable new principals when they are persisted, whereas SAM enables new principals when they are persisted. The application can only set this property to a value after it has been persisted in the store.

Perhaps it's related if the default is false ?

Also, there's a post on the MSDN forum about UserPrincipal.Enabled returns False for accounts that are in fact enabled? and that really sound similar to your issue. According to the post there's perhaps a solution here :

I think I misunderstood. Disregard what I posted before. I think I know what's happening. The GetMembers method apparently isn't loading the UserPrincipal data. I don't know if there is a better solution, but the following works (at least on my AD):

foreach (UserPrincipal user in group.GetMembers(false))
{
   UserPrincipal tempUser = UserPrincipal.FindByIdentity(context, user.SamAccountName);
   // use tempUser.Enabled
   // other code here
}
Emmanuel Istace
  • 1,209
  • 2
  • 14
  • 32
  • The users are already persisted, so the first part of your answer is not relevant to the question. As for the rest, yes - I know I can do this - the question states that we want to have a correct value for the `Enabled` property *without* having to do any additional queries (especially not one per user like in that foreach loop). The post you're quoting from even says that this solution is too slow to be useful. – RobSiklos Aug 11 '13 at 20:58