ドメインユーザを表す DomainUser クラスのデータバインド用のメソッドから呼び出してる DirectoryAccess クラスのメソッドです。
先にVBのコードを。
※引数チェックは省略します。
'指定した名前と種類の Directory オブジェクトを検索します。
Public Shared Function FindDirectoryObject(name As String, objectCategory AsCategoryType) AsDirectoryObject
Using root = GetRootEntry() 'ルートのDirectoryEntryを取得 参考:ユーザやグループの検索
If CanConnectDomain Then 'ドメインに接続できる時
Dim filter As String
Select Case objectCategory
CaseCategoryType.User
filter = String.Format("(&(objectCategory={0})(sAMAccountName={1}))", objectCategory, name)
CaseCategoryType.PrintQueue
filter = String.Format("(&(objectCategory={0})(printerName={1}))", objectCategory, name)
Case Else
filter = String.Format("(&(objectCategory={0})(name={1}))", objectCategory, name)
End Select
Using searcher As NewDirectorySearcher(root, filter)
Dim result = searcher.FindOne()
Return If(result Is Nothing, Nothing, CreateInstance(result.GetDirectoryEntry()))
End Using
Else 'ドメインに接続できない時 <-- こっちはローカル
Return CreateInstance(root.Children.Find(name, objectCategory.ToString()))
End If
End Using
End Function
'ユーザの所属するグループを取得します。
Public Shared Function GetBelongGroups(user AsIUser) AsReadOnlyCollection(Of String)
Dim groups As NewList(Of String)()
For Each group AsIADsIn user.Native.Groups() '所属するグループ数分(プライマリ グループ以外)
groups.Add(PathToCn(group.Name)) 'PathToCn メソッドは、LDAPパスから名前の部分を切り出します。
Next
If TypeOf user IsDomainUserThen 'ドメインユーザの時
Dim primaryGroupId = DirectCast(user, DomainUser).PrimaryGroupId
groups.Add(GroupTokens.Item(primaryGroupId))
'GroupTokens プロパティ:IDictionary(Of Integer, String) は下のLoadGroupTokens メソッド内で要素がセットされます。
End If
groups.Sort()
Return groups.AsReadOnly()
End Function
'ユーザを取得します。
Public Shared Function GetUsers(Of T As {DirectoryObject, IUser})() AsIList(OfT)
Dim users As NewList(OfT)()
Using root = GetRootEntry() 'ルートのDirectoryEntryを取得
If CanConnectDomain Then 'ドメインに接続できる時
Dim filter = String.Format("(objectCategory={0})", CategoryType.User)
Using searcher As NewDirectorySearcher(root, filter)
Using results = searcher.FindAll()
For Each res AsSearchResultIn results
users.Add(DirectCast(CreateInstance(res.GetDirectoryEntry()), T))
Next
End Using
If GroupTokens.Count = 0Then 'ドメイングループのPrimaryGroupTokenと名前の組のリストがない時
LoadGroupTokens(searcher) 'ドメイングループのPrimaryGroupTokenと名前の組のリストをロード
End If
End Using
Else 'ドメインに接続できない時 <-- こっちはローカル
root.Children.SchemaFilter.Add(CategoryType.User.ToString())
For Each entry AsDirectoryEntryIn root.Children
users.Add(DirectCast(CreateInstance(entry), T))
Next
End If
End Using
Return users
End Function
'DirectoryObject のインスタンスを作成します。
Private Shared Function CreateInstance(entry AsDirectoryEntry) AsDirectoryObject
Dim category AsCategoryType
If[Enum].TryParse(OfCategoryType)(entry.SchemaClassName, True, category) = False Then
Throw NewArgumentException("entry の種類が CategoryType に該当しません。", "entry")
End If
Select Case category
CaseCategoryType.User
If CanConnectDomain Then 'ドメインに接続できる時
Return NewDomainUser(entry)
Else 'ドメインに接続できない時
Return NewLocalUser(entry)
End If
Case Else
Throw NewNotImplementedException()
End Select
End Function
'ドメイングループの PrimaryGroupToken と名前の組のリストをロードします。
Private Shared Sub LoadGroupTokens(searcher AsDirectorySearcher)
searcher.Filter = String.Format("(objectCategory={0})", CategoryType.Group)
Using results = searcher.FindAll()
For Each res AsSearchResultIn results
Dim entry = res.GetDirectoryEntry()
entry.Invoke("GetInfoEx", New Object() {"primaryGroupToken"}, 0)
Dim token = Convert.ToInt32(entry.Properties.Item("primaryGroupToken").Value)
GroupTokens.Add(token, PathToCn(entry.Name))
Next
End Using
End Sub
ユーザの所属するグループの取得に関する説明は別途書きます。