Will man Information aus dem Active Directory in einer eigenen Applikation via System.DirectoryServices abfragen, so erfordert dies für manche Daten eine spezielle Umwandlung, um sie in C# weiter verarbeiten zu können.
Um dies zu erleichtern, folgt nun ein einfaches Beispiel für die Erweiterung von DirectoryEntry via Extension Methods.
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Principal;
using System.DirectoryServices;
namespace ExtensionDemo
{
public static class DirectoryEntryExtensionMethods
{
public static string GetPropertyOfTypeString(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
return directoryEntry.Properties[propertyName].Value.ToString();
}
public static DateTime? GetPropertyOfTypeDateTime(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
return Convert.ToDateTime(directoryEntry.Properties[propertyName].Value);
}
public static long? GetPropertyOfTypeLong(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
return ConvertActiveDirectoryLargeIntToLong(directoryEntry.Properties[propertyName].Value);
}
public static byte[] GetPropertyOfTypeByteArray(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
return ConvertObjectToByteArray(directoryEntry.Properties[propertyName].Value);
}
public static Guid? GetPropertyOfTypeGuid(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
return new Guid(directoryEntry.Properties[propertyName].Value as byte[]);
}
public static SecurityIdentifier GetPropertyOfTypeSecurityIdentifier(this DirectoryEntry directoryEntry, string propertyName)
{
if (directoryEntry.Properties[propertyName].Value == null)
{
return null;
}
byte[] byteSid = directoryEntry.Properties[propertyName].Value as byte[];
return new SecurityIdentifier(byteSid, 0);
}
private static long ConvertActiveDirectoryLargeIntToLong(object activeDirectoryLargeInt)
{
int highPart = (int)activeDirectoryLargeInt.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, activeDirectoryLargeInt, null);
int lowPart = (int)activeDirectoryLargeInt.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, activeDirectoryLargeInt, null);
return (highPart * ((long)uint.MaxValue + 1)) + lowPart;
}
private static byte[] ConvertObjectToByteArray(Object objectToConvert)
{
if (objectToConvert == null) return null;
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream;
using (memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, objectToConvert);
}
return memoryStream.ToArray();
}
}
}
Verwendet können die ExtensionMethods dann z.B. wie in folgendem Code-Ausschnitt gezeigt.
DirectorySearcher dirSearcher = new DirectorySearcher();
dirSearcher.SearchRoot = dirEntry;
dirSearcher.PageSize = 500;
dirSearcher.SearchScope = SearchScope.Subtree;
dirSearcher.Filter = searchFilter;
dirSearcher.PropertiesToLoad.Add("objectGUID");
dirSearcher.PropertiesToLoad.Add("objectSid");
dirSearcher.PropertiesToLoad.Add("dn");
dirSearcher.PropertiesToLoad.Add("cn");
dirSearcher.PropertiesToLoad.Add("displayName");
dirSearcher.PropertiesToLoad.Add("givenName");
dirSearcher.PropertiesToLoad.Add("uSNChanged");
dirSearcher.PropertiesToLoad.Add("whenChanged");
dirSearcher.PropertiesToLoad.Add("thumbnailPhoto");
SearchResultCollection resultCol = dirSearcher.FindAll();
foreach (SearchResult result in resultCol)
{
ResultPropertyCollection propertiesCol = result.Properties;
DirectoryEntry currentDirEntry = result.GetDirectoryEntry();
Console.WriteLine($"cn: {currentDirEntry.GetPropertyOfTypeString("cn")}");
Console.WriteLine($"displayname: {currentDirEntry.GetPropertyOfTypeString("displayname")}");
Console.WriteLine($"distinguishedName: {currentDirEntry.GetPropertyOfTypeString("distinguishedName")}");
Console.WriteLine($"givenname: {currentDirEntry.GetPropertyOfTypeString("givenname")}");
Console.WriteLine($"objectGUID: {currentDirEntry.GetPropertyOfTypeGuid("objectGUID")}");
Console.WriteLine($"objectSid: {currentDirEntry.GetPropertyOfTypeSecurityIdentifier("objectSid")}");
Console.WriteLine($"uSNChanged: {currentDirEntry.GetPropertyOfTypeLong("uSNChanged")}");
Console.WriteLine($"whenChanged: {currentDirEntry.GetPropertyOfTypeDateTime("whenChanged")}");
Console.WriteLine($"whenCreated: {currentDirEntry.GetPropertyOfTypeDateTime("whenCreated")}");
if(currentDirEntry.GetPropertyOfTypeByteArray("thumbnailPhoto") != null) {
Console.WriteLine($"thumbnailPhoto: {BitConverter.ToString(currentDirEntry.GetPropertyOfTypeByteArray("thumbnailPhoto"))}");
}
}
Die Ausgabe für das Beispiel sieht dann so aus.

