2012-04-17 123 views
0

嗨,我尝试重置的Active Directory用户的密码,但我得到的错误,以下是我的代码:错误的密码更改的Active Directory用户

public string ChangePassword(string Identity,string OldPassword, string Password) 
{ 
     string success = "Success"; 
     try 
     { 


      DirectoryEntry UserEntry = null; 
      DirectoryEntry entry = new DirectoryEntry("LDAP://.../DC=Domain,DC=COM", Identity, OldPassword); 

      DirectorySearcher search = new DirectorySearcher(entry); 
      SearchResult resultsearch = search.FindOne(); 
      if (resultsearch == null) 
      { 
       success = "User Not Found In This Domain"; 
      } 
      else 
      { 

       success = "find"; 
       UserEntry = resultsearch.GetDirectoryEntry(); 
       UserEntry.Username = @"Domain\Administrator"; 
       UserEntry.Password = "password"; 
       UserEntry.AuthenticationType = AuthenticationTypes.None; 

       if (UserEntry == null) 
        success = "User Not Found In This Domain"; 
       else 
       { 
        try 
        { 
         success = UserEntry.Username.ToString(); 


    UserEntry.Invoke("ChangePassword", new object[] { OldPassword, Password }); 
         UserEntry.CommitChanges(); 

        } 
        catch (Exception ex) 
        { 
         success = ex.ToString(); 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      success = ex.ToString(); 
     } 

UserEntry.Invoke所以我得到错误(“ChangePassword”,新对象[] {OldPassword,Password}); UserEntry.CommitChanges();

错误:

 System.Runtime.InteropServices.COMException (0x80020006): Unknown name.   (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME)) 
     at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args) 
     at WebService.ChangePassword(String Identity, String OldPassword, String Password) in c:\inetpub\wwwroot\WebSite1\App_Code\WebService.cs:line 370 
+0

@迈克尔·托德是的,我只是改变名称,但其正确的域和我有管理员权限。 – Hiren 2012-04-17 22:21:59

+0

是否有你没有使用新的'System.DirectoryServices.AccountManagement' API的原因?它是'UserPrincipal'类_has_ ['ChangePassword'](http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.authenticableprincipal.changepassword.aspx)方法,工作得很好。 – 2012-04-17 22:26:24

+0

是的,我可以理解,它看起来像API不包括changepassword方法,@ M.Babcock - 我使用system.DirectoryServices.dll,我应该使用任何其他的DLL文件? – Hiren 2012-04-17 22:31:58

回答

1

如果您使用的是.NET Framework 3.5或更高版本,则下面的代码将解决该问题。类定义被省略。

using System.DirectoryServices.AccountManagement; 

public static string ChangePassword(string adminUser, string adminPassword, 
    string domain, string container, string userName, string newPassword) 
{ 
    try 
    { 
     PrincipalContext principalContext = 
      new PrincipalContext(ContextType.Domain, domain, container, 
       adminUser, adminPassword); 
     UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, userName); 
     if (user == null) return "User Not Found In This Domain"; 

     user.SetPassword(newPassword); 
     return user.Name; 
    } 
    catch (Exception ex) 
    { 
     return ex.Message; 
    } 
} 

用法:

ChangePassword(@"DOMAIN\Administrator", "password", "DOMAIN", 
    "DC=Domain,DC=COM", userName, newPassword); 

编辑:增加了一个版本的.NET 2.0框架。

更改密码方法.NET 2.0:

public static string ChangePassword20(string adminUser, string adminPassword, 
    string container, string domainController, string userName, string newPassword) 
{ 
    const AuthenticationTypes authenticationTypes = AuthenticationTypes.Secure | 
     AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind; 

    DirectoryEntry searchRoot = null; 
    DirectorySearcher searcher = null; 
    DirectoryEntry userEntry = null; 

    try 
    { 
     searchRoot = new DirectoryEntry(String.Format("LDAP://{0}/{1}", 
      domainController, container), 
      adminUser, adminPassword, authenticationTypes); 

     searcher = new DirectorySearcher(searchRoot); 
     searcher.Filter = String.Format("sAMAccountName={0}", userName); 
     searcher.SearchScope = SearchScope.Subtree; 
     searcher.CacheResults = false; 

     SearchResult searchResult = searcher.FindOne(); ; 
     if (searchResult == null) return "User Not Found In This Domain"; 

     userEntry = searchResult.GetDirectoryEntry(); 

     userEntry.Invoke("SetPassword", new object[] { newPassword }); 
     userEntry.CommitChanges(); 

     return "New password set"; 
    } 
    catch (Exception ex) 
    { 
     return ex.ToString(); 
    } 
    finally 
    { 
     if (userEntry != null) userEntry.Dispose(); 
     if (searcher != null) searcher.Dispose(); 
     if (searchRoot != null) searchRoot.Dispose(); 
    } 
} 

用法:

ChangePassword20(@"DOMAIN\Administrator", "password", "DC=Domain,DC=COM", 
    "domainControllerName", "userName", "newPassword"); 
+0

谢谢埃斯彭,我现在可以重置我的密码,但我需要在.net 4.0中运行我的应用程序,我想在framework 2.0中运行它,因为需求,你能告诉我为什么我不能使用directotyentry.invoke()吗? – Hiren 2012-04-18 17:22:51

+0

如果您拥有管理员权限,则设置密码的正确方法是使用Invoke(“SetPassword”)。更改密码方法要求旧密码是已知的。诀窍是使用正确的凭证和AuthenticationTypes初始化searchRoot目录条目。 – 2012-04-18 21:27:27

0

几件事情:

  • 你不应该在UserEntry可以设置一个用户名,密码或AuthN类型。
  • 您的成功= UserEntry.Username...应该是obj foo = UserEntry.NativeObject;。如果通过,你有一个有效的DE。
  • 这里不需要拨打CommitChanges()
  • 您可以在用户的​​上下文中调用ChangePassword,而不是管理员。这将正确地通过GetDirectoryEntry()呼叫。
+0

我尝试以上所有仍然没有得到它。 – Hiren 2012-04-17 23:08:23

相关问题