ヨッシーの部屋

オートバイとパソコンの話題が中心

VBSでログオンスクリプトを再構築(その7)

2006-07-10 15:57:34 | Windows管理者の悩ましき日々
今回はネットワークドライブを接続する方法を考える。

基本的には WshNetworkオブジェクトの MapNetworkDriveメソッドを使えばよい。
基本的な文法は以下の通りだ。

01:Set objNet = CreateObject("WScript.Network")
02:objNet.MapNetworkDrive "Z:","¥¥FileServer¥Shar1",False

上例では "FileServer" というホストの "Shar1" という共有フォルダを "Z:" として接続し、False 指定により接続内容を記録しない(=次回ログオン時に自動接続しない)といった指令を行っている。

単に全ユーザーに同じ条件で接続したいのであればこれだけで良いのだが、実際にはユーザー名や所属するセキュリティグループによってドライブを変更したいケースが多いと思う。

ログオンしたユーザー名を特定するには WshNetworkオブジェクトの UserNameプロパティを参照すればよい。

01:Set objNet = CreateObject("WScript.Network")
02:Select Case objNet.UserName
03: Case "ユーザー1"
04:  Call MapNetDrive("X:","¥¥FileServer¥Shar1")
03: Case "ユーザー2"
04:  Call MapNetDrive("Y:","¥¥FileServer¥Shar2")
03: Case "ユーザー3"
04:  Call MapNetDrive("Z:","¥¥FileServer¥Shar3")
05:End Select
06:
07:Sub MapNetDrive(strDrive,strNetPath)
08: objNet.MapNetworkDrive strDrive,strNetPath,False
09:End Sub

上例のように MapNetworkDriveメソッドをサブルーチン化(7~9行目)し、UserNameプロパティの値を Select文で分岐させると見易いコードになる。

次に所属するセキュリティグループによってドライブを変更したい場合を紹介する。

ユーザー名から所属するセキュリティグループの一覧を取得するには、DOSの「Net User」コマンドを使う手法も有りだが、標準出力の内容を1行づつ評価する必要がある為、ADSIオブジェクトを利用する手法の方がスマートかつ正確だ。
まずはサンプルコードを紹介する。

01:Set objADs = CreateObject("ADSystemInfo")
02:Set objUser = GetObject("LDAP://" & objADs.UserName)
03:Select Case TypeName(objUser.MemberOf)
04: Case "Variant()"
05:  ReDim strGroups(UBound(objUser.MemberOf))
06:  strGroups = objUser.MemberOf
07: Case "String"
08:  ReDim strGroups(0)
09:  strGroups(0) = objUser.MemberOf
10: Case else
11:  ReDim strGroups(0)
12:  strGroups(0) = Empty
13:End Select

1行目でADSIオブジェクトを参照し、2行目で現在ログオンしているユーザーの ActiveDirectory上のコンテナをオブジェクト化する。
セキュリティグループの一覧は1行目でオブジェクトしたユーザーコンテナの MemberOfプロパティで取得できるが、戻り値のタイプ(=データ型)が所属するグループの数によって異なる点に注意が必要だ。
サンプルコードでは3行目で MemberOfプロパティのデータ型を判断し、処理を分岐させている。

4~6行目は2つ以上のグループに所属している場合のコーディングで、戻り値のデータ型は配列型となる。
5行目で戻り値と同じ配列数の変数「strGroups」を宣言し、6行目で戻り値を宣言した配列にセットしている。

7~9行目は単一のグループに所属している場合のコーディングで、戻り値のデータ型は文字列型となる。
8行目で配列数=1個の変数「strGroups」を宣言し、9行目で戻り値を宣言した配列にセットしている。

10~12行目はどのグループにも所属していない場合のコーディングで、戻り値のデータ型はEmptyとなる。
11行目で配列数=1個の変数「strGroups」を宣言し、12行目で空値を宣言した配列にセットしている。

単に MemberOfプロパティの内容を列挙する手法(For Each GroupName In objUser.MemberOf)ではエラーとなるケースがあったので、このようなコーディングを考案した。

グループの一覧を取得したら今度はグループ名による分岐とドライブの接続だ。

01:For Each strGroup in strGroups
02: If Len(strGroup) > 0 Then
03:  Set objGroup = GetObject("LDAP://" & strGroup)
04:  strGroupName = LCase(objGroup.CN)
05:  Select Case strGroupName
06:   Case "Group1"
07:    Call MapNetDrive("X:","¥¥FileServer¥Shar1")
08:   Case "Group2"
09:    Call MapNetDrive("Y:","¥¥FileServer¥Shar2")
10:   Case "Group3"
11:    Call MapNetDrive("Z:","¥¥FileServer¥Shar3")
12:  End Select
13: End If
14:Next
15:
16:Sub MapNetDrive(strDrive,strNetPath)
17: objNet.MapNetworkDrive strDrive,strNetPath,False
18:End Sub

1行目で配列型変数「strGroups」の内容を文字列型の変数「strGroup」に列挙。
2行目で変数「strGroup」のレングスをチェック。
3行目でセキュリティグループの ActiveDirectory上のコンテナをオブジェクト化。
4行目でコンテナ名を取得。
5~12行目でグループ名の分岐とサブルーチンの呼び出し。

以上で一通りの解説を終わるが、ログオンスクリプトの最後でネットワーク障害やサーバ障害で接続できなかったドライブをメッセージ表示したい。
これには先の MapNetworkDriveメソッドの戻り値を記憶しておく方策が得策だ。

01:Sub MapNetDrive(strDrive,strNetPath)
02: On Error Resume Next
03: objNet.MapNetworkDrive strDrive,strNetPath,False
04: If Err.Number <> 0 Then
05:  ErrCnt = ErrCnt + 1
06:  ErrDrive(ErrCnt,0) = strDrive
06:  ErrDrive(ErrCnt,1) = strNetPath
07: End If
08: Err.Clear
09: On Error GOTO 0
10:End Sub

2次元配列の変数「ErrDrive」とエラーカウント変数「ErrCnt」を事前に準備しておき、MapNetworkDriveメソッドが失敗したらエラーカウント変数「ErrCnt」をカウントアップし、配列「ErrDrive」にドライブ名とネットワークパスを保存しておく。

ログオンスクリプトの最後でエラーカウント変数「ErrCnt」がゼロ以上の場合にメッセージを表示するといったコーディングを記述すれば完璧だ。


最新の画像もっと見る