あんだあどらいぶ このページをアンテナに追加 RSSフィード

2009-06-09

windowsXPでネットワークドライブに自動的にログインする方法(wsh)

前回はバッチファイルでネットワークドライブに自動ログインする方法を調べた。今回はwshを使う方法。


wshを使う方法は以下のサイトを参考に。

基礎解説 演習方式で身につけるチェック式WSH超入門:第15回 WshNetworkオブジェクトを利用する (2/2) - @IT

MapNetworkDrive メソッド

wshそのものについては以下を参考に。

基礎解説 演習方式で身につけるチェック式WSH超入門:第1回 WSHを始めよう (1/3) - @IT



ごく基本的には、以下の記述を○○.vbs (○○は適当な名前)で保存してダブルクリックすれば自動的にネットワークドライブに接続できる。保存したファイルをスタートアップに入れておけば、起動時に自動ログインできるようになる。

 Dim objWshNetwork
 Set objWshNetwork = WScript.CreateObject("WScript.Network")
 objWshNetwork.MapNetworkDrive "x:", "\\サーバ名\共有フォルダ名", False, "ユーザ名", "パスワード"

ただ、この方法でもファイルにパスワードを記述しておく必要がある。それが嫌な場合は、InputBoxを使ってユーザー入力を受け取るようにすれば、ファイルに記述しておく必要は無くなる。InputBoxで入力されたパスワード文字列に保持し、それを先ほどのコマンドに渡してやれば良い。以下のような記述で実現可能。

 Option Explicit
 Dim string
 string = InputBox("パスワードを入力してください。")
 Dim objWshNetwork
 Set objWshNetwork = WScript.CreateObject("WScript.Network")
 objWshNetwork.MapNetworkDrive "x:", "\\サーバ名\共有フォルダ名", False, "ユーザー名", string

接続するネットワークドライブが複数の場合、パスワードがすべて同じであれば、objWshNetwork.MapNetworkDriveを複数記述してやれば、1度のパスワード入力で全ドライブにログインできるようになる。

が、InputBoxでは入力した文字列がまる見えになる。できれば****のように表示して隠して表示したい。


パスワードをマスクする方法

入力したパスワードを****のようにマスクして表示する方法がないか調べてみた。結果、wsh(vbs)ではパスワード入力をマスクする方法がないことが分かった。下記のサイトによると、ScriptPWというオブジェクトを使えば実現できるらしいが、windowsXP HomeだとScriptPWが使えないようだ。

Microsoft スクリプト センター | TechNet

先のサイトでは、HTMLで実現する方法が載っているが、パスワード入力のためだけにIEが立ち上がるのもどうかと思うので、別の方法を考えることにする。


パスワード入力方法の方針

結局、visual C++ express edition 2008を使って、パスワード入力用のフォームを表示するだけのプログラムを作成し、wshからそれを呼び出す方法をとることにする。

入力されたパスワード文字列は、標準出力を使って出力し、wsh側でそれを受け取るようにする。


visual C++パスワード入力用のフォームを作成

入力されたパスワードをそのまま表示したくないので、MaskedTextBox を使うことにする。MaskedTextBoxを使うと、入力された文字列の代わりに「*」を表示して、パスワードを隠すことが出来る。

使うときはMaskedTextBoxのPasswordCharプロパティに「*」を入力すればいい。その他のプロパティデフォルトのままでOK。入力された文字列は、普通のTextBoxと同じように参照できる。

フォームにはMaskedTextBoxと、OKボタン、キャンセルボタンのみを配置。パスワード入力後にOKボタンを押すと、入力された文字列を標準出力に出力して、プログラムを終了する。OKボタンを押した後の動作のソースは以下のようになる。

 // OKボタンが押されたときの処理
 private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
     // 標準出力に出力
     Console::Write(maskedTextBox1->Text);
     Application::Exit();
  }
 // キャンセルボタンが押されたときの処理
 private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
    Application::Exit();
 }

ちなみに、フォームを画面の中央に表示するには、フォームのプロパティのStartPositionをCenterScreen としておけばいい。

以下のページを参照のこと。

フォームを画面の真ん中(あるいは、任意の位置)に表示する: .NET Tips: C#, VB.NET


wshからパスワード入力フォームを呼び出し&パスワード文字列の取得

先に作成したパスワード入力用フォームを表示するプログラムを、wshから呼び出してパスワード入力を行う。

wshから外部のアプリケーションを呼び出す方法には、WshShellオブジェクトのRunメソッドとExecメソッドがある。詳しい解説は次のサイトを参照。

