ドメインのグループのメンバには、ユーザ、グループ、コンピュータ、外部のセキュリティプリンシパルがいます。
メンバは ADSI の IADsGroup.Members メソッドで取得します。このメソッドの戻り値の型は IADsMembers で、IEnumerable を継承してるので For Each で回せます。(ユーザの所属するグループを取得する ADSI の IADsUser.Groups メソッドと同じ)
ユーザやコンピュータのプライマリグループになっていると、そのユーザやコンピュータはメンバに含まれないので、別途取得する必要があります。
また、外部のセキュリティプリンシパルは名前が SID 表記になるので、読み取り可能な名前に変換します。
サンプルアプリではメンバの名前と所属パス(ファイルでいうフォルダパス)を取得します。
Windows アプリは文字列の配列から ListViewItem を作成して ListView に追加してます。
Web アプリは DataRow を作成して DataTable に追加し、GridView にバインドしてます。
まずは IADsGroup.Members メソッドで取得できるメンバの処理はこんな感じです。
※System.Security.Principal 名前空間をインポートします。
対象のグループを group(IADsGroup 型) とすると、
VB
For Each member As IADs In group.Members()
Dim objectType = DirectCast([Enum].Parse(GetType(CategoryType), member.Class, True), CategoryType)
If objectType = CategoryType.ForeignSecurityPrincipal Then '外部のセキュリティプリンシパルの時
Dim objectSid = DirectCast(member.Get("objectSid"), Byte())
Dim sid = New SecurityIdentifier(objectSid, 0) 'SID
Dim account = DirectCast(sid.Translate(GetType(NTAccount)), NTAccount) 'アカウントに変換
文字列の配列の要素 0 または DataRow.Item(0) = account.Value 'NT AUTHORITY\○○ => ToString メソッドでも同じ
Else '外部のセキュリティプリンシパル以外の時
文字列の配列の要素 0 または DataRow.Item(0) = member.Get("cn").ToString()
End If
文字列の配列の要素 1 または DataRow.Item(1) = DirectoryAccess.GetBelongPath(member) '所属パスを取得
ListView に項目を追加 または DataTable に行を追加
Next
C#
foreach (IADs member in group.Members())
{
var objectType = (CategoryType)Enum.Parse(typeof(CategoryType), member.Class, true);
if (objectType == CategoryType.ForeignSecurityPrincipal) //外部のセキュリティプリンシパルの時
{
var objectSid = (byte[])member.Get("objectSid");
var sid = new SecurityIdentifier(objectSid, 0); //SID
var account = (NTAccount)sid.Translate(typeof(NTAccount)); //アカウントに変換
文字列の配列の要素 0 または DataRow[0] = account.Value; //NT AUTHORITY\○○ => ToString メソッドでも同じ
}
else //外部のセキュリティプリンシパル以外の時
{
文字列の配列の要素 0 または DataRow[0] = member.Get("cn").ToString();
}
文字列の配列の要素 1 または DataRow[1] = DirectoryAccess.GetBelongPath(member); //所属パスを取得
ListView に項目を追加 または DataTable に行を追加
}
プライマリグループのメンバはこんな感じで処理します。
DirectoryAccess.GroupTokens プロパティには、DirectoryAccess.GetGroups メソッドでグループの一覧を取得した際に、そのグループの PrimaryGroupToken の値/グループ名 の組のリストが格納されているので、対象のグループの名前から PrimaryGroupToken の値を導出。
この PrimaryGroupToken の値を引数として DirectoryAccess.GetPrimaryGroupMemberEntries メソッドで対象のグループのメンバの DirectoryEntry コレクションを取得。(ユーザまたはコンピュータの属性「primaryGroupID」の値 = PrimaryGroupToken の値)
この DirectoryEntry の Path プロパティの値/SchemaClassName プロパティの値から CategoryType にパースした値の組(メンバのLDAPパスとオブジェクトの種類の組)をコレクション(Dictionary)として作成。
※参照:DirectoryAccessクラスに追加したグループ関連のメソッド(VB、C#)
このコレクションを primaryMembers とすると、
VB
For Each member In primaryMembers 'プライマリグループになっているメンバ数分
文字列の配列の要素 0 または DataRow.Item(0) = DirectoryAccess.PathToCn(member.Key) '名前を取得
文字列の配列の要素 1 または DataRow.Item(1) = DirectoryAccess.GetBelongPath(member.Key) '所属パスを取得
ListView に項目を追加 または DataTable に行を追加
Next
C#
foreach (var member in primaryMembers) //プライマリグループになっているメンバ数分
{
文字列の配列の要素 0 または DataRow[0] = DirectoryAccess.PathToCn(member.Key); //名前を取得
文字列の配列の要素 1 または DataRow[1] = DirectoryAccess.GetBelongPath(member.Key); //所属パスを取得
ListView に項目を追加 または DataTable に行を追加
}
画面はこちらです。(Windows アプリ、Web アプリとも)
それから DirectoryEntry.SchemaClassName = IADs.Class で、DirectoryEntry.Path = IADs.ADsPath です。