前回の続きで、SID/アカウント名のコレクションを作成する CreateSidNameDictionary メソッドです。
このメソッドは SID(文字列)のコレクションを受け取って SID/アカウント名のコレクションを返します。
公開しないメソッドなので引数や戻り値の型に List<T> や Dictionary<TKey, TValue> を使ってます。
アカウント名を取得するために検索を行います。処理手順はユーザやグループの検索と基本的には同じです。
検索は SID をキーにするので、検索対象の属性は objectSid になります。
検索フィルタ(DirectorySearcher.Filter プロパティ)は (objectSid=SID) を指定します。
※参考:Active Directory 内のオブジェクトの検索指定
SID はオブジェクトに対して一意なので、検索の実行は DirectorySearcher.FindOne メソッドを使います。
戻り値は SearchResult オブジェクトになります。
検索値である SID は元々アクセス権の設定対象(ユーザやグループなど)のアクセス制御エントリ(ACE)から取得してるので、検索すれば必ず見つかると思ってました。
実際に検索を実行してみると SYSTEM、SELF、Everyone などの特殊なアカウントは見つからず Nothing/null が返されました。管理ツール「Active Directory ユーザとコンピュータ」で管理できないアカウントは見つからないってことかなぁ。
見つかった場合はお決まりの処理で、SearchResult.GetDirectoryEntry メソッドで DirectoryEntry を取得してます。
そしてオブジェクトの種類(スキーマ クラス:DirectoryEntry.SchemaClassName プロパティ)が 外部のセキュリティプリンシパル(foreignSecurityPrincipal)の時は SID をアカウントに変換して そこからアカウント名部分を取得してます。見つからなかった時も同様です。
CategoryType はライブラリ側に定義した列挙体で、サンプルアプリで扱う Directory オブジェクトの種類を表してて、DirectoryEntry.SchemaClassName(ADSI は IADs.Class)プロパティの値を列挙体の値に変換できるように定義してます。
外部のセキュリティプリンシパル以外の時は cn 属性の値がアカウント名(ログオン名ではなく表示名)なので この値を使ってます。
この辺はグループのメンバの取得と表示でやってることと同じです。
この時は SecurityIdentifier クラスのインスタンス化は SID のバイト配列とオフセットを引数にとるコンストラクタを使ってますが、今回は SID の文字列を引数にとるコンストラクタを使ってます。
列挙体のプロパティ値をテキスト化する ToEnumValueText メソッド(変更)はまた別途書きます。