Obtener NetbiosName de un objeto UserPrincipal
-
28-09-2019 - |
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.
Solución
Existen dos opciones que se me ocurre.
- Analizar, o tomar todo lo que está en el derecho de
name@fully.qualified.domain.name
; - 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()