2

我正在尝试使用 .NET System.DirectoryServices 命名空间在我的开发活动目录服务器上创建一个新用户。

我尝试使用以下代码:

DirectoryEntry dirEntry = new DirectoryEntry(path, "TESTDOM\\Administrator", "2109password", AuthenticationTypes.Secure | AuthenticationTypes.ServerBind);

object o = dirEntry.NativeObject;
DirectoryEntry newUser = dirEntry.Children.Add("CN=NewUser4", "user");
newUser.Properties["samAccountName"].Value = "NewUser4";
newUser.Properties["Description"].Add("User Description");

newUser.Invoke("SetPassword",  new object[] {"2109password"} );
newUser.CommitChanges();

我也尝试过使用

newUser.CommitChanges();

在我调用 Invoke 设置密码之前。我总是得到一个 TargetInvocationException 包装:

InnerException {"The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)"} System.Exception {System.Runtime.InteropServices.COMException}

异常总是只在我调用时抛出

newUser.Invoke("SetPassword",  new object[] {"2109password"} );

如果在尝试使用 SetPassword 调用 Invoke 之前调用 newUser.CommitChanges(),则会在域上创建新用户。然后我可以手动转到 AD 机器并毫无问题地设置相同的密码(因此密码字符串违反规则不是问题)。我注意到网上有很多关于此的帖子,但没有找到解决方案。

我认为这可能与运行代码的机器不是域中的成员有关。尽管用户 TESTDOM\Administrator 是 TESTDOM 域上的管理员、域管理员、模式管理员和企业管理员组的成员。

请注意,当我使用 .NET 2 时,我不能使用 System.DirectoryServices.AccountManagement 命名空间关于如何解决这个问题的任何想法?生无可恋

4

3 回答 3

1

我想您需要先创建用户,然后再为其设置属性,我通常这样做

/// <summary>
/// This Method will Create a new User Directory Object based on a Username and LDAP Domain
/// </summary>
/// <param name="sUserName">The Username of the New User</param>
/// <param name="sLDAPDomain">The LDAP Domain for the New User</param>
/// <returns></returns>
public DirectoryEntry CreateNewUser(string sUserName, string sLDAPDomain)
{
    //Set the LDAP qualification so that the user will be Created under the Users Container
    string LDAPDomain = "/CN=Users," + sLDAPDomain;
    oDE = new DirectoryEntry("LDAP://" + sADServer + "/" + sLDAPDomain, sADUser, sADPassword, AuthenticationTypes.Secure);

    oDEC = oDE.Children.Add("CN=" + sUserName, "user");
    oDE.Close();
    return oDEC;
}

然后设置我需要的任何属性

/// <summary>
/// This will Set the Property of the Directory Entry Object
/// </summary>
/// <param name="oDE">The Directory Object to Set to</param>
/// <param name="sPropertyName">The Property Name</param>
/// <param name="sPropertyValue">The Property Value</param>
public void SetProperty(DirectoryEntry oDE, string sPropertyName, string sPropertyValue)
{
    //Check if the Value is Valid
    if (sPropertyValue != string.Empty)
    {
        //Check if the Property Exists
        if (oDE.Properties.Contains(sPropertyName))
        {
            oDE.Properties[sPropertyName].Value = sPropertyValue;
            oDE.CommitChanges();
            oDE.Close();
        }
        else
        {
            oDE.Properties[sPropertyName].Add(sPropertyValue);
            oDE.CommitChanges();
            oDE.Close();
        }
    }
}

然后设置密码

/// <summary>
/// This Method will set the Users Password based on Directory Entry Object
/// </summary>
/// <param name="oDE">The Directory Entry to Set the New Password</param>
/// <param name="sPassword">The New Password</param>
/// <param name="sMessage">Any Messages catched by the Exception</param>
public void SetUserPassword(DirectoryEntry oDE, string sPassword, out string sMessage)
{
    try
    {
        //Set The new Password
        oDE.Invoke("SetPassword", new Object[] { sPassword });
        sMessage = "";

        oDE.CommitChanges();
        oDE.Close();
    }
    catch (Exception ex)
    {
        sMessage = ex.InnerException.Message;
    }

}

最后启用帐户

/// <summary>
/// This Method will Enable a User Account Based on the Directory Entry Object
/// </summary>
/// <param name="oDE">The Directoy Entry Object of the Account to Enable</param>
public void EnableUserAccount(DirectoryEntry oDE)
{
    oDE.Properties["userAccountControl"][0] = ADMethods.ADAccountOptions.UF_NORMAL_ACCOUNT;
    oDE.CommitChanges();
    oDE.Close();
}

对于完整的实现,你可以去这里-> http://anyrest.wordpress.com/2010/02/01/active-directory-objects-and-c/

于 2010-11-02T22:28:14.513 回答
1

好的,我得到了它的工作:

 dirEntry = new DirectoryEntry(ldapPath, domainAdminUser, domainAdminPassword);
    dirEntry.Invoke("SetPassword", new object[] { newPassword });
    dirEntry.Properties["LockOutTime"].Value = 0; //unlock account

ldapPath 应该包含我们尝试更改的用户的完整 DN,所以它应该看起来像:

string ldapPath = "LDAP://ad.domain.com:389/CN=username,OU=Users,DC=ad,DC=domain,DC=com"
于 2010-12-21T16:10:41.153 回答
0

您是对的,您需要先创建帐户,然后调用 SetPassword。您可以尝试使用 Invoke SetInfo 而不是 CommitChanges,然后使用 SetPassword。

如果这不起作用,我的猜测是您没有设置必需的属性,例如 displayName。

于 2010-10-17T19:48:46.833 回答