Pregunta

Estoy utilizando la parte System.DirectoryServices.AccountManagement de la biblioteca .NET para interfaz en ActiveDirectory.

Después de haber emplazado GetMembers () en un objeto GroupPrincipal y filtrar los resultados, ahora tengo una colección de objetos UserPrincipal

GroupPrincipal myGroup;  // population of this object omitted here 

foreach (UserPrincipal user in myGroup.GetMembers(false).OfType<UserPrincipal>())
{
    Console.WriteLine(user.SamAccountName);
}

El ejemplo de código anterior se imprimirá nombres de usuario como "TestUser1". Necesito compararlos con una lista que viene de otra aplicación en formato "dominio \ TestUser1".

¿Cómo consigo la parte "DOMINIO" del objeto UserPrincipal?

No puedo simplemente anexar un nombre de dominio conocido, ya que hay múltiples dominios implicados y que necesitan diferenciarse DOMAIN1 \ TestUser1 y DOMAIN2 \ testuser2.

¿Fue útil?

Solución

Existen dos opciones que se me ocurre.

  1. Analizar, o tomar todo lo que está en el derecho de name@fully.qualified.domain.name;
  2. Uso del espacio de nombres System.DirectoryServices.

No sé acerca de UserPrincipal , ni hacer acerca de GroupPrincipal . Por otra parte, no conozco una forma de trabajo a achive a lo que desea.

[TestCase("LDAP://fully.qualified.domain.name", "TestUser1")] 
public void GetNetBiosName(string ldapUrl, string login)
    string netBiosName = null;
    string foundLogin = null;

    using (DirectoryEntry root = new DirectoryEntry(ldapUrl))
        Using (DirectorySearcher searcher = new DirectorySearcher(root) {
            searcher.SearchScope = SearchScope.Subtree;
            searcher.PropertiesToLoad.Add("sAMAccountName");
            searcher.Filter = string.Format("(&(objectClass=user)(sAMAccountName={0}))", login);

            SearchResult result = null;

            try {
                result = searcher.FindOne();

                if (result == null) 
                    if (string.Equals(login, result.GetDirectoryEntry().Properties("sAMAccountName").Value)) 
                        foundLogin = result.GetDirectoryEntry().Properties("sAMAccountName").Value
            } finally {
                searcher.Dispose();
                root.Dispose();
                if (result != null) result = null;
            }
        }

    if (!string.IsNullOrEmpty(foundLogin)) 
        using (DirectoryEntry root = new DirectoryEntry(ldapUrl.Insert(7, "CN=Partitions,CN=Configuration,DC=").Replace(".", ",DC=")) 
            Using DirectorySearcher searcher = new DirectorySearcher(root)
                searcher.Filter = "nETBIOSName=*";
                searcher.PropertiesToLoad.Add("cn");

                SearchResultCollection results = null;

                try {
                    results = searcher.FindAll();

                    if (results != null && results.Count > 0 && results[0] != null) {
                        ResultPropertyValueCollection values = results[0].Properties("cn");
                        netBiosName = rpvc[0].ToString();
                } finally {
                    searcher.Dispose();
                    root.Dispose();

                    if (results != null) {
                        results.Dispose();
                        results = null;
                    }
                }
            }

    Assert.AreEqual("INTRA\TESTUSER1", string.Concat(netBiosName, "\", foundLogin).ToUpperInvariant())
}

Otra información o enlaces relacionados disponibles en esta pregunta SO.
C # Active Directory:? Obtener nombre de dominio del usuario
Como encontrar el nombre de NetBIOS de un dominio

Otros consejos

El uso de la biblioteca Activeds COM, se ha incorporado en la traducción de nombres que funciona y qué no hacer ninguna suposición (como otras respuestas aquí).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ActiveDs;

namespace Foo.Repository.AdUserProfile
{
    public class ADUserProfileValueTranslate
    {
        public static string ConvertUserPrincipalNameToNetBiosName(string userPrincipleName)
        {
            NameTranslate nameTranslate = new NameTranslate();
            nameTranslate.Set((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_USER_PRINCIPAL_NAME, userPrincipleName);
            return nameTranslate.Get((int) ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_NT4);
        }
    }
}

¿Usted ha intentado pasar el nombre de dominio completo a esta otra aplicación? La mayoría de las ventanas de la API no se quejará si lo hace fully_qualified_domain\USER.

Se podría buscar los posibles dominios en la propiedad user.DistinguishedName. Un usuario en el dominio 1 debe contener la cadena "DC = DOMAIN1". Definitivamente no debe contener la cadena "DC = DOMAIN2".

Como se mencionó en uno de los comentarios a la pregunta creo que esto es una buena respuesta para tiempos más recientes:

 user.Sid.Translate(typeof(System.Security.Principal.NTAccount)).ToString()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top