クエリーベース配布リストを使い倒す

Microsoft Exchange 2003 Serverを使い込んでいると、いろいろと面白い発見がある。その一つが「クエリーベースの配布グループ」である。
Exchange 2003 ServerをインストールしたWindowsサーバ上でActive Directory管理ツールを起動すると、通常のActive Directory構成のWindowsサーバでは作成できない「クエリーベースの配布グループ」というものを作成できる。
通常はユーザを一人ずつ固定で指定するメーリングリスト(Windows用語では「セキュリティグループ」または「配布グループ」)しか作成できないのだが、Exchange 2003 Serverが導入されているサーバ上のActive Directory管理ツールでは、GUIを使ってユーザを動的に抽出してメンバーにしたメーリングリストが作成できるようになるのだ。
ユーザを抽出する条件としてはユーザのプロパティなら何でも使える。例えばユーザのプロパティの「説明」欄に所属部署を入力しておいて、部署別の同報通知用メーリングリストを「クエリーベースの配布グループ」として作成したりできる。
このようにすると、新入社員はActive Directoryにユーザ登録して、説明欄に所属部署を入力するだけで、自動的に該当の部署のメーリングリストに追加される。ユーザ登録とメーリングリストのメンバーを管理する二度手間がなくなるわけだ。これがクエリーベースの配布リストの便利な点である。
ここまではExchange 2003 Server以降をお使いの方なら誰でもご存知だろうか、ここからが本題である。
Active Directory管理ツールのGUIからクエリーベースの配布リストを作成する場合、抽出条件として複数の条件を指定するとき、AND条件にしかならないという制限がある。
例えば、電子部品事業部の所属で、かつ、東京事業所勤務のユーザという具合に、抽出条件をAND条件として、どんどん絞り込んでいくことはできても、経理部所属のユーザ、または、人事部所属のユーザという具合に、抽出条件をOR条件にして、どんどん人数を増やしていくことができないのだ。
しかし内部的にクエリベースの配布リストがユーザを抽出するときに使っているのは、LDAPフィルタ文字列である。LDAPフィルタ文字列とは、LDAPに対してさまざまなオブジェクトを問い合わせるために使う文字列で、関係データベースでいうSQL文に相当するものだ。
LDAPフィルタの文法は次のようなものだ。「AかつB」は「(&(A)(B))」と表現する。「AかつBかつC」は「(&(A)(B)(C))」となる。「AまたはC」は「(|(A)(B))」となる。「Aかつ(BまたはC)」なら「(&(A)(|(B)(C)))」だ。否定の場合は「!」を使うので、「Aではない」は「(!(A))」と表現される。
Active Directory内からユーザを抽出したいとき、オブジェクトカテゴリは「user」なので、まず「(objectCategory=user)」という条件が必要だ。次に説明欄が「経理部」という条件は「(description=経理部)」となる。文字列の部分一致検索をしたければ「(description=*経理部*)」、前方一致なら「(description=経理部*)」、後方一致なら「(description=*経理部)」でよい。
経理部ユーザと人事部ユーザ全員を抽出したければ「(&(objectCategory=user)(|(description=経理部)(description=人事部)))」となる。じっさいにVBScriptでユーザを抽出したければ下記のようになる。
Set oConn = CreateObject(“ADODB.Connection”)
Set oCommand = CreateObject(“ADODB.Command”)
oConn.Provider = “ADsDSOObject”
oConn.Open “Active Directory Provider”
Set oCommand.ActiveConnection = oConn
oCommand.CommandText = _
“<LDAP://dc=yourcompany,dc=co,dc=jp>;(&(objectCategory=user)(|(description=経理部)(description=人事部)));cn”
Set oRS = objCommand.Execute
後は最後のADODB.Recordsetオブジェクトを最初から最後までループさせてoRs.Fields(“cn”).Valueを読み取れば、抽出結果のユーザの共通名(common name)を列挙できる。ちなみにこの事例は、あなたの会社のActive Directoryドメイン名が「yourcompany.co.jp」と前提している。それが「LDAP://dc=yourcompany,dc=co,dc=jp」という部分である。
そしてここからが今回のハイライトである。なんとGUIではAND条件しか指定できないクエリーベースの配布リストも、その「msExchDynamicDLFilter」という名称のプロパティにLDAPフィルタ文字列を直接書き込んでやると、どんな条件でも自由に設定できてしまうのだ。
まず該当のクエリーベース配布リストのオブジェクトを取得する。そのクエリーベース配布リストが「メーリングリスト」という名称のOU内にあるとしよう。
Set oGroup = GetObject(“LDAP://cn=経理人事メーリングリスト,ou=メーリングリスト,dc=yourcompany,dc=co,dc=jp”)
そして、このオブジェクトのmsExchDynamicDLFilterプロパティに、好きなだけ複雑なLDAPフィルタ文字列を設定し、保存すればよい。
oGroup.Put “msExchDynamicDLFilter”, “(&(objectCategory=user)(|(description=経理部)(description=人事部)))”
oGroup.SetInfo
以上である。このクエリーベース配布リストをActive Directory管理ツールから開くと、既に抽出条件はGUIから変更できなくなっているが、抽出結果のユーザ一覧を見ると、フィルタが正常に機能していることがわかる。
スクリプトでしか抽出条件を変更できない点は不便だが、AND条件、OR条件、NOT条件をいかようにでも複雑に組み合わせられることを考えれば、かなり使える発見だと思う。これを知らないまま、クエリーベース配布リストは実用に耐えないと思っている企業ユーザは、意外に多そうな気がする。