Hey, Scripting Guy!

Scripting Guys が皆さんの質問にお答えします

Hey, Scripting Guy!

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

詳細情報

Hey, Scripting Guy! カテゴリ別アーカイブ

Hey, Scripting Guy! 日付別アーカイブ

Hey, Scripting Guy! ダウンロード

Spacer

*

IP アドレスに基づいてドライブを割り当てる方法はありますか

Hey, Scripting Guy! Question

Scripting Guy さん、よろしくお願いします。私は、Hey, Scripting Guy! コラムで紹介されていたグループ メンバシップに基づいてドライブを割り当てるスクリプトを使用していて、このスクリプトは問題なく機能するのですが、ドライブ割り当てがコンピュータの場所 (もっと具体的に言うと、コンピュータの IP アドレス) にも基づいて行われるように、スクリプトを変更する必要があります。たとえば、ISDN 接を使用しているリモート サイトがあるのですが、ドライブ割り当ては、このリンク経由ではなく、ローカル サイトのサーバーに対して行う必要があります。ドライブを割り当てる際にグループ メンバシップと IP アドレスの両方が使用されるようにするには、スクリプトをどのように変更すればよいですか。

-- BT

SpacerHey, Scripting Guy! AnswerScript Center

BT さん、こんにちは。説明を始める前に、マイクロソフトで新しく働き始めた社員 (このコラムを読み始めた、まさに文字どおり、私たちの一言一言に熱心に耳を傾けている仲間たち) に向けて特別にあいさつをさせてください。皆さん、我が社へようこそ。皆さんが今日のコラムを読んでがっかりしないとよいのですが。今日の Scripting Guys はきわめて事務的で、いつものようなくだらない話は、しないからです。

おや、ちょっとしたジョークを 1 つ言う時間がありますね。金髪、黒髪、赤毛の 3 人の女性がバーに入りました。金髪の女性が、「ねえ、バーテンダーさん。この若くてきれいな女の子 3 人だけで、よく知らない町で一夜を過ごさないといけなくなったんだけど、お勧めのインターネット検索エンジンを教えてもらえるかしら」と言いました。

バーテンダーは、「もちろん、Windows Live Search ですよ。これは単に優れたインターネット検索エンジンであるだけでなく、唯一のインターネット検索エンジンですから」と答えました。

まあ、あまりおもしろいジョークではなかったかもしれません。でも、マイクロソフト社員のユーモア センスは独特なのです。

私たち Scripting Guys は何度もそれを思い知らされているんですが。

それに、もう本題に入る時間です (でも、まだお伝えしていなかったとしたら、Windows Live Search は単に優れたインターネット検索エンジンであるだけでなく、唯一のインターネット検索エンジンであるということをお伝えしておかなければなりません。少なくとも、検索エンジンとして関心を持つ必要がある唯一のインターネット検索エンジンだということは断言できます)。

BT さんは、特定の Active Directory グループにおけるユーザーのメンバシップに基づいてネットワーク ドライブを割り当てる方法として、ログオン スクリプト (以前のコラムで説明したもの) を使用してきたとのことです。しかし、コンピュータの IP アドレス (もう少し正確に言うと、IP アドレスの第 3 オクテット) に基づいた条件を追加することが必要になりました。たとえば、ユーザーが Finance Users グループに属していて、コンピュータの IP アドレスが 192.168.36.1 の場合は、ドライブには \\atl-fs-01\finance が割り当てられます。それ以外の場合は、\\atl-fs-02\finance が割り当てられます。

ちなみに、IP アドレスに基づいてドライブを割り当てる方法についての質問は、一般的な質問のようで、この方法について問い合わせる電子メールは、ここ数週間で数件寄せられました。今日のスクリプトは、このような質問への回答にもなるでしょう。

: お勧めのインターネット検索エンジンを教えてもらえないかという内容の電子メールも、ここ数週間で数件ありました。もちろん、お教えしますよ。Windows Live Search です。

Windows Live Search。それは、単に優れたインターネット検索エンジンであるだけでなく、唯一のインターネット検索エンジンです。

編集者注 : 完全な情報公開と公正を期して、Windows Live Search が唯一のインターネット検索エンジンではない可能性があることを認めます ("可能性がある" と言ったんですよ)。唯一のものでなくても、唯一のものだというふりをしておいてください。

さて、BT さんのお役に立つには、どうすればよいでしょうか。次のスクリプトを使用します。

On Error Resume Next 
 
Set objSysInfo = CreateObject("ADSystemInfo") 
Set objNetwork = CreateObject("Wscript.Network") 
 
strUserPath = "LDAP://" & objSysInfo.UserName 
Set objUser = GetObject(strUserPath) 
 
strComputer = "." 
 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") 
 
Set colItems = objWMIService.ExecQuery _ 
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True") 
 
