Active Directoryのグループから1,500件を超えるメンバーを取得する方法(はもう考えなくていい)


Active Directoryにおいて属性値が1,500件を超えている場合、すべての値を一度に取得することができません(でした)。この場合の属性値の取得方法について解説します。

この記事ではldapsearchコマンドで検証しています。また、そこまで値が増える属性はmemberくらいしか無いと思いますので、member属性に絞って書いています。

TL;DR

最近のWindows Serverではこのような考慮が不要で、どんなに属性値が多くても一度に取得できるようです。やったね!

1,500件以上だと返却される属性名がmemberではなくなる

まず、普通にldapsearchコマンドでグループのメンバを取得してみます。

1
2
3
4
5
$ ldapsearch -h dc.example.com -D user000000@example.com -w p@ssw0rd -x -b "dc=example,dc=com" "(cn=group1)" member
dn: cn=group1,ou=groups,dc=example,dc=com
member: cn=user000000,ou=users,dc=example,dc=com
member: cn=user000001,ou=users,dc=example,dc=com
member: cn=user000002,ou=users,dc=example,dc=com

3件のグループメンバを取得することができました。

しかし、該当のグループのメンバが1,500件を超えていると、以下のように返却されます。

1
2
3
4
5
6
7
$ ldapsearch -h dc.example.com -D user000000@example.com -w p@ssw0rd -x -b "dc=example,dc=com" "(cn=group1)" member
dn: cn=group1,ou=groups,dc=example,dc=com
member;range=0-1499: cn=user000000,ou=users,dc=example,dc=com
member;range=0-1499: cn=user000001,ou=users,dc=example,dc=com
member;range=0-1499: cn=user000002,ou=users,dc=example,dc=com
.................
member;range=0-1499: cn=user001499,ou=users,dc=example,dc=com

返却される属性名がmemberからmember;range=0-1499に変わっています。Active Directoryでは属性値を一度に1,500件までしか取得することができないため、範囲を絞って取得されたことを属性名を使って示しているのです。

属性名自体が変わっているので、Javaなどのプログラムで属性値を取得する場合は注意が必要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SearchResult sr = (SearchResult)results.next();
Attributes attrs = si.getAttributes();
if (attrs != null) {

  // メンバ情報を取得できない
  Attribute attr1 = attrs.get("member");

  // メンバ情報を取得できる
  Attribute attr2 = attrs.get("member;range=0-1499");

}

さらに、1,501件目以降のメンバを取得を取得してみます。

リクエストする属性名をmember;range=1500-*またはmember;range=1500-2999とすると、1,501件目以降の値を取得できます。TOにあたる部分を*を指定することは、最大件数、つまりこの場合だと2999を指定するのと同じ意味になります。

1
2
3
4
5
6
7
$ ldapsearch -h dc.example.com -D user000000@example.com -w p@ssw0rd -x -b "dc=example,dc=com" "(cn=group1)" "member;range=1500-*"
dn: cn=group1,ou=groups,dc=example,dc=com
member;range=1500-2999: cn=user001500,ou=users,dc=example,dc=com
member;range=1500-2999: cn=user001501,ou=users,dc=example,dc=com
member;range=1500-2999: cn=user001502,ou=users,dc=example,dc=com
.................
member;range=1500-2999: cn=user002999,ou=users,dc=example,dc=com

member;range=1500-*として投げたのに、返却された属性名がmember;range=1500-2999でした。属性名の範囲のTOにあたる部分が具体的な数字で返却される場合は、取得した範囲以降にまだ値が残っていることを表しています。

次に3001件目以降を取得します。リクエストする属性名をmember;range=3000-4499として検索してみます。

1
2
3
4
5
6
7
$ ldapsearch -h dc.example.com -D user000000@example.com -w p@ssw0rd -x -b "dc=example,dc=com" "(cn=group1)" "member;range=3000-4499"
dn: cn=group1,ou=groups,dc=example,dc=com
member;range=3000-*: cn=user003000,ou=users,dc=example,dc=com
member;range=3000-*: cn=user003001,ou=users,dc=example,dc=com
member;range=3000-*: cn=user003002,ou=users,dc=example,dc=com
.................
member;range=3000-*: cn=user003999,ou=users,dc=example,dc=com

range=3000-*という属性名で1000件分が返却されました。指定した範囲内に収まる件数の場合には、属性名のTOにあたる部分が*となっていると、それ以上属性値がないことを示しています。つまりこのグループには4000件のメンバが登録されていたことになります。

じゃあキッチリ3001件目から4000件目までを指定して取得したらどうなるでしょう?

1
2
3
4
5
6
7
$ ldapsearch -h dc.example.com -D user000000@example.com -w p@ssw0rd -x -b "dc=example,dc=com" "(cn=group1)" "member;range=3000-3999"
dn: cn=group1,ou=groups,dc=example,dc=com
member;range=3000-*: cn=user003000,ou=users,dc=example,dc=com
member;range=3000-*: cn=user003001,ou=users,dc=example,dc=com
member;range=3000-*: cn=user003002,ou=users,dc=example,dc=com
.................
member;range=3000-*: cn=user003999,ou=users,dc=example,dc=com

やっぱりmember;range=1500-*:として返却されます。それ以上値が残っていないためです。

Windows 2000 Serverの場合は1000件まで

上記はWindows Server 2003の場合の話です。(もうそんなサーバは残っていないと思いますが)Windows 2000 Serverの場合は一度に取得できる属性値の件数が1,500件ではなく1,000件となります。取得方法は同じです。

Windows Server 2008以降

Windows Server 2008以降は、上記のような上限がなくなったように見受けられます。少なくとも6,000件を超える属性値を一度に取得できました。残念ながら文献を見つけることはできませんでした。ご存知の方がいらっしゃいましたら教えていただけますと幸いです。