Check if UserPrincipal is enabled

I am using C # code to query Active Directory. The main problem I am facing is to determine if an account is disabled or not. Looking at many of the online articles, it would seem that you can't rely on the UserPrincipal.Enabled property alone to determine if a user account is enabled or not. Fair enough since its a nullable Boolean, but when the AD admin disables the account, this appears to get false. The problem I am having is when I query for client-side AD I find that most user accounts UserPrincipal objects return false for this property. So when I use this code to check if an account is disabled:

private bool IsUserEnabled(UserPrincipal userPrincipal)
{
        bool isEnabled = true;

        if (userPrincipal.AccountExpirationDate != null)
        {
            // Check the expiration date is not passed.
            if (userPrincipal.AccountExpirationDate <= DateTime.Now)
            {
                Log.DebugFormat("User {0} account has expired on {1}", userPrincipal.DisplayName, userPrincipal.AccountExpirationDate.Value);
                isEnabled = false;
            }
        }

        if (userPrincipal.IsAccountLockedOut())
        {
            isEnabled = false;
            Log.DebugFormat("User {0} account is locked out", userPrincipal.DisplayName);
        }

        if (userPrincipal.Enabled != null)
        {
            isEnabled = userPrincipal.Enabled.Value;
            Log.DebugFormat("User {0} account is Enabled is set to {1}", userPrincipal.DisplayName, userPrincipal.Enabled.Value);
        }

        return isEnabled;
}

      

Most of the accounts are disabled due to validation userPrincipal.Enabled

.

However, if I leave that and just rely on the account expiration date and account lockout properties, I can skip someone disabled by using a checkbox in Active Directory that just disables the account - without setting the expiration date account.

All accounts where enabled returns false are effectively active accounts that can log into the domain.

How can you check if an account is actually enabled or not?

+5


source to share


3 answers


I faced a similar problem and was equally puzzled!

I originally used System.DirectoryServices.DirectorySearcher

to find disabled users. The AD user's entry status (re-disabled, locked out, password expired, etc.) Stored in the UserAccountControl property. You can pass a DirectorySearcher filter to find, say, disabled accounts by specifying the UserAccountControl property as part of the filter.

I never liked this approach as it boiled down to using a magic string and some magic numbers to build a query; for example, this is the filter used to find disabled accounts:

 var searcher = new DirectorySearcher(dirEntry)
            {
                Filter = "(UserAccountControl:1.2.840.113556.1.4.803:=2)",
                PageSize = 50
            };

      

When I switched to using UserPrincipal, I was thrilled to see this nice "Enabled" convenience property right in the class. At least until I realized that it doesn't return the same value that the DirectorySearcher filter returns.



Unfortunately, the only reliable way to determine if an account was actually enabled is to dig into the underlying DirectoryEntry object and check the UserAccountControl property directly, i.e .:

var result = (DirectoryEntry)userPrincipal.GetUnderlyingObject();
var uac = (int)result.Properties["useraccountcontrol"];
var isEnabled = !Convert.ToBoolean(uac & 2);

      

Note. The UserAccountControl property is a "flags" enumeration; all possible values ​​for the UserAccountControl property can be found here: https://msdn.microsoft.com/en-us/library/aa772300(v=vs.85).aspx

I ended up embedding the above snippet in a small extension method; Fortunately, doing this extra work of retrieving the UserAccountControl property didn't noticeably slow down my AD queries.

+2


source


I can tell you what works for me in one of my applications. Here is a snippet from my application:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "domain.com"))
{
    using (UserPrincipal user = UserPrincipal.FindByIdentity(pc, "Doe, John"))
    {
        Console.Out.Write(user.Enabled);
    }
}

      



This for me exactly returns whether the account is enabled or not.

0


source


I got the solution by expanding the result and going to base and expanding the base. You will see the included property there. Then I right click on the expression and add to view and copy the observation expression into my code.

  using (var context = new PrincipalContext(ContextType.Domain, "xyz.com", "Administrator", "xyz123"))
        {
            using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
            {
             foreach (var result in searcher.FindAll())
                {
                  DirectoryEntry de = result.GetUnderlyingObject() as DrectoryEntry;
             foreach (String key in de.Properties.PropertyNames)
                {
                   Console.WriteLine(key + " : " + de.Properties[key].Value);
                }
               Console.WriteLine("Enabled: "    +((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled);
               Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
                    }
                 }
             }
        Console.ReadLine();

      

((System.DirectoryServices.AccountManagement.AuthenticablePrincipal)(result)).Enabled

works fine to get enabled true or false in user list.

0


source







All Articles