【问题标题】:How to programmatically change Active Directory password如何以编程方式更改 Active Directory 密码
【发布时间】:2020-01-31 16:05:28
【问题描述】:

我有一组要创建的测试帐户,但这些帐户将被设置为在第一次登录时需要更改密码。我想用 C# 编写一个程序来检查测试帐户并更改密码。

【问题讨论】:

    标签: c# active-directory directoryservices


    【解决方案1】:

    只要找到正确的 UserPrincipal 对象,您就可以使用UserPrincipal 类的SetPassword 方法,前提是您有足够的权限。使用FindByIdentity 查找有问题的主体对象。

    using (var context = new PrincipalContext( ContextType.Domain ))
    {
      using (var user = UserPrincipal.FindByIdentity( context, IdentityType.SamAccountName, userName ))
      {
          user.SetPassword( "newpassword" );
          // or
          user.ChangePassword( "oldPassword", "newpassword" );
    
          user.Save();
      }
    }
    

    【讨论】:

    • 这仅在 .NET 3.5 及更高版本中可用,顺便说一句(PrincipalContext 和所有)。
    • 之后记得user.Save()
    • 很好的解决方案。如何使用上述解决方案切换“用户下次登录时必须更改密码”?
    【解决方案2】:
    public void ResetPassword(string userName, string Password, string newPassword)
    {
        try
        {
            DirectoryEntry directoryEntry = new DirectoryEntry(Path, userName, Password);
    
            if (directoryEntry != null)
            {
                DirectorySearcher searchEntry = new DirectorySearcher(directoryEntry);
                searchEntry.Filter = "(samaccountname=" + userName + ")";
                SearchResult result = searchEntry.FindOne();
                if (result != null)
                {
                    DirectoryEntry userEntry = result.GetDirectoryEntry();
                    if (userEntry != null)
                    {
                        userEntry.Invoke("SetPassword", new object[] { newPassword });
                        userEntry.Properties["lockouttime"].Value = 0;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Log.Error("Password Can't Change:" + ex.InnerException.Message);
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是一个很棒的 Active Directory 编程快速参考:

      Howto: (Almost) Everything In Active Directory via C#

      查看接近尾声的密码重置代码。

      public void ResetPassword(string userDn, string password)
      {
          DirectoryEntry uEntry = new DirectoryEntry(userDn);
          uEntry.Invoke("SetPassword", new object[] { password });
          uEntry.Properties["LockOutTime"].Value = 0; //unlock account
      
          uEntry.Close();
      }
      

      【讨论】:

      • 问题是关于更改密码,而不是设置密码。两种不同的东西。用户是否知道当前密码?
      • 这太棒了!我可以在没有旧密码的情况下更改密码。谢谢达娜霍尔特!
      • 当您在 AD 中设置密码时,您还可以选择强制用户在使用临时密码时更改它。如何使用上面的代码实现它?谢谢
      【解决方案4】:

      可以使用 .NET Framework 2.0 为域帐户设置新密码。 请参阅下面的工作代码:

      string domainfqdn="mydomain.test.gov" //fqdn of the domain
      string ldapPath =GetObjectDistinguishedName (objectClass.user,returnType.distinguishedName, args[0].ToString(),domainfqdn);
      ldapPath="LDAP://" + domainfqdn + :389/"+ldapPath;
      
      DirectoryEntry uEntry = new DirectoryEntry(ldapPath,null,null,AuthenticationTypes.Secure);
      uEntry.CommitChanges();
      Console.WriteLine(ldapPath);
      string password="myS3cr3tPass"              
      uEntry.Invoke("SetPassword", new object[] { password });
      uEntry.Properties["LockOutTime"].Value = 0; //unlock account                
      uEntry.CommitChanges();
      uEntry.Close();             
      

      检查uEntry的参数很重要,代码会在当前线程安全上下文下运行,除非指定了空值

      【讨论】:

        【解决方案5】:

        试试这个代码。它对我有用,

        public void ChangeMyPassword(string domainName, string userName, string currentPassword, string newPassword)
        {
            try
            {
                string ldapPath = "LDAP://192.168.1.xx";
                DirectoryEntry directionEntry = new DirectoryEntry(ldapPath, domainName + "\\" + userName, currentPassword);
                if (directionEntry != null)
        
                {
                    DirectorySearcher search = new DirectorySearcher(directionEntry);
                    search.Filter = "(SAMAccountName=" + userName + ")";
                    SearchResult result = search.FindOne();
                    if (result != null)
                    {
                        DirectoryEntry userEntry = result.GetDirectoryEntry();
                        if (userEntry != null)
                        {
                            userEntry.Invoke("ChangePassword", new object[] { currentPassword, newPassword });
                            userEntry.CommitChanges();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        

        【讨论】:

        • 这是从网络应用程序更改密码的最佳方法。它不会在服务器上创建用户文件夹,而是更改密码而不是管理员重置。此处列出了有益的原因。 stackoverflow.com/questions/17493571/…
        • 为什么要捕获异常只是为了再次抛出它?如果必须,为什么不直接“投掷”?以便异常不会丢失原始堆栈跟踪?
        【解决方案6】:

        解决方法如下:

        string newPassword = Membership.GeneratePassword(12, 4);    
        string quotePwd = String.Format(@"""{0}""", newPassword);    
        byte[] pwdBin = System.Text.Encoding.Unicode.GetBytes(quotePwd);    
        UserEntry.Properties["unicodePwd"].Value = pwdBin;    
        UserEntry.CommitChanges();
        

        【讨论】:

        • 在我的情况下,我收到消息:“服务器不愿意处理请求”。
        • 需要using System.Web.Security;,但对我有用。
        猜你喜欢
        • 2012-12-09
        • 1970-01-01
        • 2011-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-26
        • 1970-01-01
        相关资源
        最近更新 更多