For Each objItem in colItems 
    For Each objAddress in objItem.IPAddress 
        arrIPAddress = Split(objAddress, ".") 
        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then 
            strAddress = arrIPAddress(2) 
            Exit For 
        End If 
    Next 
    Exit For 
Next 
 
For Each strGroup in objUser.MemberOf 
    strGroupPath = "LDAP://" & strGroup 
    Set objGroup = GetObject(strGroupPath) 
    strGroupName = objGroup.CN 
 
    Select Case strGroupName 
        Case "Finance Users" 
            If strAddress = 36 Then 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance" 
                Exit For 
            Else 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance" 
                Exit For 
            End If 
        Case "Human Resource Users"  
            If strAddress = 36 Then 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\hr" 
                Exit For 
            Else 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\hr" 
                Exit For 
            End If 
        Case "Manufacturing Users" 
            If strAddress = 36 Then 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\manufacturing" 
                Exit For 
            Else 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\manufacturing" 
                Exit For 
            End If 
        Case "Shipping and Receiving Users" 
            If strAddress = 36 Then 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\shipping" 
                Exit For 
            Else 
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\shipping" 
                Exit For 
            End If 
    End Select 
Next

ちなみに、このスクリプトの長さにひるまないでくださいね。こんなに長いのは、単に、4 〜 5 グループ分のドライブ割り当てコードが含まれているからです。もうおわかりだと思いますが、このスクリプトの大部分は定型的で、コピーして貼り付けて、それから場合によっては、(グループ名やネットワーク パスの変更など) ちょっとした変更を 1 つか 2 つ加えるだけで、運用環境で使用できるコードになります。

このスクリプトでは、まず ADSystemInfo オブジェクトと Wscript.Network オブジェクトのインスタンスを作成します。ADSystemInfo オブジェクトは、ローカル ユーザーの Active Directory ユーザー アカウントにバインドするために使用し、Wscript.Network オブジェクトは、ネットワーク ドライブを割り当てるために使用します。2 つのオブジェクトを作成したら、次のコード行を使用して、ログオンしているユーザーの ADsPath を作成します。

strUserPath = "LDAP://" & objSysInfo.UserName

ADsPath を作成したら、次のコード行を実行して、Active Directory のユーザー アカウントにバインドできます。

Set objUser = GetObject(strUserPath)

: ええ、確かに、ADSystemInfo と ADSystemInfo の用途に関する上記の説明は、かなり大雑把なものでしたね。詳細については、グループ メンバシップに基づいてドライブを割り当てる方法に関する以前のコラムを参照してください。

Windows Live Search を使用してインターネットで詳細を検索すると、なお良いでしょう。

Windows Live Search。それは、単に優れたインターネット検索エンジンであるだけでなく・・・。はい、そうでしたね。このセリフはもう言いましたよね。

次は、ローカル コンピュータの IP アドレスを特定します。この処理は、皆さんが思っているよりも少し厄介です (なぜかというと、コンピュータには複数のネットワーク アダプタを搭載することができ、複数の IP アドレスを割り当てることができるからです)。まず、次のコード ブロックを使用して、ローカル コンピュータの WMI サービスに接続します。

strComputer = "." 
 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

続いて、次のコード行を使用して、このコンピュータに搭載されている “本物の” ネットワーク アダプタすべてのコレクションを取得します。

Set colItems = objWMIService.ExecQuery _ 
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")

: “本物の” ネットワーク アダプタというのは、どういう意味でしょうか。良かれ悪しかれ (正直なところ、おそらくこれは悪いことでしょうが)、Win32_NetworkAdapterConfiguration クラスは、実在する本物のネットワーク アダプタだけでなく多数の仮想ネットワーク アダプタに関する情報も返すのです。さいわい、IPEnabled プロパティが True に設定されているアダプタのデータだけが返されるように制限する Where 句を含めることによって、このような仮想アダプタの大半を除外できます。上記のコードでは、まさにこの処理が行われています。

次は、このコード ブロックです。

For Each objItem in colItems 
    For Each objAddress in objItem.IPAddress 
        arrIPAddress = Split(objAddress, ".") 
        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then 
            strAddress = arrIPAddress(2) 
            Exit For 
        End If 
    Next 
    Exit For 
Next

ここでは、ネットワーク アダプタのコレクション全体をループ処理する For Each ループを設定しています。その直後に、2 つ目の For Each ループを設定しています。このループは、各アダプタに割り当てられている全 IP アドレスをループ処理するように設計されています (1 つのアダプタに複数の IP アドレスを割り当てることができるので、IPAddress プロパティには情報が配列として格納されています)。この 2 つ目のループでは、Split 関数を使用して、1 つ目の IP アドレスをピリオドの箇所で分割しています。たとえば、192.168.1.2 という IP アドレスは、次の要素で構成される arrIPAddress という名前の配列になります。

