我需要查询当前域控制器,可能主要更改用户密码。以编程方式确定当前域控制器
(P),DC名称应该是完全合格的,即DC=pdc,DC=example,DC=com
(如何正确名称,符号?)
如何可以在使用C#来完成?
我需要查询当前域控制器,可能主要更改用户密码。以编程方式确定当前域控制器
(P),DC名称应该是完全合格的,即DC=pdc,DC=example,DC=com
(如何正确名称,符号?)
如何可以在使用C#来完成?
(需要System.DirectoryServices.AccountManagement.dll):
using (var context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain))
{
string server = context.ConnectedServer; // "pdc.examle.com"
string[] splitted = server.Split('.'); // { "pdc", "example", "com" }
IEnumerable<string> formatted = splitted.Select(s => String.Format("DC={0}", s));// { "DC=pdc", "DC=example", "DC=com" }
string joined = String.Join(",", formatted); // "DC=pdc,DC=example,DC=com"
// or just in one string
string pdc = String.Join(",", context.ConnectedServer.Split('.').Select(s => String.Format("DC={0}", s)));
}
如果您正在寻找交互的Active Directory,您不应该知道在哪里FSMO角色大部分。如果你想从程序中更改AD拓扑(我不会),请看DomainController类。
如果要更改用户密码,可以在用户对象上调用这些操作,并且Active Directory将确保更改已正确复制。
从http://www.rootsilver.com/2007/08/how-to-change-a-user-password
public static void ChangePassword(string userName, string oldPassword, string newPassword)
{
string path = "LDAP://CN=" + userName + ",CN=Users,DC=demo,DC=domain,DC=com";
//Instantiate a new DirectoryEntry using an administrator uid/pwd
//In real life, you'd store the admin uid/pwd elsewhere
DirectoryEntry directoryEntry = new DirectoryEntry(path, "administrator", "password");
try
{
directoryEntry.Invoke("ChangePassword", new object[]{oldPassword, newPassword});
}
catch (Exception ex) //TODO: catch a specific exception ! :)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("success");
}
修复的。您如何看待我可以使用我自己的用户名和当前密码更改当前密码? – abatishchev 2010-11-05 10:33:02
复制我们使用这样的事情对我们的内部应用程序。
应该返回类似DC=d,DC=r,DC=ABC,DC=com
public static string RetrieveRootDseDefaultNamingContext()
{
String RootDsePath = "LDAP://RootDSE";
const string DefaultNamingContextPropertyName = "defaultNamingContext";
DirectoryEntry rootDse = new DirectoryEntry(RootDsePath)
{
AuthenticationType = AuthenticationTypes.Secure;
};
object propertyValue = rootDse.Properties[DefaultNamingContextPropertyName].Value;
return propertyValue != null ? propertyValue.ToString() : null;
}
是的,你是对的。我们通常在catch语句中有一些自定义日志记录代码,但是我为此示例拿出了它。 – Lareau 2010-10-26 14:31:20
@abatishchev:该语句是错误的 - 只调用'throw'将**保存**堆栈跟踪;创建一个新的异常或者执行'throw ex;'会破坏调用堆栈;见:http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx – 2010-11-05 10:16:44
@marc_s:是啊,你对,我错了(在关于堆栈跟踪的短语中)。无论如何这是没有意义的,直到日志等@Lareau说 – abatishchev 2010-11-05 10:24:31
检索信息时存在域中的DomainController
在你的机器不属于,你需要更多的东西。
DirectoryContext domainContext = new DirectoryContext(DirectoryContextType.Domain, "targetDomainName", "validUserInDomain", "validUserPassword");
var domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(domainContext);
var controller = domain.FindDomainController();
我不想传递用户名和密码。 – abatishchev 2012-11-13 19:43:15
不幸的是,如果你跨域,你需要。否则您的现有身份将不会被识别。即使使用“新”3.5“System.DirectoryServices.AccountManagement”命名空间,您也必须在* external *域中包含有效的用户名/密码。 – 2012-11-14 20:21:15
这不起作用,因为您的本地计算机将无法找到该域的DC。 – Bluebaron 2016-01-29 23:26:28
这不适用于跨域情况(例如,您的计算机不是域控制器所在的域的一部分)。看到我的答案这样的解决方案。 – 2012-11-13 14:44:26
@Firo:谢谢,修正。错误是通过'string []' - >'IEnumerable' –
abatishchev
2012-11-30 07:34:26