Web Active Directory offers a replacement tool for IISADMPWD.
The IISADMPWD replacement tool allows user to reset their passwords when a password change is requried. Learn More
Changes to IIS 7 authentication have made it so that the IISADMPWD tool no longer works. In fact, any user with the “User must change password at next logon” flag set in Active Directory cannot authenticate to an IIS application configured to use Windows or Basic authentication.
I needed to check the value of the “User must change password at next logon” setting for users in Active Directory programatically while working on a replacement for IISADMPWD. It is a somewhat non-intuitive process to check this value, though, since Active Directory does not have a direct attribute representation of the setting. Instead, AD uses a combination of a userAccountControl attribute flag along with the pwdLastSet attribute to determine if the “User must change password at next logon” value is true or false for a user account. Refer to the AD Pwd-Last-Set attribute documentation for an explanation of how these two values relate.
The C# method here checks the value of the “User must change password at next logon” setting in AD by looking at the pwdLastSet value (represented in the UserPrincipal class as the LastPasswordSet property) and the UF_DONT_EXPIRE_PASSWD flag, represented in the userAccountControl attribute as the 0x10000 bit value.
[sourcecode language=”csharp”] private bool IsChangePasswordAtNextLogonSet(string userName){
var domainContext = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(domainContext, userName);
// Check the state of the LastPasswordSet and userAccountControl attribute.
// Refer to http://msdn.microsoft.com/en-us/library/ms679430%28VS.85%29.aspx: If this value is set
// to 0 and the User-Account-Control attribute *does not* contain the UF_DONT_EXPIRE_PASSWD flag,
// then the user must set the password at the next logon.
if (user.LastPasswordSet != null
&& user.LastPasswordSet == new DateTime(0))
{
// Check the userAccountControl’s UF_DONT_EXPIRE_PASSWD flag using the DirectoryEntry.
DirectoryEntry entry = user.GetUnderlyingObject() as DirectoryEntry;
if (entry != null)
{
if (entry.Properties.Contains("userAccountControl") &&
entry.Properties["userAccountControl"].Count > 0)
{
var userAccountControl = (int)entry.Properties["userAccountControl"][0];
// UF_DONT_EXPIRE_PASSWD hex value is 0x10000. Refer to http://msdn.microsoft.com/en-us/library/aa772300.aspx
// and http://msdn.microsoft.com/en-us/library/ms680832(v=vs.85).aspx for a full list of userAccountControl flags.
return (userAccountControl & 0x10000) == 0;
}
else
{
return true;
}
}
}
return false;
}
[/sourcecode]
Resources
The resources below have good information about the “User must change password at next logon” value in AD.
- Setting userAccountControl and pwdLastSet with the AccountManagement API
- ADS_USER_FLAG_ENUM Enumeration
- User-Account-Control Attribute
- I (think) I want to use a BItWise Operator to check useraccountcontrol property!
Pingback: Web Active Directory Releases Replacement for Microsoft IISADMPWD for Windows IIS7 « Web Active Directory Blog