Hey, Scripting Guy!わずか 5 セントで OU に関する質問に回答する

Microsoft Scripting Guys

この記事で使用しているコードのダウンロード: HeyScriptingGuy2007_03.exe (151KB)

質問 - Active Directory から OU を選択するダイアログ ボックスを表示する方法はありますか。

ご存じでしょうが、この質問を受けるたびに Scripting Guys が 5 セントずつ受け取っていたとしたら、ええと、そうですね、実際には $37.15 にしかならないですね。しかし、時間がなくてまだ質問していないが、この質問をしたいと思っているすべてのユーザーから 5 セントずつ受け取ったとしたら、ええと、まあ、金額なんてどうでもいいです。なぜなら、私たちはお金のために Scripting Guys になったわけではありませんから。Scripting Guys になったのは、ユーザーがシステム管理タスクをより速く、より簡単に実行できるようになるという満足感のためです。

注: 厳密に言えば、収入を得るために Scripting Guys になりました。でも上司が言いました。「君たちが業績を上げてかなりの収入を得ることは可能だが、それは一生懸命働いて高品質のものだけを生産しようという強い意志があって初めて可能になる。」この言葉を聞いたときから、お金がすべてではないと思うようになりました。

それはどうでもいいことです。問題は、OU を選択し、その延長線上で、スクリプトを使用してその OU に接続できるようなダイアログ ボックスを表示する方法を多くのユーザーが知りたいと思っていることです。最近、次のような電子メールを受け取りました。「以前に、フォルダを選択するダイアログ ボックスを表示する方法を説明していただきました。また、ファイルを選択するダイアログ ボックスについても記事が掲載されています。しかし、Active Directory® から OU を選択するダイアログ ボックスの表示方法に関する記事がないのはなぜですか。」

はい、たしかに、フォルダを選択するダイアログ ボックスを表示する方法について説明しました。この例については、こちら を参照してください。また、ファイルを選択するダイアログ ボックスの表示方法については、https://www.microsoft.com/japan/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx にアクセスしてご確認ください。これらの記事は非常に好評で、このテクニックがユーザーのスクリプトで利用されていることを知っています。Active Directory から OU を選択できるようなダイアログ ボックスの表示方法に関する記事がないのはなぜでしょうか。これはマイクロソフトの陰謀か何かでしょうか。

もちろんそうではありません (ちょっと待ってください。陰謀にかかわっている人は必ずこう言いますよね)。実のところ、Active Directory から OU を選択するダイアログ ボックスの表示方法を説明していないことには、正当な理由があります。それは、そのようなダイアログ ボックスが存在しないからです。野球では、「見えないものは打てない」とよく言います。同様に、スクリプトでは、「存在しないものは表示できない」と言います。

さて、今月のコラムはこれで終わりです。またお会いしましょう。

そうは問屋が卸しません。TechNet Magazine の編集者によると、これで終わりではないそうです。**編集者は次のように言いました。「そのようなダイアログ ボックスが存在しないと、何か問題でもあるのですか。あなたたちは Scripting Guys でしょうが。何とかして ダイアログ ボックスを作成できないのですか。スクリプトに関しては何でもできると思っていたのに。」

言うまでもありませんが、TechNet Magazine の編集者は大きな思い違いをしています。**スクリプトに関しては何でもできる? 必ずしもそうではありません。実際、スクリプトに関して Scripting Guys にできることは 1 つだけです。

幸い、私たちにできることは、唯一、Active Directory から OU を選択するダイアログ ボックスを作成することです。図 1 をご覧ください。

はい、どちらかと言えば長いスクリプトですね。しかし、よく言われるように、卵を割らずにオムレツは作れません。同様に、卵を割らずにカスタム ダイアログ ボックスは作成できません (このコラムの途中でおなかがすいたので、中断して軽食を取りました)。さて、食欲が満たされたので、このスクリプトの動作を説明できるかどうかやってみましょう。

このスクリプトでは、Internet Explorer® オブジェクト モデルを使用して擬似ダイアログ ボックスを作成します。Internet Explorer のインスタンスを作成し、Active Directory から OU のコレクションを取得し、Internet Explorer ウィンドウのリスト ボックスに取得した OU を表示します。ユーザーが OU を選択するまで待ち、選択したら、その項目の ADsPath を取得し、ダイアログ ボックスを閉じ、処理を継続します。

