2010-10-25 28 views

Respuesta

1

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

Esto no funcionará en una situación de dominio cruzado (por ejemplo, su máquina no es parte del dominio donde existe el controlador de dominio). Vea mi respuesta para tal solución. –

+0

@Firo: Gracias, corregido. El error fue corregido por 'cadena []' -> 'IEnumerable ' – abatishchev

0

Si usted está buscando para interactuar Active Directory, que no debería tener que saber dónde están los papeles FSMO son en su mayor parte. Si desea cambiar la topología AD de su programa (no lo haría), mire la clase DomainController.

Si desea cambiar una contraseña de usuario, puede invocar esas acciones en el objeto Usuario y Active Directory se asegurará de que los cambios se repliquen correctamente.

copiado de 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

¿Cómo piensas, puedo cambiar mi contraseña actual usando mi propio nombre de usuario y contraseña actual? – abatishchev

2

Estamos utilizando algo como esto para nuestras aplicaciones internas.

debe devolver algo así como 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í, tienes razón. Normalmente tenemos algún código de registro personalizado en la declaración catch, pero lo saqué para este ejemplo. – Lareau

+1

@abatishchev: esa afirmación es incorrecta: al llamar solo 'throw' se ** preservará ** el seguimiento de la pila; crear una nueva excepción o hacer 'throw ex;' rompería la pila de llamadas; ver: http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx –

+0

@marc_s: sí, eres bien, estaba equivocado (en la frase sobre el seguimiento de la pila). de todos modos, esto no tiene sentido hasta el registro, etc. como @Lareau dijo – abatishchev

5

Para recuperar la información cuando el DomainController existe en un dominio en el que su máquina no pertenece, se necesita algo más.

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

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

No quiero pasar el nombre de usuario y la contraseña. – abatishchev

+0

Lamentablemente, si cruza dominios, debe hacerlo. Su identidad existente no se reconocerá de lo contrario. Incluso con el "nuevo" 3.5 espacio de nombres 'System.DirectoryServices.AccountManagement' tendrías que incluir un nombre de usuario/contraseña válido en el dominio * externo *. –

+0

Esto no funciona porque su computadora local no podrá encontrar un DC para ese dominio. – Bluebaron

Cuestiones relacionadas