7 Stimmen

Aktuellen Domänencontroller programmatisch ermitteln

Ich muss den aktuellen Domänencontroller abfragen, wahrscheinlich den primären, um das Benutzerkennwort zu ändern.

(P)DC name sollte voll qualifiziert sein, d.h. DC=pdc,DC=example,DC=com (wie benennt man eine solche Notation richtig?)

Wie lässt sich das mit C# bewerkstelligen?

6voto

Brett Veenstra Punkte 46226

Um die Informationen abzurufen, wenn die DomainController in einem Bereich existiert, in den Ihr Rechner nicht gehört, brauchen 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 Stimmen

Ich möchte keinen Benutzernamen und kein Passwort angeben.

0 Stimmen

Leider müssen Sie das tun, wenn Sie Domänengrenzen überschreiten. Ihre bestehende Identität wird sonst nicht erkannt. Selbst mit der "neuen" 3.5 System.DirectoryServices.AccountManagement Namespace müssen Sie einen gültigen Benutzernamen/Passwort auf der extern Bereich.

0 Stimmen

Dies funktioniert nicht, da Ihr lokaler Computer nicht in der Lage ist, einen DC für diese Domäne zu finden.

2voto

abatishchev Punkte 94886

(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 Stimmen

Dies funktioniert nicht in einer domänenübergreifenden Situation (z. B. wenn Ihr Rechner nicht Teil der Domäne ist, in der der Domänencontroller existiert). Siehe meine Antwort für eine solche Lösung.

2voto

Lareau Punkte 1962

Wir verwenden etwas Ähnliches für unsere internen Anwendungen.

Sollte etwas zurückgeben 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 Stimmen

Ja, Sie haben Recht. Normalerweise haben wir einige benutzerdefinierte Logging-Code in der catch-Anweisung, aber ich habe es für dieses Beispiel herausgenommen.

1 Stimmen

@abatishchev: diese Aussage ist falsch - ich rufe nur throw wird erhalten der Stack-Trace; Erstellen einer neuen Ausnahme oder throw ex; würde den Aufrufstapel unterbrechen; siehe: weblogs.asp.net/fmarguerie/archive/2008/01/02/

0 Stimmen

@marc_s: ja, du hast recht, ich war falsch (in der Phrase über Stack-Trace). sowieso macht dies keinen Sinn, bis Logging, etc. wie @Lareau sagte

0voto

jwmiller5 Punkte 2564

Wenn Sie mit dem Active Directory interagieren wollen, sollten Sie nicht wissen müssen, wo die FSMO Die Rollen sind zum größten Teil gleich. Wenn Sie die AD-Topologie von Ihrem Programm aus ändern wollen (was ich nicht tun würde), sehen Sie sich die DomainController classe.

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

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

0 Stimmen

Was meinen Sie, kann ich mein aktuelles Passwort mit meinem eigenen Benutzernamen und meinem aktuellen Passwort ändern?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X