注: これは装飾された非常に美しいダイアログ ボックスになりますか。はい、[OK] ボタンも [Cancel] ボタンもなく、必要最小限の機能だけを備えたものを "装飾された非常に美しい" ダイアログ ボックスと呼ぶのであればそうなります。弁解になりますが、この例の目的は、基本的な枠組みを示すことです。ダイアログ ボックスを装飾したり変更したりする場合は、自力でお試しください。

(「自力でお試しください」と言うたびに 5 セントずつ受け取っていたら、ほんとうに "金持ち" になっていたでしょう。寄付の送り先は、TechNet Magazine の The Scripting Guys です。)

技術的な説明を与えられたスペースに収めるには、一部の項目を飛ばすしかありません。たとえば、次のコード ブロックについて説明できることは、幅が 350 ピクセル、高さが 400 ピクセルの Internet Explorer インスタンスを作成し、その際に、アドレス バーやステータス バーなどを非表示にすることだけです。

Set objExplorer = CreateObject( _
    "InternetExplorer.Application")

objExplorer.Navigate "about:blank"   
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width= 350
objExplorer.Height = 400 
objExplorer.Left = 400
objExplorer.Top = 400
objExplorer.Visible = 1             

もちろん、上記のコードでは、空白の Internet Explorer ウィンドウが作成されるだけです。ドメイン内の OU の一覧を取得するには、Active Directory を検索する必要があります。今日は Active Directory の検索について詳しく説明することはできません。詳細については、Script Center の 2 部構成シリーズ (microsoft.com/japan/technet/community/columns/scripts/sg0405.mspx) を参照してください。ここでは簡単に、次のコードが fabrikam.com ドメイン内の各 OU の Name と ADsPath を取得するためのコードであると説明しておきます。

objCommand.CommandText = _
    "SELECT Name, ADsPath FROM 'LDAP://DC=fabrikam,DC=com' WHERE objectCategory=
    'organizationalUnit' ORDER BY Name"

また、見やすくするために、OU の名前をアルファベット順に並べ替えました。このために ORDER BY Name 句を追加しました。(お安いご用です。これが私の務めですから。)

Execute メソッドを呼び出すと、fabrikam.com 内のすべての OU から成るレコードセットが返されます。したがって、次のステップは、これらの OU をリスト ボックスに表示することです。

では、どのような方法で表示するのでしょう。まず最初に、メモリ内にリスト ボックス全体を構築する必要があります。初心者のために説明しますが、それは次のコードを使用して、<SELECT> タグを strHTML という変数に格納することです。

strHTML = "<select size = '20' name='OUList' style='width:300px'>"

このコードでは、どのような操作を行っていますか。通常の HTML リスト ボックスを作成しているだけです (これには <SELECT> タグを使用します)。その際に、このリスト ボックスに OUList という名前を付け、一度に 20 項目が表示されるように構成し、幅を 300 ピクセル (300px) に設定します。HTML について少しでもご存知な方でしたら、上記のコードは見慣れていると思います。

次に、いくつかの項目 (つまり、OU) をリスト ボックスに追加する必要があります。偶然にも、レコードセットは、ドメイン内の各 OU に関する情報で構成されています。そのため、レコードセット全体をループする Do Until ループをセットアップすれば、情報を取得し、各 OU をリスト ボックスに追加できます。このループ内で、次のコード (リスト ボックスに項目を追加するための標準の HTML) を使用して各 OU を追加し、OU の Name が一覧に表示されるように項目を構成します。また、リスト ボックス内の OU をクリックしたとき、スクリプトに ADsPath が渡されるようにします。

strHTML = strHTML & "<option value= " & _
    Chr(34) & objRecordSet.Fields
    ("AdsPath").Value & Chr(34)
strHTML = strHTML & ">" & objRecordSet.
    Fields("Name").Value

