Detecting if user needs Reset Password in Active Directory using C #

In Active Directory, if the user account is disabled and then enabled, by default the user must change his password at the first login. Am I struggling to detect this programmatically using C #? Is there a property that is set or something like that if the user needs to reset their property?

Say I have a DirecotryEntry object pointing to a user:

 DirectoryEntry user = ... 

Is there a property that I can use:

 user.Properties[someProperty]; 
+7
source share
4 answers

Got it using the following code:

 public bool PasswordRequiresChanged(string userName) { DirectoryEntry user = GetUser(userName); //A directory entry pointing to the user Int64 pls; int uac; if (user != null && user.Properties["pwdLastSet"] != null && user.Properties["pwdLastSet"].Value != null) { pls = ConvertADSLargeIntegerToInt64(user.Properties["pwdLastSet"].Value); } else { throw new Exception("Could not determine if password needs reset"); } if (user != null && user.Properties["UserAccountControl"] != null && user.Properties["UserAccountControl"].Value != null) { uac = (int)user.Properties["UserAccountControl"].Value; } else { throw new Exception("Could not determine if password needs reset"); } return (pls == 0) && ((uac & 0x00010000) == 0) ? true : false; }
public bool PasswordRequiresChanged(string userName) { DirectoryEntry user = GetUser(userName); //A directory entry pointing to the user Int64 pls; int uac; if (user != null && user.Properties["pwdLastSet"] != null && user.Properties["pwdLastSet"].Value != null) { pls = ConvertADSLargeIntegerToInt64(user.Properties["pwdLastSet"].Value); } else { throw new Exception("Could not determine if password needs reset"); } if (user != null && user.Properties["UserAccountControl"] != null && user.Properties["UserAccountControl"].Value != null) { uac = (int)user.Properties["UserAccountControl"].Value; } else { throw new Exception("Could not determine if password needs reset"); } return (pls == 0) && ((uac & 0x00010000) == 0) ? true : false; } 
 private static Int64 ConvertADSLargeIntegerToInt64(object adsLargeInteger) { var highPart = (Int32)adsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null); var lowPart = (Int32)adsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null); return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart; }
private static Int64 ConvertADSLargeIntegerToInt64(object adsLargeInteger) { var highPart = (Int32)adsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null); var lowPart = (Int32)adsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, adsLargeInteger, null); return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart; } 
+3
source

The condition is stored in two attributes:

  • pwdLastSet: if the value is set to 0 ...
  • userAccountControl: and the UF_DONT_EXPIRE_PASSWD flag is not set.

From here .

+7
source

Here is what I wrote for this. Not quite answering your question, but useful for others who read it later.

Important bits from PrincipalContext on. All that was above is how I tried to always return the name AdName with the exact correct capital letter.

Note that this is just the code making the first answer, the LastPasswordSet test using the user principal instead of DE.

Eric -

  private bool TestAdShouldChangePassword( string adUser ) { try { string adName = ""; MembershipUser mu = Membership.GetUser( adUser ); if ( mu != null ) { IStudentPortalLoginBLL splBll = ObjectFactory.GetInstance< IStudentPortalLoginBLL >(); adName = splBll.GetCleanAdName( adUser );// I wrote this is just pulls outhe name and fixes the caplitalization - EWB PrincipalContext pctx = new PrincipalContext( System.DirectoryServices.AccountManagement.ContextType.Domain ); UserPrincipal p = UserPrincipal.FindByIdentity( pctx, adName ); if ( p == null ) return false; if ( p.LastPasswordSet.HasValue == false && p.PasswordNeverExpires == false ) { return true; } } } catch ( MultipleMatchesException mmex ) { log.Error ( "TestAdShouldChangePassword( ad user = '" + adUser + "' ) - Exception finding user, can't determine if ad says to change password, returing false : Ex = " + mmex.ToString() ); } return false; } 
+6
source
 var username = "radmin"; var adContext = new PrincipalContext(ContextType.Domain, adLocation, adContainer, adAdminUsername, adAdminPassword); var user = UserPrincipal.FindByIdentity(adContext, username); Console.WriteLine(user.LastPasswordSet); 

If LastPasswordSet is null, "the user must change the password at the next login."

+1
source

All Articles