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.