System.DirectoryServices を使用して、ユーザのプライマリグループしてみます。

確認環境

  • 動作環境:Windows 2003 Server (AD環境)
  • 開発環境:Visual Studio 2008 Professional
  • .NET 3.5

1. プライマリグループを取得する

ユーザのディレクトリオブジェクトにバインドすると、プロパティprimaryGroupIdにプライマリグループのSIDの一部(相対識別ID)が格納されています。プライマリグループのSIDを取得するには、属性objectSidのバイト値の最後4バイトをprimaryGroup属性値で置き換えることで取得します。

crmuser03というユーザのプライマリグループを取得するサンプルを掲載します。

public static void ShowPrimaryGroup()
{
    using (DirectoryEntry user = GetEntry("CN=crmuser03,OU=CrmUsers,DC=crm1,DC=local"))
    {
        byte[] primaryGroup = CreatePrimaryGroupSID(user);
        string path = string.Format("<SID={0}>", ToSidString(primaryGroup));
        using (DirectoryEntry group = GetEntry(path))
        {
            Console.WriteLine(group.Properties["distinguishedName"].Value);
        }
    }
}
/// <summary>
/// userのprimaryGroupId属性値はプライマリグループの相対識別値のみ
/// 含まれているので、userのobjectSidのバイト値の最後の4バイトをprimaryGroupId
/// のバイト値で置き換えることで取得する。
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static byte[] CreatePrimaryGroupSID(DirectoryEntry user)
{
    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;
}
public static DirectoryEntry GetEntry(string path)
{
    return new DirectoryEntry("LDAP://" + path, null, null, AuthenticationTypes.Secure);
}
private static string ToSidString(byte[] bytes)
{
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < bytes.Length; ++i)
    {
        builder.AppendFormat(bytes[i].ToString("X2"));
    }
    return builder.ToString();
}

実行するとAD環境では通常Domain Users がプライマリグループとして取得されます。

説明は以上です。誤りなどがあればご連絡ください。