Tipps und Tricks rund um .NET und Visual Studio

Benutzerinformationen auslesen
Kommentare

Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer teilen in der Kolumne „.NETversum“ ihr Expertenwissen rund um .NET-Tools und WPF mit.

Während der .NET-Klassenbibliotheks-Namensraum System.DirectoryServices (aus der System.DirectoryServices.dll) nur sehr allgemeine Klassen zur Behandlung jeglicher Einträge in verschiedenen Verzeichnisdiensten bietet, existiert seit .NET 3.5 der Namensraum System.DirectoryService.AccountManagement mit speziellen Klassen zur Verwaltung von Benutzerkonten (Klasse UserPrincipal), Computerkonten (Klasse ComputerPrincipal) und Gruppen (Klasse GroupPrincipal). Die neuen Klassen (Abb. 1) sind enthalten in der Assembly System.DirectoryServices.AccountManagement.dll. Unterstützt werden hier aber nur das Microsoft Active Directory und lokale Benutzerkonten in Windows-Systemen.

Abb. 1: Klassendiagramm der wichtigsten Klassen aus „System.DirectoryService.AccountManagement“

Das folgende Beispiel zeigt, wie man mit den Klassen aus dem Namensraum System.DirectoryService.AccountManagement Informationen über einen Benutzer aus dem Active Directory ausliest. Die Klasse PrincipalContext dient dazu, einen Verzeichnisbaum auszuwählen. Es gibt drei Arten von Verzeichnisbäumen, die in ContextType unterstützt werden:

  • Domain: Active Directory (AD)
  • ApplicationDirectory: Active Directory Lightweight Directory Services (AD LDS), früher Active Directory Application Mode (ADAM)
  • Machine: Lokale Benutzerkonten in der Windows-Security-Account-Manager-(SAM-)Datenbank

Zunächst erzeugt man ein PrincipalContext-Objekt, im Fall des Active Directory unter Angabe von ContextType.Domain, den Namen eines Domänencontrollers (optional) und – ebenfalls optional, dem LDAP-Pfad des Containers des Benutzers. Das heißt, folgende Instanziierungen sind möglich:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null);

oder

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "DC03", "DC=IT-Visions,DC=de");

Danach folgt der Zugriff auf den gewünschten Benutzer innerhalb des instanziierten Kontexts. Die Klasse UserPrincipal bietet dazu die statische Methode FindByIdentity(), die als Parameter den Kontext, eine Identifikationsart und einen Wert passend zu der Identifikationsart erwartet. Das Programmcodefragment in Listing 1 zeigt fünf verschiedene Optionen zur Benutzeridentifizierung über den Verzeichnisnamen, den NT-kompatiblen Anmeldenamen (SamAccountName), den Distinguished Name (inkl. LDAP-Pfad), den Security Identifier (SID) und die GUID des Benutzerskontos.

string Name = "Holger Schwichtenberg";
UserPrincipal u2 = UserPrincipal.FindByIdentity(ctx, IdentityType.Name, Name);

string SamAccountName = "HolgerSchwichtenberg";
UserPrincipal u1 = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, SamAccountName);

string DN = "CN=Holger Schwichtenberg,OU=Management,DC=IT-Visions,DC=local";
UserPrincipal u3 = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, DN);

string SID = "S-1-5-21-1973890784-140174113-2732654181-1171";
UserPrincipal u4 = UserPrincipal.FindByIdentity(ctx, IdentityType.Sid, SID);

string GUID = "17307548-42e9-4904-84f7-526b1d106e6a";
UserPrincipal u5 = UserPrincipal.FindByIdentity(ctx, IdentityType.Guid, GUID);

Wenn der Benutzer nicht gefunden werden kann, liefert FindbyIdentity() den Wert null, sonst bekommt ein UserPrincipal-Objekt mit vielen Informationen über den Benutzer und sein Anmeldeverhalten.

Console.WriteLine("Namen und Nummern:");
Console.WriteLine(u.Name);
Console.WriteLine(u.SamAccountName);
Console.WriteLine(u.UserPrincipalName);
Console.WriteLine(u.DistinguishedName);
Console.WriteLine(u.DisplayName);
Console.WriteLine(u.EmployeeId);
Console.WriteLine(u.GivenName);
Console.WriteLine(u.Surname);
Console.WriteLine(u.Sid);
Console.WriteLine(u.Guid);

Console.WriteLine("Informationen:");
Console.WriteLine(u.Description);

Console.WriteLine("Adressen:");
Console.WriteLine(u.EmailAddress);
Console.WriteLine(u.VoiceTelephoneNumber);

Console.WriteLine("Konfiguration:");
Console.WriteLine(u.HomeDirectory);
Console.WriteLine(u.HomeDrive);
Console.WriteLine(u.Enabled);

Console.WriteLine("Anmeldungen:");
Console.WriteLine(u.LastLogon);
Console.WriteLine(u.BadLogonCount);
Console.WriteLine(u.LastPasswordSet);
Console.WriteLine(u.PasswordNeverExpires);
Console.WriteLine(u.UserCannotChangePassword);

Auch der Zugriff auf lokale Benutzerkonten in der „SAM“-Datenbank eines Windows-Betriebssystems ist möglich. Solche lokalen Benutzerkonten gibt es auf Clients und auf Servern, die nicht Domain-Controller sind. Bei der Erzeugung des Kontexts ist ContextType.Machine und als zweiter Parameter der Rechnername anzugeben. Die Angabe eines Containers ist nicht erlaubt, da es in der „SAM“-Datenbank keine Ordnerstrukturen gibt: Alle Benutzer sind in einer flachen Liste. Auch bei FindByIdentity() ist zu beachten, dass hier nicht alle Identifikationstypen erlaubt sind, denn eine „SAM“-Datenbank kennt weder einen Distinguished Name noch einen User Principal Name für Einträge. Es funktioniert aber der Kontoname mit Identifikationstypen Name und SamAccountName:

//Stamm für alle weiteren Operationen festlegen auf eine lokale SAM-Datenbank
PrincipalContext ctx = new PrincipalContext(ContextType.Machine, "E60");
 
// Zugriff auf einen bestimmten Benutzer
string IDWert = "hs";
UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "hs");

Console.WriteLine(u.Name);
Console.WriteLine(u.Description);
usw.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -