(.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識別名の先頭の"LDAP"は大文字にしとかないといけないようですね。
LDAP識別名のホスト名以降のルールは、マイコミジャーナル:LDAP識別名の記述ルールが参考になります。
指定した条件の ActiveDirectory を見つけるために、DirectorySearcher クラスというLDAP検索フィルタを使ってます。
この DirectorySearcher.Filter プロパティにフィルタを定義するんですが、これは書き方がLDAP書式になるようで複数条件の時がちょっと慣れないんですよね。
そのあたりの書式や使用例はMS:Windows PowerShell から Active Directory を検索する方法はありますか (2009/03) | Hey, Scripting Guy!が非常に参考なります。
後、気になったのが一部取得できない属性があったりするんですよね。
createTimeStamp とか modifyTimeStamp がその一例です。これらはドメインコントローラ間で複製されるようなんですが、(WhenCreated,WhenChanged等は複製されない)なぜか取得できませんでした。他にもいくつかこのような属性がありましたね。。。
参考: