2010-11-26 9 views
12

Ich verwende den System.DirectoryServices.AccountManagement-Teil der .Net-Bibliothek als Schnittstelle zu ActiveDirectory.NETBIOSName von einem UserPrincipal-Objekt abrufen

GetMembers Aufforderung der() auf einem Objekt und Groupprincipal die Ergebnisse filtern, ich habe jetzt eine Sammlung von Objekten Userprincipal

GroupPrincipal myGroup; // population of this object omitted here 

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

Das obige Codebeispiel wird Benutzername auszudrucken wie „TestUser1“. Ich muss diese mit einer Liste vergleichen, die von einer anderen Anwendung im Format "DOMAIN \ TestUser1" kommt.

Wie bekomme ich den "DOMAIN" -Teil vom UserPrincipal-Objekt?

Ich kann nicht einfach einen bekannten Domänennamen anhängen, da mehrere Domänen beteiligt sind und ich DOMAIN1 \ TestUser1 und DOMAIN2 \ TestUser2 unterscheiden muss.

+0

@marc_s Die userPrincipleName enthält den Namen in [email protected] Format - Ich kann nicht sehen, wie man das einfach in DOMAIN \ Benutzerformat umwandelt (besonders da die beteiligten Domänen eine bekannte Liste sind - jede Produktionsumgebung wird eine andere Liste von Domänen als meine Entwicklungsumgebung sein) – Grhm

+0

Sie können auch das 'msDS verwenden "PrincipalName" -Eigenschaft, wie hier beschrieben http://StackOverflow.com/questions/10702188/ –

+2

Oder verwenden Sie 'user.Sid.Translate (typeof (System.Security.Principal.NTAccount)). ToString()', um die Domain \ Benutzername von eac h Gruppenmitglied. Siehe http://StackOverflow.com/questions/6759463 –

Antwort

4

Sie haben zwei Möglichkeiten, die ich mir vorstellen kann.

  1. Parse, oder nehmen Sie alles, was auf der rechten Seite ist [email protected];
  2. Verwenden Sie den Namensbereich System.DirectoryServices.

weiß ich nicht über Userprincipal, ich auch nicht über Groupprincipal. Auf der anderen Seite kenne ich einen funktionierenden Weg, um zu erreichen, was Sie wollen.

[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()) 
} 

Andere verwandte Informationen oder Links in dieser SO Frage.
C# Active Directory: Get domain name of user?
How to find the NetBIOS name of a domain

+0

Sieht gut aus, funktioniert aber nicht. Das Ergebnis.GetDirectoryEntry() hat keine "NETBIOSName" -Eigenschaft - es ist immer Null. (. Außerdem hatte ich Eigenschaften nutzen [ „NetbiosName“] Wert und mein Ergebnis Objekt nicht über eine Dispose() - mit .Net4 wenn das macht einen Unterschied) – Grhm

+0

@Grmh: Ich habe meine Antwort bearbeitet. Bitte schau es dir an und sag mir, ob es funktioniert. Ich habe es in einem NUnit TestCase gekapselt, um das Testen zu erleichtern. –

+0

@Will: Ich habe anscheinend keine "CN = Partitionen, CN = Konfiguration" in meiner Domäne. Meine Domäne ist anscheinend eine untergeordnete Domäne und der Elternteil hat einen Abschnitt CN = Copnfiguration. Ich muss untersuchen .... – Grhm

0

Haben Sie versucht, den vollqualifizierten Domänennamen an diese andere App weiterzugeben? Die meisten Windows-APIs werden sich nicht beschweren, wenn Sie fully_qualified_domain\USER tun.

+0

den anderen App speichern die Benutzername in einer Datenbank Leider und erwartet, dass der Benutzername eindeutig zu sein . Es ist auch mit einer Reihe anderer Apps verbunden, auf die ich keinen Zugriff habe. – Grhm

2

Verwenden Sie die ActiveDs COM-Bibliothek wurde integrierten Namen Übersetzung, das funktioniert und macht keine Annahmen (wie auch andere Antworten hier).

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); 
     } 
    } 
} 
0

Sie könnten die möglichen Domänen in der user.DistinguishedName Eigenschaft suchen. Ein Benutzer in Domäne 1 sollte die Zeichenfolge "DC = DOMAIN1" enthalten. Es sollte definitiv nicht die Zeichenfolge "DC = DOMAIN2" enthalten.

+1

Nicht unbedingt. Ich hatte eine Domäne, die mit DC = dev, DC = Projekt, DC = local es [email protected] oder PROJECTDEV \ User1 Die user.DistinguishedName beendet war nicht enthält DC = PROJECTDEV – Grhm

+0

Ah - thx für die Korrektur. Ich hatte gedacht, dass ein bestimmter Name in gewisser Weise ein kalkuliertes Feld ist - und in meiner Umgebung konsistent ist. –

0

Wie in einer der Kommentare auf die Frage erwähnte ich denke, das ist für den neueren Zeiten eine gute Antwort lautet:

user.Sid.Translate(typeof(System.Security.Principal.NTAccount)).ToString() 
Verwandte Themen