基礎解説 演習方式で身につけるチェック式WSH超入門:第12回 WshShellオブジェクトを利用する(1) (1/2) - @IT

今回は標準入出力を使いたいので、Execメソッドを使う。詳しい解説は以下のサイトを参照。

基礎解説 演習方式で身につけるチェック式WSH超入門:第14回 WshShellオブジェクトを利用する(3) (1/4) - @IT

外部プログラムを起動するためのオブジェクト変数の宣言とWshShellオブジェクトの作成は以下の通り。

 Dim objWshShell
 Set objWshShell = WScript.CreateObject("WScript.Shell")

上記オブジェクトのExecメソッドで、先ほどのパスワード入力フォーム表示プログラム(passform.exe)を起動するには次のように記述する。パスは適当。

 Dim objExec
 Set objExec = objWshShell.Exec("C:\passform.exe")

なお、パスは絶対パスでも、スクリプトを置いてあるディレクトリからの相対パスでもOK。

標準出力に出力された文字列を取得するには、以下のようにする。

 Dim string
 string = objExec.StdOut.ReadLine

詳しくは以下のサイトを参照。

Office TANAKA - Excel VBA Tips[MS-DOSコマンドの標準出力を取得する]



ここまでできれば、あとは上のほうに記述した方法で、ネットワークドライブの割り当てを行えばいい。

結局、作成したスクリプトは以下のようになった。

ここでは、server1のshareAというフォルダをxドライブ、server2のshareBというフォルダをzドライブ、server3のshareCというフォルダをyドライブとしてネットワークドライブの接続を行っている。ユーザー名はuser_nameとしてある。

また、上記の基本機能に加えて、以下の機能も追加してある。

  • 起動したパスワード入力フォーム表示プログラムの終了を待ってから、以降の処理を実行する
  • パスワード入力フォームでキャンセルボタンを押されたときはスクリプトを終了する
  • すでに接続済みの場合は処理を行わない(接続済みのドライブに接続しようとするとエラーになって、そこでスクリプトが止まる)
  • 接続完了したら、それを通知するポップアップを表示(5秒表示した後、勝手に消える)

ポップアップについての説明は次のサイトを参照。

Popup メソッド

 Option Explicit

 'オブジェクト変数の宣言とWshShellオブジェクトの作成。
 Dim objWshShell
 Set objWshShell = WScript.CreateObject("WScript.Shell")

 ' 標準入出力を使うため、Execメソッドで起動
 Dim objExec
 Set objExec = objWshShell.Exec("passform.exe")

 WScript.Sleep(1000)

 ' 起動したプログラムの終了を待つ
 Do While objExec.Status = 0
  WScript.Sleep(100)
 Loop 

 Dim string
 ' 標準出力から文字列を1行取得
 string = objExec.StdOut.ReadLine

 If(string = "") Then
  MsgBox "キャンセルされました"
  WScript.Quit
 End If


 Dim objWshNetwork
 Set objWshNetwork = WScript.CreateObject("WScript.Network")
 Dim objFSO
 Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
 '接続済みのネットワークドライブを調査し、未接続なら接続する
 If Not objFSO.DriveExists("x:") Then
    objWshNetwork.MapNetworkDrive "x:", "\\server1\shareA", False, "user_name", string
 End If
 If Not objFSO.DriveExists("z:") Then
    objWshNetwork.MapNetworkDrive "z:", "\\server2\shareB", False, "user_name", string
 End If
 If Not objFSO.DriveExists("y:") Then
    objWshNetwork.MapNetworkDrive "y:", "\\server3\shareC", False, "user_name", string
 End If

 ' 完了通知ポップアップの表示
 string = "全ネットワークドライブに接続完了しました"
 objWshShell.Popup string, 5',, vbInformation


 ' オブジェクトの破棄
 Set objWshShell = Nothing
 Set objExec = Nothing
 Set objWshNetwork = Nothing
 Set objFSO = Nothing

まとめ

以上の方法で、windowsXPネットワークドライブに自動ログインするスクリプトを作成できた。パスワードスクリプトファイルに直接書いておかなくてもよくなったし、やや手間はかかったがパスワード入力時に入力した文字列をマスクすることも可能となった。スクリプトの記述はどこかおかしい箇所があるかもしれないし、もっとスマートなやり方があるかもしれないが、とりあえずうまく動いているようなので、これでよしとする。

あと、参考にされる方は自己責任でお願いしますね。




WSHクイックリファレンス 第2版
羽山 博
オライリー・ジャパン
売り上げランキング: 13198
おすすめ度の平均: 5.0
5 TIPS本ではなくリファレンス本です

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証