Search code examples
c#active-directorypasswordsdirectoryentry

Setting Password Never Expires for new AD user using System.DirectoryServices.DirectoryEntry (ADLDS, ADAM, Active Directory Application Mode)


I've seen this question and tried with both "userPrincipalName" and "userFlags" and I'm receiving "The specified directory service attribute or value does not exist" in both cases.

I am able to set the attribute with the following in Powershell

Get-ADUser -Filter 'cn -like "*username*"' -Server <serveraddrress> -SearchBase "<searchbase>" | Set-ADUser -PasswordNeverExpires:$True

My C# code is as follows, it works fine if I remove the line setting userAccountControl, but it creates the user with Password Never Expires = FALSE

using (var dirEntry = entry.Children.Add("CN=" + username, "user"))
{
    dirEntry.Properties["userPrincipalName"].Value = string.Format("{0}@principal", username);
    dirEntry.CommitChanges();
    dirEntry.Options.PasswordPort = port;
    dirEntry.Options.PasswordEncoding = PasswordEncodingMethod.PasswordEncodingClear;
    dirEntry.Invoke("SetPassword", password);

    if (!string.IsNullOrEmpty(email))
         dirEntry.Properties["mail"].Value = email;
    dirEntry.Properties["msDS-UserAccountDisabled"].Value = "FALSE";

    //this doesn't work with both "userAccountControl" and "userFlags"
    dirEntry.Properties["userAccountControl"].Value = (int)(dirEntry.Properties["userAccountControl"].Value ?? 0) | 0x10000;

    dirEntry.CommitChanges();
}

Solution

  • Are you using Active Directory Application Mode (ADAM)? This line makes me think you are:

    dirEntry.Properties["msDS-UserAccountDisabled"].Value = "FALSE";
    

    That attribute doesn't exist in normal Active Directory. So if that's working for you, then you are using ADAM.

    If you are using ADAM, then use the msDS-UserDontExpirePassword attribute to make the password not expire:

    dirEntry.Properties["msDS-UserDontExpirePassword"].Value = true;
    

    If you are not using ADAM, then the "msDS-UserAccountDisabled doesn't exist and you shouldn't be using that. Instead, use userAccountControl to set both.

    Since you just created the account, you don't need to worry about what the value already was, you can just set it to a specific value. Assuming you want it enabled with the "don't expire password" flag, then you can use this:

    //NORMAL_ACCOUNT | DONT_EXPIRE_PASSWORD
    dirEntry.Properties["userAccountControl"].Value = 0x0200 | 0x10000;
    

    You can leave each value separated like that, or just use the resulting decimal value of 66048.