人気ブログランキング | 話題のタグを見る
(.Net,ADSI)Active Directroyの情報を参照。
Windows標準のActiveDirectoryオブジェクト管理ツールはちょいと使いにくいので .Net でツールを作ることにしました。

.Net 標準のクラスライブラリで Active Directory の操作はできるようです。

DirectoryEntryクラスを使うと Active Directory に接続して任意のオブジェクトを取得できるようです。

とりあえずユーザ情報を取得するサンプルです。(C#)(文字数制限にひっかかったんでハイライト無しで..)
※System.DirectoryServices.dllの参照を追加する必要があります。

using System.DirectoryServices;

///
/// ActiveDirectoryから情報を取得し、Userオブジェクトリストを作成
///

///
public List GetUserAllList()
{
//既定接続の接続するLDAP名 (ドメイン名が hogehoge.jp の場合)
private const string cPath = @"LDAP://domaincontroller/DC=hogehoge,DC=jp";
//既定接続のユーザ名
private const string cUser = @"cn=administrator,DC=hogehoge,DC=jp";
//パスワード
private const string cPasswd = @"password";

//ActiveDirectoryに接続
DirectoryEntry mDrctEntry = new DirectoryEntry(cPath, cUser, cPasswd);
//ログインできた確認
try{
Object obj = mDrctEntry.NativeObject;
} catch (Exception ex){
//ログイン失敗
Utility.DispMessageBox(Utility.StrType.LoginErr);
Console.WriteLine(ex.Message);
return;
}

// LDAP検索オブジェクトを作成
DirectorySearcher drSearch = new DirectorySearcher(mDrctEntry);

// アカウントフィルターを設定 Userオブジェクトだけ取得するように
drSearch.Filter = "(ObjectCategory=user)";
//↓アカウントが hoge のユーザを取得する場合はこのように
//drSearch.Filter = "(SAMAccountName=hoge)";
//↓複数条件の場合(serオブジェクトかつhogeという名前のオブジェクト)
//string loginName = "hoge";
//drSearch.Filter = "(&(ObjectCategory=user)(SAMAccountName=hoge))";

//既定では PropertiesToLoad を指定しないとすべての属性を取得する
//個別に取得する属性を取るには下記のように指定。
// Common Name(cn)プロパティを取得する
//drSearch.PropertiesToLoad.Add("cn");
//sAMAccountName
//drSearch.PropertiesToLoad.Add("sAMAccountName");
//説明
//drSearch.PropertiesToLoad.Add("description");
//所属グループ
//drSearch.PropertiesToLoad.Add("memberOf");

// 指定した条件で検索する
SearchResultCollection scn = drSearch.FindAll();
if (scn == null) return null;

List lstUser = new List();
//Userオブジェクト新規生成
foreach (SearchResult sResult in scn) {
//Userオブジェクト生成
lstUser.Add(SetUserBySearchResult(sResult));
}
return lstUser;
}

//検索結果 SearchResultからオブジェクトの属性取得
private User SetUserBySearchResult(SearchResult sResult)
{
User usr = new User();
if (sResult.Properties["objectGUID"].Count > 0) {
byte[] byt = (byte[])sResult.Properties["objectGUID"][0];
usr.dmObjectGUID = new Guid(byt);
}
if (sResult.Properties["sAMAccountName"].Count > 0) {
usr.dmSamAccountName = (string)sResult.Properties["sAMAccountName"][0];
}
if (sResult.Properties["userPrincipalName"].Count > 0) {
usr.dmUserPrincipalName = (string)sResult.Properties["userPrincipalName"][0];
}
if (sResult.Properties["WhenCreated"].Count > 0) {
//UTCなのでローカル時間に変換。
DateTime dtm = (DateTime)sResult.Properties["WhenCreated"][0];
usr.dmWhenCreated = dtm.ToLocalTime();
}
if (sResult.Properties["WhenChanged"].Count > 0) {
//UTCなのでローカル時間に変換。
DateTime dtm = (DateTime)sResult.Properties["WhenChanged"][0];
usr.dmWhenChanged = dtm.ToLocalTime();
}
if (sResult.Properties["displayName"].Count > 0) {
usr.dmDisplayName = (string)sResult.Properties["displayName"][0];
}
if (sResult.Properties["lastLogon"].Count > 0) {
//1601/01/01からミリ秒をDateTimeに変換
Int64 lastLogonTimestamp = (Int64)sResult.Properties["lastLogon"][0];
DateTime baseDateTime = new DateTime(1601, 01, 01);
usr.dmLastLogon = TimeZoneInfo.ConvertTimeFromUtc(baseDateTime.AddTicks(lastLogonTimestamp), TimeZoneInfo.Local);
}
if (sResult.Properties["distinguishedName"].Count > 0) {
usr.dmDistinguishedName = (string)sResult.Properties["distinguishedName"][0];
}
if (sResult.Properties["memberOf"].Count > 0) {
foreach (object item in sResult.Properties["memberOf"])
{
if (usr.dmMemberOf == null) {
usr.dmMemberOf = new List();
}
usr.dmMemberOf.Add((string)item);
}
}
if (sResult.Properties["sn"].Count > 0) {
usr.dmSn = (string)sResult.Properties["sn"][0];
}
if (sResult.Properties["givenName"].Count > 0) {
usr.dmGivenName = (string)sResult.Properties["givenName"][0];
}
if (sResult.Properties["cn"].Count > 0) {
usr.dmCn = (string)sResult.Properties["cn"][0];
}
if (sResult.Properties["description"].Count > 0) {
usr.dmDescription = (string)sResult.Properties["description"][0];
}
return usr;
}

ActiveDirectoryから取得したユーザアカウント情報は User クラスに値を持たす用にしてます。
Userクラスのコードはこちらを参照。


今回は ActiveDirectory への接続文字列として、LDAPを用いてます。

LDAP://ドメインコントローラ名/DC=ドメイン名(セカンド),DC=ドメイン(トップレベル)


注意点としてLDAP識別名の先頭の"LDAP"は大文字にしとかないといけないようですね。
LDAP識別名のホスト名以降のルールは、マイコミジャーナル:LDAP識別名の記述ルールが参考になります。


指定した条件の ActiveDirectory を見つけるために、DirectorySearcher クラスというLDAP検索フィルタを使ってます。
この DirectorySearcher.Filter プロパティにフィルタを定義するんですが、これは書き方がLDAP書式になるようで複数条件の時がちょっと慣れないんですよね。
そのあたりの書式や使用例はMS:Windows PowerShell から Active Directory を検索する方法はありますか (2009/03) | Hey, Scripting Guy!が非常に参考なります。

後、気になったのが一部取得できない属性があったりするんですよね。
createTimeStamp とか modifyTimeStamp がその一例です。これらはドメインコントローラ間で複製されるようなんですが、(WhenCreated,WhenChanged等は複製されない)なぜか取得できませんでした。他にもいくつかこのような属性がありましたね。。。


参考:
寝ても覚めても.NET(?): ADのユーザ名から所属するグループの一覧を取得する
My Private Adversaria: Windowsのユーザ一覧を取得するには(.Net)
by jehoshaphat | 2010-03-20 06:22 | .Net開発


<< (.Net)SIDを文字列に変換 (.Net,ADSI)Acti... >>