Hey, Scripting Guy!

Hey, Scripting Guy!

TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

Hey, Scripting Guy! アーカイブも忘れずにチェックしてください。

今日の質問 : Active Directory 内の全サイトとそれらのサイト内の全サーバーの一覧を取得する方法はありますか


Active Directory 内の全サイトとそれらのサイト内の全サーバーの一覧を取得する方法はありますか

Q

Scripting Guy さん、よろしくお願いします。Active Directory の全サイトとそれらのサイト内の全サーバーの一覧を取得する方法はありますか。

-- DW

A

DW さん、こんにちは。私たちを試そうとしているのですね。ユーザーとグループについては十分な知識があります。少なくともユーザーとグループがいったい何なのかはある程度理解しています。コンピュータ アカウントや OU についても、まったく問題ありません。ただし、サイトやサイト リンクのようなものとなると、心配になってきました。結局、それらのスクリプトの作成方法どころか、それらが何であるかさえ確信が持てないのです。

しかしこれまでに、Scripting Guys が、知識や理解の不足によって立ち止まったことはあったでしょうか。もちろんありません。次のスクリプトでは、Active Directory 内の全サイトと、それらの各サイト内にあるサーバーの一覧を取得します。

On Error Resume Next

Set objRootDSE = GetObject("LDAP://RootDSE")
strConfigurationNC = objRootDSE.Get("configurationNamingContext")
 
strSitesContainer = "LDAP://cn=Sites," & strConfigurationNC
Set objSitesContainer = GetObject(strSitesContainer)
objSitesContainer.Filter = Array("site")
 
For Each objSite In objSitesContainer
    Wscript.Echo objSite.CN
    strSiteName = objSite.Name
    strServerPath = "LDAP://cn=Servers," & strSiteName & ",cn=Sites," & _
        strConfigurationNC
    Set colServers = GetObject(strServerPath)
 
    For Each objServer In colServers
        WScript.Echo vbTab & objServer.CN
    Next
    Wscript.Echo
Next

ここでは何をしているのでしょうか (実はこれは修辞疑問ではなく、誰かが私たちにすべて説明してくれることを期待していました)。まず、次の 2 行のコードを使用して Active Directory ルートにバインドしてから、Configuration コンテナ (configuringNamingContext) にバインドします。

Set objRootDSE = GetObject("LDAP://RootDSE")
strConfigurationNC = objRootDSE.Get("configurationNamingContext")

なぜこのような操作から開始するのでしょうか。Configuration コンテナには、Active Directory の物理的な構造およびレイアウトに関する情報が保持されています。そこには、サイトに関する情報と各サイトに割り当てられているサーバーに関する情報があります。Active Directory ルート (rootDSE) にバインドしてから、Get メソッドを使用して configurationNamingContext を取得すると、ドメイン名にかかわらず、Configuration コンテナへの Active Directory パスを取得できます。

注 : それはどういうことでしょうか。1 つには、fabrikam.com を実際のドメイン名に変更せずに、このスクリプトをそのまま使用できるということです。ご覧のとおり、スクリプトでは fabrikam.com (または他のドメイン名) を参照している部分がありません。

次のステップでは、すべての Active Directory サイトのコレクションを取得します。その処理は次のコード部分で行われます。

strSitesContainer = "LDAP://cn=Sites," & strConfigurationNC
Set objSitesContainer = GetObject(strSitesContainer)
objSitesContainer.Filter = Array("site")

1 行目では、LDAP://cn=Sites と configurationNamingContext を結合して Sites コンテナへの ADsPath を作成します。GetObject メソッドを使用してコンテナにバインドし、コレクション内のアイテムを Site オブジェクトに制限する Filter を適用します。最終結果を見てみましょう。objSitesContainer にはすべての Active Directory サイトのコレクションが含まれています。

思っていたより簡単です。次に、サイトのコレクションを順番に処理するように For Each ループを設定します。ループ内でコレクションの最初のサイトの CN をエコーし、strSiteName 変数にサイトの Name (CN=Default-First-Site-Name など) を保存します。

Wscript.Echo objSite.CN
strSiteName = objSite.Name

ご覧のように、各 Active Directory サイトには Servers コンテナがあり、各 Servers コンテナにはそのサイトに割り当てられているサーバーの一覧が保持されています。最初のサイトの Servers コンテナにバインドするには、次のコード行を使用して ADsPath を作成します。パスは、変数 strServerPath に格納されます。

strServerPath = "LDAP://cn=Servers," & strSiteName & ",cn=Sites," & _
    strConfigurationNC

ADsPath を作成したら、次のコード行を使用して最初のサイトの Servers コンテナにバインドします。

Set colServers = GetObject(strServerPath)

順調です。次に、Servers コンテナにある項目のコレクションを順番に処理する 2 番目の For Each ループを設定します。コレクション内のサーバーごとに、サーバー CN をエコー バックするだけです。

For Each objServer In colServers
    WScript.Echo vbTab & objServer.CN
Next

そうでした。サーバー名の前にタブ文字 (vbTab) を挿入します。サンプル出力を見ると、理由はすぐにわかります。

これで終わりです。最初のサイトの名前と、そのサイトに割り当てられているすべてのサーバーがエコー バックされています。ループに戻り、コレクション内の 2 番目のサイトで同じ処理を繰り返します。このループは、すべてのサイトを処理し、それらのサイト内のすべてのサーバー名をエコー バックするまで続きます。すべて終了すると、次のような出力が返されます。

Default-First-Site-Name
    atl-dc-01
    atl-dc-02

European-Site
    lon-dc-01
    lon-dc-02
    par-dc-01
    bru-dc-01
    bru-dc-02

どうですか。悪くないでしょう。私たちが何をしているのかを実際に知っていたなら、どんなにすばらしいスクリプトを書くことかできたことでしょう。


関連情報

Hey, Scripting Guy!- アーカイブもチェックしてください。

ページのトップへページのトップへ