メルマガ・ステップメール基本システム

[VBS] 特定の処理を各PCで一度だけ実行させるVBS

数十台ある社内のPCで、一斉にネットワークドライブの設定変更を行う必要が出たので、ログオンスクリプト代わりのバッチファイルから呼び出せる「一度だけ処理させたいときの判定ツール」を作ってみたのでメモメモ。

先に使い方。

ファイル名は「only_once.vbs」とします。

Usage  : > cscript only_once.vbs <param>
               param: 実行させたいvbsファイル(拡張子なし)
Comment: ・<param>.txtというファイル名でPC管理用ファイルを生成する
         ・<param>.txtに記述の無いPCだけ、<param>.vbsを実行する
         ・<param>.vbsがエラー終了した場合は、<param>.txtに書き込まない
         ・<param>.vbs内では、正常終了時に0を返すように処理を組むこと

このVBSを実行したPCのコンピュータ名がテキストファイルに次々追加されていき、既にテキストファイルにコンピュータ名が存在するPCは、処理を行わずに終了する、という流れ。

なんだか説明が難しいので、詳しくはソースで(笑)

Option Explicit

' 定数宣言
Const vbFileRead = 1          ' ファイル読込モード
Const vbFileWrite = 2         ' ファイル書込モード
Const vbFileAppend = 8        ' ファイル追記モード

Const vbFileCreate = True     ' ファイルが存在しなかった場合新規作成する
Const vbFileNotCreate = False ' ファイルが存在しなかった場合新規作成しない

Const vbEncAscii = 0          ' 文字コード ASCII
Const vbEncUtf16 = -1         ' 文字コード UTF-16
Const vbEncSystemDefault = -2 ' 文字コード システムのデフォルト


' 変数宣言
Dim blmIsExist
Dim strPath, strFileScriptPath, strFileTextPath, strHostName, strTextLine
Dim intReturn
Dim objNetwork, objFso, objInputFile, objOutputFile, objShell


' 初期設定
strPath = "\\192.168.1.1\logon_scripts\script\"


'-------------------------------------------------------------------------------
' 処理開始
'-------------------------------------------------------------------------------
blmIsExist = False

' パラメータの数をチェックし、1つ以外の場合はエラー終了する
If WScript.Arguments.Count <> 1 Then
    WScript.Quit(-1)
End If

' ファイルシステムオブジェクトを生成
Set objFso = WScript.CreateObject( "Scripting.FileSystemObject" )

' パラメータで指定されたファイル名から、スクリプトとPC名管理ファイルのフルパスを生成する
strFileScriptPath = strPath & WScript.Arguments(0) & ".vbs"
strFileTextPath = strPath & WScript.Arguments(0) & ".txt"

' パラメータで指定されたスクリプトファイルが存在しない場合はエラー終了する
If Not objFso.FileExists( strFileScriptPath ) Then
    WScript.Quit(-1)
End If

' PC名を取得する
Set objNetwork = CreateObject( "WScript.Network" )
strHostName = objNetwork.ComputerName
Set objNetwork = Nothing

' 読み込みファイルが存在したら、ファイル内にPC名が存在するかどうかチェックする
If objFso.FileExists( strFileTextPath ) Then
    ' 読み込みファイルをオープンする
    Set objInputFile = objFso.OpenTextFile( strFileTextPath, vbFileRead, vbFileNotCreate, vbEncAscii )
    ' ファイル内を1行ずつ読み込む
    Do Until objInputFile.AtEndOfStream
        strTextLine = objInputFile.ReadLine
        ' 取得したPC名が存在したら処理を抜ける
        If InStr( strTextLine, strHostName ) > 0 Then
            blmIsExist = True
            Exit Do
        End If
    Loop
    ' 読み込みファイルをクローズする
    objInputFile.Close
End If

' ファイル内にPC名が存在していなかったら、処理を行い、PC名をファイルに書き込む
If Not blmIsExist Then
    ' 処理用のスクリプトファイルを同期で呼ぶ
    Set objShell = WScript.CreateObject( "WScript.Shell" )
    intReturn = objShell.Run( "cscript " & strFileScriptPath, 0, True )
    ' 処理が正常終了してきた場合のみ、PC管理用ファイルに書き込み処理をする
    If intReturn = 0 Then
        ' 書き込みファイルを追記モードでオープンする(存在しない場合は新規作成)
        Set objOutputFile = objFso.OpenTextFile( strFileTextPath, vbFileAppend, vbFileCreate )
        ' 取得したPC名を書き込む
        objOutputFile.WriteLine strHostName
        ' 書き込みファイルをクローズする
        objOutputFile.Close
    End If
End If

で、このスクリプトから呼ぶ、ネットワークドライブの設定変更を行うVBS。今回は、ネットワークドライブのIPアドレス変更による設定変更処理。

共有フォルダは「\\192.168.xxx.xxx\example」の「example」の部分をドライブ名称にする前提。

Option Explicit

' 変数宣言
Dim objNetwork, objFSO, objShellApps
Dim strFromIp, strToIp, strDrive, strPath, strDrvName
Dim colDrives
Dim i

' 初期設定
Set objNetwork = CreateObject( "WScript.Network" )
Set objFSO = CreateObject( "Scripting.FileSystemObject" )
Set objShellApps = CreateObject( "Shell.Application" )

Set colDrives = objNetwork.EnumNetworkDrives
strFromIp = "192.168.1.10"
strToIp = "192.168.1.250"


'-------------------------------------------------------------------------------
' 処理開始
'-------------------------------------------------------------------------------

' 共有ドライブの数だけ処理を行う
For i = 0 to colDrives.Count - 1 Step 2
    ' ドライブレターを取得する
    strDrive = colDrives.Item(i)
    ' ネットワークドライブのアドレス表記をIPアドレス形式に統一する
    strPath = Replace( LCase( colDrives.Item(i+1) ), "share", strFromIp )

    ' ドライブレター存在チェック(念のため)
    If objFSO.DriveExists( strDrive ) Then
        ' ネットワークドライブアドレスに strFromIp が含まれているかチェック
        If InStr( strPath, "\\" & strFromIp & "\" ) > 0 Then
            ' 上記アドレスが含まれていたらネットワークドライブを切断する
            objNetwork.RemoveNetworkDrive strDrive, true, true
            ' 切断後インターバルを置く(念のため)
            WScript.sleep 1000

            ' ドライブ名称をネットワークアドレスから取得する
            strDrvName = Replace( strPath, "\\" & strFromIp & "\", "" )
            ' ドライブのアドレスを置き換える
            strPath = Replace( strPath, strFromIp, strToIp )

            ' 新しいアドレスでネットワークドライブを設定する
            objNetWork.MapNetworkDrive strDrive, strPath, true
            ' ドライブ名称を付け替える
            With objShellApps.NameSpace( strDrive )
                .Items().Item().Name = strDrvName
            End With
        End If
    End If
Next

WScript.Quit(0)

メモメモしてみたけど、こんな特殊な処理、普通は使わないだろうなぁ(苦笑)

スポンサーリンク

この記事をシェア

アカウントをフォロー