192

168

1

2

しくみをおわかりいただけましたでしょうか。それは良かったです。これで、説明を続けることができます。

有効な IP アドレスが割り当てられていることを確認するために、今度は次のコード行を実行します。

If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then

ここでは単に、IP アドレスの第 1 オクテット (つまり配列の要素 0) が、0 と 169 のいずれでもないことを確認しています。第 1 オクテットが 0 の場合は、IP アドレスが割り当てられていないアダプタを参照している可能性があります。また、第 1 オクテットが 169 の場合は、自動的に割り当てられた IP アドレスを使用しているアダプタを参照していることになります。このどちらの条件にも該当しない場合は、有効な IP アドレスが割り当てられていると見なします。これを念頭に置き、次のコード行を使用して、strAddress という名前の変数に配列の要素 2 (IP アドレスの第 3 オクテット) を代入します。

strAddress = arrIPAddress(2)

: 配列の 1 つ目の要素のインデックス番号は 0 で、配列の 2 つ目の要素のインデックス番号は 1 です。第 3 オクテットの値を取得する際に arrIPAddress(2) を参照しているのは、配列の 3 つ目の要素のインデックス番号が 2 だからです。

有効なアドレスが割り当てられていることを確認したら、Exit For ステートメントを呼び出して For Each ループを終了します。つまり、コンピュータに複数の IP アドレスが割り当てられていても、最初に見つかった有効な IP アドレスを使用するということです (おそらく、この動作によってそれほど多くの問題が発生することはないでしょう。というのも、通常、ログオン スクリプトは、クライアント コンピュータに対して実行されるもので、クライアント コンピュータには一般的に複数の IP アドレスは割り当てられないからです)。

これで、ログオンしているユーザーが属しているグループを表すコレクション全体のループ処理を開始する準備ができました。このループ処理は、次のコード行を使用して行います (MemberOf 属性は複数の値を持つ属性で、この属性には、ユーザーが属しているグループがすべて格納されています)。

For Each strGroup in objUser.MemberOf

このループでは、どのような処理を行うのでしょうか。まず、コレクション内の各グループに対して、次のコード ブロックを使用して、Active Directory のグループ アカウントにバインドし、グループの CN 属性 (共通名) の値を取得します。

strGroupPath = "LDAP://" & strGroup 
Set objGroup = GetObject(strGroupPath) 
strGroupName = objGroup.CN

その後、Select Case ステートメントを設定し、ユーザーが特定のグループのメンバであるかどうかの確認作業を開始します。特定のグループのメンバである場合は、そのグループに応じてドライブ X にネットワーク パスを割り当てます。以下に例を示します。

Case "Finance Users" 
    If strAddress = 36 Then 
        objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance" 
        Exit For 
    Else 
        objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance" 
        Exit For 
    End If

ここで行っている処理を理解するのは、それほど難しいことではありません。ユーザーが属している最初のグループの名前を取得し、そのグループ名が Finance Users であるかどうかを確認しています。そのグループ名が Finance Users の場合は、IP アドレスの第 3 オクテットが 36 であるかどうかを確認します。これを行うのが次のコード行です。

If strAddress = 36 Then

第 3 オクテットが 36 の場合は、ドライブ X に \\atl-fs-01\finance を割り当てます。第 3 オクテットが 36 でない場合は、ドライブ X に \\atl-fs-02\finance を割り当てます。どちらの場合も、ドライブ X にネットワーク ドライブを割り当てたら、Exit For ステートメントを使用して For Each ループを終了します。これにより、ユーザーが目的のグループのうちの複数に属している場合にエラーが発生するのを防ぐことができます (なぜエラーが発生するかというと、既にドライブ X に \\atl-fs-01\finance を割り当てたにもかかわらず、ドライブ X に \\atl-fs-01\shipping の割り当てを試行する可能性があるからです。これはやってはいけないことです)。

: では、ユーザーが複数のグループに属している場合について考えてみましょう。その場合、使用されていないドライブ文字を必要に応じて割り当てて、複数のネットワーク ドライブをマップすることは可能でしょうか。このような処理は可能です。ただし、言うまでもありませんが、これを行うには追加の処理が必要です。今日は、この追加の処理について説明する時間はありませんが、ドライブ文字として次に使用可能な文字を特定する方法について説明した別のコラムをご紹介することぐらいはできます。

これでご質問の回答になっているとよいのですが、BT さん。Scripting Guys が Windows Live Search を使用してインターネットで検索を行う時間が来てしまいました。Windows Live Search。それは、単に優れた検索エンジンであるだけでなく・・・。続きはご自分で言えますよね。私たちは検索をしなけらばならないものですから。


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