Created
February 24, 2013 20:49
-
-
Save cabrel/5025568 to your computer and use it in GitHub Desktop.
Retrieving objects from Active Directory (Originally posted on 09/14/2010)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Retrieves all objects from the given DN and returns their given properties | |
/// | |
/// If we are told to search recursively then if we find any OU's we iterate through those | |
/// as well | |
/// </summary> | |
/// <param name="DN"></param> | |
/// <param name="properties"></param> | |
/// <param name="useRecursion"></param> | |
/// <returns></returns> | |
public static List<string> GetAllObjects(string DN, List<string> properties, bool useRecursion) | |
{ | |
var results = new List<string>(); | |
// Certain values from the AD search are | |
// date/time values. Because of their format | |
// we need to convert them into something that | |
// we can understand. | |
// | |
// The following is a short list I use to | |
// convert any of those dates. | |
// | |
// Any dates not listed here will not be converted | |
var dates = new List<string>() | |
{ | |
"pwdLastSet", | |
"badPasswordCountTime", | |
"lastLogoff", | |
"lastLogon", | |
"lastLogonTimestamp", | |
"lockoutTime" | |
}; | |
try | |
{ | |
DirectoryEntry de = new DirectoryEntry("LDAP://" + DN); | |
foreach (DirectoryEntry child in de.Children) | |
{ | |
// If we require recursion, this is the place to do it | |
// | |
// We need to remove the LDAP:// header though because | |
// we will re-add it automatically | |
if (child.Properties.Contains("ou")) | |
{ | |
if (useRecursion) results.AddRange(GetAllObjects(child.Path.Remove(0, 7), properties, useRecursion)); | |
} | |
else | |
{ | |
var propertySb = new StringBuilder(); | |
var lcounter = 0; | |
// Since we accept property inputs we need to make sure those | |
// are what we capture from the search. | |
// | |
// In our case we don't return the entire property list if the properties are | |
// empty. If no properties are specified then no results will be returned | |
foreach (var property in properties) | |
{ | |
var val = ""; | |
if (child.Properties.Contains(property)) | |
{ | |
if(dates.Contains(property)) | |
{ | |
var t = child.Properties[property].Value; | |
var ticks = GetInt64(child, property); | |
var dateFormattedValue = DateTime.FromFileTime(ticks); | |
val = dateFormattedValue.ToString(); | |
} | |
else | |
{ | |
val = child.Properties[property].Value.ToString(); | |
} | |
if (val != property) | |
{ | |
if (lcounter + 1 == properties.Count) | |
{ | |
propertySb.Append(val); | |
} | |
else | |
{ | |
propertySb.Append(val + ","); | |
} | |
} | |
} | |
lcounter++; | |
} | |
results.Add(propertySb.ToString()); | |
} | |
child.Close(); | |
child.Dispose(); | |
} | |
de.Close(); de.Dispose(); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex.ToString()); | |
} | |
return results; | |
} | |
/// <summary> | |
/// Given a directory entry and the property we are looking at | |
/// we can convert the illegible timestamp into a format | |
/// that can be parsed by the DateTime class. | |
/// </summary> | |
/// <param name="entry"></param> | |
/// <param name="attr"></param> | |
/// <returns></returns> | |
private static Int64 GetInt64(DirectoryEntry entry, string attr) | |
{ | |
DirectorySearcher ds = new DirectorySearcher( | |
entry, | |
String.Format("({0}=*)", attr), | |
new string[] { attr }, | |
SearchScope.Base | |
); | |
SearchResult sr = ds.FindOne(); | |
if (sr != null) | |
{ | |
if (sr.Properties.Contains(attr)) | |
{ | |
return (Int64)sr.Properties[attr][0]; | |
} | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment