我一直在寻找一段时间如何设置/更改密码并撤销/恢复用户但尚未找到真正适合我的解决方案。
我开始倾向于这样一个事实:即使我可以通过编程方式创建/删除/更新甚至连接/断开用户与组之间的问题。
基本上,我尝试过以下方法:
DirectoryEntry account = new DirectoryEntry("LDAP://" + adHostname + "/" + dn, adUserName, adPassword);
account.Invoke("SetPassword", "Password1");
account.Properties["LockOutTime"].Value = 0;
account.CommitChanges();
还
account.Invoke("SetPassword", new object[] { "Password1" });
它们最终都会抛出错误“一个或多个输入参数无效\ r \ n”
然后我尝试使用主要上下文的.NET 3.5方法。
using (var context = new PrincipalContext(ContextType.Domain, adHostname, myContainer, ContextOptions.SimpleBind, adUserName, adPassword))
{
using (var user = UserPrincipal.FindByIdentity(context, account.Properties["sAMAccountName"].Value.ToString()))
{
user.SetPassword(password);
}
}
这种方法也抛出了与上面相同的错误。如果我切换一些东西(我似乎无法记住我尝试的所有组合),它有时会抛出“发生本地错误”COM异常。
非常感谢任何帮助。
答案 0 :(得分:0)
看到这篇文章: https://www.codeproject.com/Articles/18102/Howto-Almost-Everything-In-Active-Directory-via-C#7
您将在所有示例中注意到我们直接绑定到directoryEntry并且未指定服务器或凭据。如果您不想使用模拟类,则可以将凭据直接发送到DirectoryEntry构造函数中。当您想要使用静态方法并且不想经历创建DirectoryContext对象以保存这些详细信息的麻烦时,模拟类很有用。同样,您可能希望定位特定的域控制器。
目标特定域控制器或凭证
您看到的代码中的所有位置:LDAP://您可以使用LDAP替换:// MyDomainControllerNameOrIpAddress以及您看到正在构建的DirectoryEntry类的任何位置,您也可以发送特定凭据。如果您需要处理您的计算机不是其林或域的成员的Active Directory,或者您希望将DC作为目标进行更改,则此功能尤其有用。
//重命名对象并直接指定域控制器和凭据
public static void Rename(string server,
string userName, string password, string objectDn, string newName)
{
DirectoryEntry child = new DirectoryEntry("LDAP://" + server + "/" +
objectDn, userName, password);
child.Rename("CN=" + newName);
}
答案 1 :(得分:0)
"新的DirectoryEntry"不绑定用户帐户。需要搜索用户以设置密码。像这样:
DirectoryEntry account = new DirectoryEntry("LDAP://" + adHostname + "/" + dn, null, null, AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.Signing);
DirectorySearcher search = new DirectorySearcher(account);
search.Filter = "(&(objectClass=user)(sAMAccountName=" + adUserName + "))";
account = search.FindOne().GetDirectoryEntry();
account.Invoke("SetPassword", "Password1");
account.Properties["LockOutTime"].Value = 0;
account.CommitChanges();
答案 2 :(得分:0)
这个一直对我有用。希望能帮助到你。
首先添加对System.DirectoryServices.AccountManagement
string hostName = "myDomain";
string adminName = "admin";
string adminPassword = "password";
public static void ResetPassword(string username, string password)
{
using (PrincipalContext pContext = new PrincipalContext(ContextType.Domain, hostName, adminName, adminPassword))
{
UserPrincipal up = UserPrincipal.FindByIdentity(pContext, username);
if (up != null)
{
up.SetPassword(password);
up.Save();
}
}
}
您还可以对UserPrincipal执行各种操作,例如锁定帐户,过期密码,获取上次登录等。
答案 3 :(得分:-1)
下午好! 我已经读过几次您的问题,但我绝对不理解您问题的实质...
如果您需要更改密码,请先阅读以下材料: https://docs.microsoft.com/en-us/windows/win32/api/iads/nf-iads-iadsuser-setpassword https://docs.microsoft.com/ru-ru/office/client-developer/outlook/mapi/hresult 请记住,更改密码时,您的帐户(将代表您尝试更改密码)必须在Active Directory域中具有足够的管理权限才能更改密码!特别重要的是要注意,新密码必须符合您的域策略设置的要求!
string distinguishedName = $"LDAP://CN=SuperUser,DC=company,DC=local";
if (!DirectoryEntry.Exists(distinguishedName))
return;
DirectoryEntry deEntry = new DirectoryEntry(distinguishedName);
try
{
deEntry.Invoke("SetPassword", "MyNew@#123Pass12091");
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.Read();
编辑-在评论后添加
太懒惰以至于无法帮助那些不满意的用户,此外,还单击了弊端……为您特别在测试台上放置一个AD域和一个未连接到该域的客户端以进行干净检查!
static void Main(string[] args)
{
Console.WriteLine($"Client - {Environment.UserDomainName}\\{Environment.MachineName}");
try
{
DirectoryEntry dirEntrForeignDomain = new DirectoryEntry();
dirEntrForeignDomain.AuthenticationType = AuthenticationTypes.ServerBind;
dirEntrForeignDomain.Path = $"LDAP://172.28.145.73/DC=kul,DC=local";
dirEntrForeignDomain.Username = $"Администратор@kul.local";
dirEntrForeignDomain.Password = $"Qwerty123";
SetPasswordUser(dirEntrForeignDomain); // but it is better to use OFFICIAL - AuthenticablePrincipal.SetPassword(String)
ResetPasswordUser(dirEntrForeignDomain);
UnResetPasswordUser(dirEntrForeignDomain);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.Read();
}
static public void SetPasswordUser(DirectoryEntry de)
{
using (DirectorySearcher dirSearchUser = new DirectorySearcher(de))
{
dirSearchUser.Filter = "(&(objectClass=user)(sAMAccountName=test))";
SearchResult searchResUser = dirSearchUser.FindOne();
if (searchResUser != null)
{
DirectoryEntry dirEntryFoundUser = searchResUser.GetDirectoryEntry();
dirEntryFoundUser.Invoke("SetPassword", new object[] { "Qwerty!!!" });
dirEntryFoundUser.CommitChanges();
Console.WriteLine("Set password is - Qwerty!!!");
}
}
}
static public void ResetPasswordUser(DirectoryEntry de)
{
using (DirectorySearcher dirSearchUser = new DirectorySearcher(de))
{
dirSearchUser.Filter = "(&(objectClass=user)(sAMAccountName=test))";
SearchResult searchResUser = dirSearchUser.FindOne();
if (searchResUser != null)
{
DirectoryEntry dirEntryFoundUser = searchResUser.GetDirectoryEntry();
dirEntryFoundUser.Properties["pwdLastSet"].Value = 0;
dirEntryFoundUser.CommitChanges();
Console.WriteLine("ResetPasswordUser!");
}
}
}
static public void UnResetPasswordUser(DirectoryEntry de)
{
using (DirectorySearcher dirSearchUser = new DirectorySearcher(de))
{
dirSearchUser.Filter = "(&(objectClass=user)(sAMAccountName=test))";
SearchResult searchResUser = dirSearchUser.FindOne();
if (searchResUser != null)
{
DirectoryEntry dirEntryFoundUser = searchResUser.GetDirectoryEntry();
dirEntryFoundUser.Properties["pwdLastSet"].Value = -1;
dirEntryFoundUser.CommitChanges();
Console.WriteLine("UnResetPasswordUser ...");
}
}
}
日志
客户端-DESKTOP-KUL \ DESKTOP-KUL
设置密码为-Qwerty !!!
ResetPasswordUser!
UnResetPasswordUser ...
很奇怪,您通过“ UserPrincipal”失败了“ SetPassword” ...