グループに所属する全てのメンバーを取得するサンプルを掲載します。サンプルでは、グループが循環参照している場合は、無限ループを発生しないように対処してあります。
動作環境
- 実行環境:Windows 2003 Server (AD環境)
- 開発環境:Visual Studio 2008 Professional
- .NET 3.5 (.NET 2.0 以上でOK)
1. グループに所属するすべてのメンバーを列挙する
子グループも含めてすべてのグループのメンバーを列挙します。メンバーの取得には属性スコープクエリを使用しています。 GroupExpander.CreateGroupExpander メソッドを呼び出すことで、testGroupグループに属する全てのメンバーを列挙する処理を開始します。
class GroupExpander
{
DirectoryEntry _expandRootGroup;
IList<string> _groupMembers;
IList<string> _processed;
public IList<string> GroupMembers
{
get { return _groupMembers; }
}
public GroupExpander()
{
}
public static void CreateGroupExpander()
{
using (DirectoryEntry group = GetEntry("CN=testGroup,CN=Users,DC=crm1,DC=local"))
{
GroupExpander expander = new GroupExpander();
expander.ExpandGroup(group);
foreach (string member in expander.GroupMembers)
{
Console.WriteLine(member);
}
}
}
public void ExpandGroup(DirectoryEntry expandRootGroup)
{
_expandRootGroup = expandRootGroup;
_groupMembers = new List<string>();
_processed = new List<string>();
_processed.Add(_expandRootGroup.Properties["distinguishedName"].Value as string);
Expand(_expandRootGroup);
}
/// <summary>
/// DirectorySearcher の Attribute Scope Query を使用して、グループを展開する
/// </summary>
/// <param name="group"></param>
private void Expand(DirectoryEntry group)
{
string[] properties = new string[]{"member", "distinguishedName", "objectClass"};
DirectorySearcher ds = new DirectorySearcher(group, "(objectClass=*)", properties, SearchScope.Base);
ds.AttributeScopeQuery = "member";
using (SearchResultCollection searchResultCollection = ds.FindAll())
{
foreach (SearchResult result in searchResultCollection)
{
string dn = (string) result.Properties["distinguishedName"][0];
if (!_processed.Contains(dn))
{
_processed.Add(dn);
if (result.Properties["objectClass"].Contains("group"))
{
Expand(result.GetDirectoryEntry());
}
else
{
_groupMembers.Add(dn);
}
}
}
}
}
public static DirectoryEntry GetEntry(string path)
{
return new DirectoryEntry("LDAP://" + path, null, null, AuthenticationTypes.Secure);
}
}
サンプルでは、ドメインがcrm1.localのコンテナUsersに含まれるtestGroupに所属する全てのメンバーを取得しています。
属性スコープクエリは.NET2.0以降で使用できます。.NET 1.1 の場合は、グループに属するグループを検索して、複数階層のメンバーを列挙する必要があります。
説明は以上です。 誤り、指摘点等がありましたらご連絡ください。