Obtenez NETBIOSNAME d'un objet UserPrincipal
-
28-09-2019 - |
Question
J'utilise la partie System.DirectoryServices.AccountManagement de la bibliothèque .Net à l'interface en ActiveDirectory.
Après avoir appelé GetMembers () sur un objet GroupPrincipal et filtrer les résultats, j'ai maintenant une collection d'objets UserPrincipal
GroupPrincipal myGroup; // population of this object omitted here
foreach (UserPrincipal user in myGroup.GetMembers(false).OfType<UserPrincipal>())
{
Console.WriteLine(user.SamAccountName);
}
L'exemple de code ci-dessus imprimera les noms d'utilisateur comme « TestUser1 ». Je dois comparer à une liste provenant d'une autre application dans le format « DOMAIN \ TestUser1 ».
Comment puis-je obtenir la partie "DOMAIN" de l'objet UserPrincipal?
Je ne peux pas simplement append un nom de domaine connu sous le nom il y a plusieurs domaines impliqués et je dois différencier DOMAIN1 \ TestUser1 et DOMAIN2 \ TestUser2.
La solution
Vous avez deux choix que je peux penser.
- Parse, ou prendre tout ce qui est sur, le droit de
name@fully.qualified.domain.name
; - Utilisez l'espace de noms
System.DirectoryServices
.
Je ne sais pas UserPrincipal , moi non plus sur les GroupPrincipal . D'autre part, je connais un moyen de travailler à achive ce que vous voulez.
[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())
}
Autres informations connexes ou des liens disponibles dans cette question SO.
C # Active Directory: Obtenir le nom de domaine utilisateur
Comment trouver le nom NetBIOS d'un domaine
Autres conseils
Utilisez la bibliothèque ActiveDs COM, il a intégré la traduction du nom que les travaux et ne fait pas d'hypothèses (comme d'autres réponses ici).
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);
}
}
}
Avez-vous essayé passer le nom de domaine complet à cette autre application? La plupart des fenêtres de l'API ne se plaindra pas si vous le faites fully_qualified_domain\USER
.
Vous pourriez rechercher les domaines possibles dans la propriété user.DistinguishedName. Un utilisateur dans le domaine 1 doit contenir la chaîne « DC = DOMAIN1 ». Il ne doit certainement pas contenir la chaîne "DC = DOMAIN2".
Comme mentionné dans l'un des commentaires à la question que je pense que c'est une bonne réponse pour des périodes plus récentes:
user.Sid.Translate(typeof(System.Security.Principal.NTAccount)).ToString()