スクリプトに ADsPath を渡すのはなぜですか。それは簡単です。ADsPath ではなく、OU の Name を渡した場合を考えてみましょう。たとえば、Name が Finance であった場合、この OU にバインドするのは困難です。何しろ、"Finance" だけでは有効な ADSI バインド文字列にはなりませんから。一方、ADsPath (LDAP://ou=Finance,dc=fabrikam,dc=com) が返された場合、バインドは非常に簡単です。なぜなら、ADsPath は、Active Directory 内のオブジェクトを検索および接続するのにまさに必要なものだからです。

ところで、リスト ボックスに Name を表示するのは、OU の名前が一意であると仮定しているからです。しかし、そうでない場合もあります。たとえば、North America\Research と Europe\Research という OU では、名前 (Research) が同じです。OU の名前が重複している場合は、ADsPath や distinguishedName など、別のプロパティをリスト ボックスで使用することをお勧めします。しかし、これは自分で判断しなければならないことです (カシャーン。また 5 セントが発生しました)。

ところで、このリスト ボックスはメモリ内に作成されている点に注意してください。つまり、ボックスに追加された各項目は、変数 strHTML に追加されたことになります。これはすべて計画どおりです。リスト ボックスのコード全体を変数 strHTML に保存してから、この変数の値を使用して Internet Explorer のインスタンスにリスト ボックスを実際に追加します。

すべての OU を追加したら、次のコードを使用してリスト ボックスの終わりであることを示します。

strHTML = strHTML & "</select>"

この時点で、strHTML には、リスト ボックスの作成に必要なすべての HTML タグが含まれています。また、何よりも良いことに、リスト ボックス内の各項目は、Active Directory 内の 1 つの OU を表しています。したがって、strHTML の値を Internet Explorer ドキュメントの InnerHTML プロパティに割り当てることができます。

objExplorer.Document.Body.InnerHTML = strHTML

これでドメイン内のすべての OU を表示するリスト ボックスができました。

待ってください。まだ完全に終わってはいません。そのままお待ちください。たとえば、ダイアログ ボックスの OU をユーザーが選択するまで、スクリプトを停止するためのコードが必要です。リスト ボックスが表示されても、このコードなしでは、ユーザーが選択したかどうかにかかわらず、スクリプトは処理を続行します。これは大変ですね。このシナリオが発生しないように、次のコード ブロックを使用します。

Do While objExplorer.Document.Body.All.OUList.Value = ""
    Wscript.Sleep 300
Loop

このコード ブロックでは、リスト ボックスの Value を繰り返し確認しています (このリスト ボックスの名前は OUList ですが、これは Scripting Guys の 1 人が自分の娘に付けた名前と同じです)。Value が空の文字列である (つまり、項目が選択されていない) 場合、スクリプトを 300 ミリ秒だけ一時停止した後、ループ処理を行い、再び確認します。この操作は、a) 永久に続くか、b) ユーザーがリスト ボックスの項目を選択するまで、または c) ユーザーが Internet Explorer ウィンドウを閉じるまで続きます。

ユーザーがリスト ボックスの OU を選択したとします。この場合は、Value (つまり、OU の ADsPath) を取得し、strTargetOU という変数に割り当てます。

strTargetOU = objExplorer.Document.Body.All.OUList.Value

次に、Quit メソッドを使用して Internet Explorer のインスタンスを終了します (次のコードを参照)。

objExplorer.Quit

これで、もうすぐ終わりです。まず、strTargetOU が空の文字列に等しいかどうかを確認します。

If strTargetOU = "" Then
    Wscript.Quit
End If

空であれば、ユーザーが OU を選択せずに Internet Explorer を閉じたことを表しています。この場合は、Wscript.Quit メソッドを使用してスクリプトを終了します (ここでは、ユーザーが OU を選択しなかった場合、ユーザーはスクリプトを実行することにあまり関心がなかったものと仮定します)。ただし、strTargetOU が空の文字列と等しくない場合は、変数の値をエコー バックします。

Wscript.Echo strTargetOU

もちろん、実際のスクリプトでは、ADsPath をエコー バックするだけでなく、Active Directory の該当する OU にバインドすることになるでしょう。しかし、よく言われるように (少なくとも、Scripting Guys の間ではよく言われます)、これは自力でお試しください。

前に説明したとおり、または、図 2 を見ておわかりのとおり、それほど美しいダイアログ ボックスではありませんが、これで十分です。また、ADsPath を入力することに比べて (ADsPath がわかっていると仮定した場合)、かなり簡単です。さらに、コードとダイアログ ボックスをニーズに合わせてカスタマイズできます。

Figure 2 A simple script dialog

Figure 2** A simple script dialog **

これで、あと、Active Directory から OU を選択するダイアログ ボックスの表示についてコラムを記述するごとに 5 セントずつ受け取ることができればいいのですが。そうすれば、通常の TechNet Magazine の収入よりも 5 セントだけ増えますから。**

念のために言っておきますが、文句を言っているわけではないのです。

Microsoft Scripting Guys はマイクロソフトの仕事をしています、というよりもマイクロソフトに雇われています。野球をプレイしたり監督したり観戦したり (または他のさまざまな活動を) しているのでない限り、彼らは TechNet Script Center を運営しています。詳細については、https://www.microsoft.com/japan/technet/scriptcenter/default.mspx を参照してください。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.