2010-10-25 13 views

risposta

1

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

Questo non funziona per una situazione tra domini (ad esempio, la macchina non fa parte del dominio in cui il controller di dominio esiste). Vedi la mia risposta per una soluzione del genere. –

+0

@Firo: Grazie, risolto. L'errore è stato risolto da 'string []' -> 'IEnumerable ' – abatishchev

0

Se siete alla ricerca di interagire Active Directory, non si dovrebbe avere per sapere dove le FSMO ruoli sono per la maggior parte. Se vuoi cambiare la topologia AD dal tuo programma (non lo farei), guarda la classe DomainController.

Se si desidera modificare una password utente, è possibile richiamare tali azioni sull'oggetto Utente e Active Directory farà in modo che le modifiche vengano correttamente replicate.

copiati da 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

come pensi, posso cambiare la mia password attuale usando il mio nome utente e la password corrente? – abatishchev

2

Stiamo utilizzando qualcosa di simile per le nostre applicazioni interne.

deve restituire qualcosa come 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

Sì hai ragione. Normalmente abbiamo un codice di registrazione personalizzato nell'istruzione catch ma l'ho eliminato per questo esempio. – Lareau

+1

@abatishchev: questa affermazione è sbagliata - chiamare solo "throw" ** preserverà ** la traccia dello stack; creare una nuova eccezione o eseguire 'throw ex;' spezzerebbe lo stack di chiamate; vedere: http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx –

+0

@marc_s: sì, sei giusto, ho sbagliato (nella frase sulla traccia dello stack). comunque questo non ha senso fino al logging, ecc. come @Lareau ha detto – abatishchev

5

Per recuperare le informazioni quando il DomainController esiste in un dominio in cui la macchina non appartiene, avete bisogno di qualcosa di più.

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

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

Non voglio passare il nome utente e la password. – abatishchev

+0

Sfortunatamente se stai attraversando domini, è necessario. La tua identità esistente non sarà riconosciuta diversamente. Anche con il "nuovo" spazio dei nomi 3.5 'System.DirectoryServices.AccountManagement' dovresti includere un nome utente/password valido nel dominio * esterno *. –

+0

Questo non funziona perché il tuo computer locale non sarà in grado di trovare un controller di dominio per quel dominio. – Bluebaron

Problemi correlati