How to determine if user account is enabled or disabled

C#Active DirectoryAttributesDirectoryservices

C# Problem Overview


I am throwing together a quick C# win forms app to help resolve a repetitive clerical job.

I have performed a search in AD for all user accounts and am adding them to a list view with check boxes.

I would like to default the listviewitems' default check state to depend upon the enabled/disabled state of the account.

string path = "LDAP://dc=example,dc=local";
DirectoryEntry directoryRoot = new DirectoryEntry(path);
DirectorySearcher searcher = new DirectorySearcher(directoryRoot,
    "(&(objectClass=User)(objectCategory=Person))");
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult result in results)
{
    DirectoryEntry de = result.GetDirectoryEntry();
    ListViewItem lvi = new ListViewItem(
        (string)de.Properties["SAMAccountName"][0]);
    // lvi.Checked = (bool) de.Properties["AccountEnabled"]
    lvwUsers.Items.Add(lvi);
}

I'm struggling to find the right attribute to parse to get the state of the account from the DirectoryEntry object. I've searched for AD User attributes, but not found anything useful.

Can anyone offer any pointers?

C# Solutions


Solution 1 - C#

this code here should work...

private bool IsActive(DirectoryEntry de)
{
  if (de.NativeGuid == null) return false;

  int flags = (int)de.Properties["userAccountControl"].Value;

  return !Convert.ToBoolean(flags & 0x0002);
}

Solution 2 - C#

Using System.DirectoryServices.AccountManagement: domainName and username must be the string values of the domain and username.

using (var domainContext = new PrincipalContext(ContextType.Domain, domainName))
{
    using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, username)) 
    {
	    if (foundUser.Enabled.HasValue) 
	    {
		    return (bool)foundUser.Enabled;
	    }
        else
        {
            return true; //or false depending what result you want in the case of Enabled being NULL
        }
    }
}

Solution 3 - C#

Not that anyone asked, but here's a java version (since I ended up here looking for one). Null checking is left as an exercise for the reader.

private Boolean isActive(SearchResult searchResult) {
    Attribute userAccountControlAttr = searchResult.getAttributes().get("UserAccountControl");
    Integer userAccountControlInt = new Integer((String) userAccoutControlAttr.get());
    Boolean disabled = BooleanUtils.toBooleanObject(userAccountControlInt & 0x0002);
    return !disabled;
}

Solution 4 - C#

You can use something like this:

    ADUserAccountControl flags;
    Enum.TryParse(de.Properties["userAccountControl"].Value.ToString(), out flags);

    if(flags.HasFlag(ADUserAccountControl.ACCOUNTDISABLE)
    {
        // account is disabled
    }

Here is a complete list of all possible flags:

    /// <summary>
    /// Source: https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
    /// </summary>
    public enum ADUserAccountControl : long
    {
        SCRIPT = 0x0001,
        ACCOUNTDISABLE = 0x0002,
        HOMEDIR_REQUIRED = 0x0008,
        LOCKOUT = 0x0010,
        PASSWD_NOTREQD = 0x0020,
        PASSWD_CANT_CHANGE = 0x0040,
        ENCRYPTED_TEXT_PWD_ALLOWED = 0x0080,
        TEMP_DUPLICATE_ACCOUNT = 0x0100,
        NORMAL_ACCOUNT = 0x0200,
        INTERDOMAIN_TRUST_ACCOUNT = 0x0800,
        WORKSTATION_TRUST_ACCOUNT = 0x1000,
        SERVER_TRUST_ACCOUNT = 0x2000,
        DONT_EXPIRE_PASSWORD = 0x10000,
        MNS_LOGON_ACCOUNT = 0x20000,
        SMARTCARD_REQUIRED = 0x40000,
        TRUSTED_FOR_DELEGATION = 0x80000,
        NOT_DELEGATED = 0x100000,
        USE_DES_KEY_ONLY = 0x200000,
        DONT_REQ_PREAUTH = 0x400000,
        PASSWORD_EXPIRED = 0x800000,
        TRUSTED_TO_AUTH_FOR_DELEGATION = 0x1000000,
        PARTIAL_SECRETS_ACCOUNT = 0x04000000,
    }

Solution 5 - C#

I came here looking for an answer, but it was only for DirectoryEntry. So here is a code that works for SearchResult / SearchResultCollection, for people who had the same problem:

private bool checkIfActive(SearchResult sr)
{
    var vaPropertiy = sr.Properties["userAccountControl"];

    if (vaPropertiy.Count > 0) 
    {
        if (vaPropertiy[0].ToString() == "512" || vaPropertiy[0].ToString() == "66048") 
        {
            return true;
        } 
        
        return false;
    }

    return false;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBryanView Question on Stackoverflow
Solution 1 - C#Dimi TakisView Answer on Stackoverflow
Solution 2 - C#MichelleView Answer on Stackoverflow
Solution 3 - C#user3006472View Answer on Stackoverflow
Solution 4 - C#marsh-wiggleView Answer on Stackoverflow
Solution 5 - C#NichtmetallView Answer on Stackoverflow