2010-10-25 27 views

Antwort

1

(erfordert 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))); 
} 
+0

Dies funktioniert nicht für eine domänenübergreifende Situation (z. B. ist Ihr Computer nicht Teil der Domäne, in der der Domänencontroller vorhanden ist). Siehe meine Antwort für eine solche Lösung. –

+0

@Firo: Danke, behoben. Fehler wurde behoben durch 'string []' -> 'IEnumerable ' – abatishchev

0

Wenn Sie das Active Directory kommunizieren suchen, sollten Sie nicht wissen, wo die FSMO Rollen zum größten Teil sind. Wenn Sie die AD-Topologie von Ihrem Programm ändern möchten (würde ich nicht), sehen Sie sich die Klasse DomainController an.

Wenn Sie ein Benutzerkennwort ändern möchten, können Sie diese Aktionen für das Benutzerobjekt aufrufen, und Active Directory stellt sicher, dass die Änderungen korrekt repliziert werden.

von 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"); 
} 
kopiert
+0

Wie denkst du, kann ich mein aktuelles Passwort mit meinem eigenen Benutzernamen und aktuellen Passwort ändern? – abatishchev

2

Wir so etwas für unsere internen Anwendungen verwenden.

Sollte so etwas wie 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; 
} 
+0

Ja, du hast Recht. Normalerweise haben wir einen benutzerdefinierten Protokollierungscode in der catch-Anweisung, aber ich habe es für dieses Beispiel herausgenommen. – Lareau

+1

@abatishchev: Diese Aussage ist falsch - das Aufrufen von 'throw' wird ** den Stack-Trace beibehalten **; eine neue Exception zu erstellen oder 'ex exch; zu machen' würde den Call-Stack unterbrechen; siehe: http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx –

+0

@marc_s: ja, du bist Richtig, ich habe mich geirrt (im Sinne von Stack-Trace). Wie auch immer, das macht keinen Sinn, bis Logging, usw. @Lareau sagte – abatishchev

5

geben die Informationen abzurufen, wenn der DomainController, in dem in einer Domäne existiert Ihre Maschine gehört nicht, müssen Sie etwas mehr.

DirectoryContext domainContext = new DirectoryContext(DirectoryContextType.Domain, "targetDomainName", "validUserInDomain", "validUserPassword"); 

    var domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(domainContext); 
    var controller = domain.FindDomainController(); 
+0

Ich möchte nicht den Benutzernamen und das Passwort übergeben. – abatishchev

+0

Wenn Sie Domains kreuzen, müssen Sie das leider tun. Ihre bestehende Identität wird sonst nicht erkannt. Selbst mit dem "neuen" 3.5 'System.DirectoryServices.AccountManagement'-Namespace müssten Sie einen gültigen Benutzernamen/Passwort für die * externe * Domain angeben. –

+0

Dies funktioniert nicht, da Ihr lokaler Computer keinen Domänencontroller für diese Domäne finden kann. – Bluebaron