.NetからADSIを用いてActiveDirectoryのユーザ情報を取ってきてるんですが、ユーザの所属するグループの値が入っている MemberOf 属性に Domain Users がいません。
逆に、Domain Users の member にはデフォルトは全ユーザがいないといけないのに、Not Set になってます。
下記は ADSI Edit で Domain Users のオブジェクトを見たときのSSです。
で、Active Directory ユーザーとコンピュータからユーザアカウント情報をよく見ると、Domain Users がプライマリグループになってました。(513がDomain Usersを表してるようです)
調べると、プライマリグループはMemberOfやmemberに含まれない仕様のようです。
[ADSI] プライマリグループを取得する - ComponentGeek Article下記サイトには、このように書いてました。
ユーザのディレクトリオブジェクトにバインドすると、プロパティprimaryGroupIdにプライマリグループのSIDの一部(相対識別ID)が格納されています。プライマリグループのSIDを取得するには、属性objectSidのバイト値の最後4バイトをprimaryGroup属性値で置き換えることで取得します。
厄介な仕様ですね。
参考先のコピペになりますが、下記のように書けばプライマリグループのSIDを取得できます。(C#)
public GetADSI(){
DirectoryEntry mDrctEntry = new DirectoryEntry(@"LDAP://domaincontroller/DC=domainname,DC=jp", "administrator", "password" );
// LDAP検索オブジェクトを作成
DirectorySearcher drSearch = new DirectorySearcher(mDrctEntry);
// アカウントフィルターを設定 Userオブジェクトだけ取得するように
drSearch.Filter = "(ObjectCategory=user)";
// 検索する
SearchResultCollection scn = drSearch.FindAll();
if (scn == null || scn.Count <= 0) {
//なかった時
Utility.DispMessageBox(Utility.StrType.NotFoundUser);
return null;
}
//Userオブジェクト新規生成(Userオブジェクトはユーザアカウント情報を格納するエンティティクラスです)
foreach (SearchResult sResult in scn) {
if (sResult.Properties["primaryGroupId"].Count > 0) {
byte[] sid = CreatePrimaryGroupSID((byte[])sResult.Properties["objectSID"][0], (int)sResult.Properties["primaryGroupId"][0]);
usr.PrimaryGroupSID = SidToString2(sid);
}
}
}
///
/// userのprimaryGroupId属性値はプライマリグループの相対識別値のみ
/// 含まれているので、userのobjectSidのバイト値の最後の4バイトをprimaryGroupId
/// のバイト値で置き換えることで取得する。
///
///
///
public byte[] CreatePrimaryGroupSID(byte[] sid ,int primaryGroup) {
//byte[] sid = user.Properties["objectSid"][0] as byte[];
//int primaryGroup = (int)user.Properties["primaryGroupId"][0];
byte[] primaryGroupBytes = BitConverter.GetBytes(primaryGroup);
for (int i = 0; i < primaryGroupBytes.Length; ++i)
{
sid.SetValue(primaryGroupBytes[i], sid.Length - (primaryGroupBytes.Length - i));
}
return sid;
}
///
/// SID配列を文字列に。
///
///
///
public string SidToString2(byte[] sids){
//ポインタ定義
IntPtr pStringSid = IntPtr.Zero;
//APIを使って変換 第二引数ポインタに結果が入ってる
int ret = ConvertSidToStringSid(sids, ref pStringSid);
//結果となる文字列変数定義
string strSid = string.Empty;
if (ret != 0)
{
//ポインタの先にある文字列をマネージStringに変換。
strSid = Marshal.PtrToStringAnsi(pStringSid);
//メモリ解放
Marshal.FreeCoTaskMem(pStringSid);
}
return strSid;
}