我正在尝试使用.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命名空间 我可以做些什么来解决这个问题?我绝望了
答案 0 :(得分: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();
}
要完整实施,您可以到这里 - &gt; http://anyrest.wordpress.com/2010/02/01/active-directory-objects-and-c/
答案 1 :(得分: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"
答案 2 :(得分:0)
您是对的,您需要先创建帐户,然后调用SetPassword。您可以尝试使用Invoke SetInfo而不是CommitChanges,然后使用SetPassword。
如果这不起作用,我的猜测是你没有设置必需的属性,如displayName。