How to determine Active Directory Domain Policies in C# using DirectorySearcher.
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
namespace DotNetDevGuide.DirectoryServices.Chapter10
{
/// <summary>
/// Determining Domain Policies
///
/// This code is meant to run on an Active Directory domain.
/// Where does this leave ADAM instances? By default, ADAM will assume any
/// local or domain policies on the Windows 2003 server where it is running.
/// This means that if our Windows 2003 server is a member of the domain, we
/// can simply use code similar to that in Listing 10.7. If, however, the server
/// is running in a workgroup configuration, the policy will be determined locally.
/// Therefore, this code would not be appropriate. Instead, we would need to know
/// our local policy or attempt to discover it using Windows Management
/// Instrumentation (WMI) classes.
///
/// Source: Addison Wesley - The .NET Developer’s Guide to Directory Services Programming
/// Listing 10.7 in full
/// Released: May 2006, by Publisher(s) Addison-Wesley Professional
/// ISBN: 0321350170
/// </summary>
public class DomainPolicy
{
ResultPropertyCollection _attribs;
public DomainPolicy(DirectoryEntry domainRoot)
{
string[] policyAttributes = new string[]
{
"maxPwdAge", "minPwdAge", "minPwdLength",
"lockoutDuration", "lockOutObservationWindow",
"lockoutThreshold", "pwdProperties",
"pwdHistoryLength", "objectClass",
"distinguishedName"
};
//we take advantage of the marshaling with
//the DirectorySearcher for Large Integer values...
DirectorySearcher ds = new DirectorySearcher(
domainRoot,
"(objectClass=domainDNS)",
policyAttributes,
SearchScope.Base
);
SearchResult result = ds.FindOne();
//do some quick validation...
if (result == null)
{
throw new ArgumentException("domainRoot is not a domainDNS object.");
}
_attribs = result.Properties;
}
//for some odd reason, the intervals are all stored
//as negative numbers. We use this to "invert" them
private long GetAbsValue(object longInt)
{
return Math.Abs((long)longInt);
}
public string DomainDistinguishedName
{
get
{
string val = "distinguishedName";
if (_attribs.Contains(val))
{
return (string)_attribs[val][0];
}
//default return value
return String.Empty;
}
}
public TimeSpan MaxPasswordAge
{
get
{
string val = "maxPwdAge";
if (_attribs.Contains(val))
{
long ticks = GetAbsValue(_attribs[val][0]);
if (ticks > 0)
{
return TimeSpan.FromTicks(ticks);
}
}
return TimeSpan.MaxValue;
}
}
public TimeSpan MinPasswordAge
{
get
{
string val = "minPwdAge";
if (_attribs.Contains(val))
{
long ticks = GetAbsValue(attribs[val][0]);
if (ticks > 0)
{
return TimeSpan.FromTicks(ticks);
}
}
return TimeSpan.MinValue;
}
}
public TimeSpan LockoutDuration
{
get
{
string val = "lockoutDuration";
if (_attribs.Contains(val))
{
long ticks = GetAbsValue(_attribs[val][0]);
if (ticks > 0)
{
return TimeSpan.FromTicks(ticks);
}
}
return TimeSpan.MaxValue;
}
}
public TimeSpan LockoutObservationWindow
{
get
{
string val = "lockoutObservationWindow";
if (_attribs.Contains(val))
{
long ticks = GetAbsValue(_attribs[val][0]);
if (ticks > 0)
{
return TimeSpan.FromTicks(ticks);
}
}
return TimeSpan.MaxValue;
}
}
public int LockoutThreshold
{
get
{
string val = "lockoutThreshold";
if (_attribs.Contains(val))
{
return (int)_attribs[val][0];
}
return 0;
}
}
public int MinPasswordLength
{
get
{
string val = "minPwdLength";
if (_attribs.Contains(val))
{
return (int)_attribs[val][0];
}
return 0;
}
}
public int PasswordHistoryLength
{
get
{
string val = "pwdHistoryLength";
if (_attribs.Contains(val))
{
return (int)_attribs[val][0];
}
return 0;
}
}
public PasswordPolicy PasswordProperties
{
get
{
string val = "pwdProperties";
// this should fail if not found
return (PasswordPolicy)_attribs[val][0];
}
}
}
}