Active Directory上のユーザーが所属するグループを取得しようとしてmemberOf属性を参照しても、実際に所属するグループの内1つのグループ(大抵はDomain Users)が取得できません。
例えば次のようなWSHのコードを書いてもグループが1つ抜けてしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
Set conn = CreateObject("ADODB.Connection") With conn .Provider = "ADsDSOObject" .Open "Active Directory Provider" End With dn = "<LDAP://dc=example,dc=local>" filters = "(&(objectCategory=user)(objectClass=person))" attr = "name,memberOf" query = dn & ";" & filters & ";" & attr & ";subtree" Set cmd = CreateObject("ADODB.Command") With cmd .ActiveConnection = conn .CommandText = query End With Set result = cmd.Execute Do Until result.EOF WScript.Echo result.Fields("name") If Not IsNull(result.Fields("memberOf").value) Then For Each group In result.Fields("memberOf").value WScript.Echo group Next End If result.MoveNext Loop |
どうもmemberOf属性にはプライマリグループは記載されないという仕様のようです。プライマリグループというのはユーザーに対し1つ必ず指定しなければならないグループで、初期状態だとDomain Usersがプライマリグループとなります。
なのでプライマリグループについては別途自前で取得する必要があります。
例えば以下の様にattrにprimaryGroupIdを追加してプライマリグループのIDを取得しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
Set conn = CreateObject("ADODB.Connection") With conn .Provider = "ADsDSOObject" .Open "Active Directory Provider" End With dn = "<LDAP://dc=example,dc=local>" filters = "(&(objectCategory=user)(objectClass=person))" attr = "name,memberOf,primaryGroupId" query = dn & ";" & filters & ";" & attr & ";subtree" Set cmd = CreateObject("ADODB.Command") With cmd .ActiveConnection = conn .CommandText = query End With Set result = cmd.Execute Do Until result.EOF WScript.Echo result.Fields("name") If Not IsNull(result.Fields("memberOf").value) Then For Each group In result.Fields("memberOf").value WScript.Echo group Next End If result.MoveNext Loop |
そして別途以下の様にfiltersとattrを指定したクエリを実行し、グループとそのIDを取得してユーザーのprimaryGroupIdとグループのprimaryGroupTokenとを突き合わせることでプライマリーグループを取得してあげる必要があります。
filters = "(objectCategory=group)"
attr = "name,primaryGroupToken"
正直とてもめんどくさい仕様だなと思います。