2010-10-25 17 views

Odpowiedz

1

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

Nie będzie działać w przypadku sytuacji międzydomenowej (np. Twój komputer nie jest częścią domeny, w której istnieje kontroler domeny). Zobacz moją odpowiedź na takie rozwiązanie. –

+0

@Firo: Dzięki, naprawione. Błąd został naprawiony przez 'string []' -> 'IEnumerable ' – abatishchev

0

Jeśli szukasz do interakcji z usługą Active Directory, nie powinno się wiedzieć, gdzie FSMO role są w przeważającej części. Jeśli chcesz zmienić topologię AD ze swojego programu (nie chciałbym), spójrz na klasę DomainController.

Jeśli chcesz zmienić hasło użytkownika, możesz wywołać te działania w obiekcie użytkownika, a usługa Active Directory upewni się, że zmiany zostały prawidłowo zreplikowane.

skopiowane z 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

Jak myślisz, w jaki sposób mogę zmienić moje obecne hasło używając mojej nazwy użytkownika i aktualnego hasła? – abatishchev

2

Używamy coś takiego dla naszych wewnętrznych zastosowań.

powinien powrócić coś jak 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

Tak, masz rację. Zazwyczaj w oświadczeniu catch znajduje się niestandardowy kod logowania, ale w tym przykładzie zostałem usunięty. – Lareau

+1

@abatishchev: to stwierdzenie jest błędne - wywołanie samego 'throw' spowoduje ** zachowanie ** śledzenia stosu; tworzenie nowego wyjątku lub wykonanie 'throw ex;' spowoduje przerwanie stosu wywołań; zobacz: http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx –

+0

@marc_s: yea, you're tak, myliłem się (w wyrażeniu na temat śledzenia stosu). w każdym razie to nie ma sensu, aż do logowania, itp., jak @Lareau powiedział – abatishchev

5

Aby pobrać informacje kiedy DomainController istnieje w domenie, w której urządzenie nie należeć, trzeba czegoś więcej.

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

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

Nie chcę przekazywać nazwy użytkownika i hasła. – abatishchev

+0

Niestety, jeśli przechodzisz przez domeny, musisz. Twoja istniejąca tożsamość nie zostanie uznana inaczej. Nawet w "nowej" przestrzeni nazw 3.5 'System.DirectoryServices.AccountManagement' musisz podać prawidłową nazwę użytkownika/hasło w * zewnętrznej * domenie. –

+0

To nie działa, ponieważ lokalny komputer nie będzie w stanie znaleźć DC dla tej domeny. – Bluebaron