見出し画像

VPN接続時ルート自動追加

ユーザー

windows11でvpn接続時に自動的に route add したい

アシスタント

Windows 11でVPN接続時に自動的に特定のルートを追加する方法は、以下のように設定できます。一般的なアプローチとしては、VPN接続のイベントをトリガーにしてルートを追加するスクリプトを実行する方法です。

手順 1: スクリプトを作成する

1. ルート追加用のスクリプトを作成

以下の内容を含む .bat ファイルを作成します。名前は例えば add-vpn-route.bat にします。

@echo off
rem 例: VPN接続時に特定のルートを追加する
route add 198.51.100.0 mask 255.255.255.0 192.0.2.1 metric 1
  • 198.51.100.0 は追加したいネットワークのアドレス

  • 255.255.255.0 はサブネットマスク

  • 192.0.2.1 はゲートウェイアドレス(VPN経由で通信するIPアドレス)

  • metric 1 はルートの優先度

2. 作成した .bat ファイルを任意のフォルダ(例: C:/vpn-route-demo)に保存します。

手順 2: タスクスケジューラでスクリプトを自動実行する

VPN接続時にこのスクリプトが自動で実行されるよう設定します。

  1. タスクスケジューラを開く。スタートメニューで「タスクスケジューラ」を検索して開きます。

  2. 新しいタスクを作成。右側の「タスクの作成」をクリックします。

  3. 一般タブで設定。タスクの名前を設定(例: Add VPN Route)。「最上位の特権で実行する」にチェックを入れます。

  4. トリガータブでトリガーを設定。「新しいトリガー」をクリックし、「イベント」を選択します。ログに Application、ソースに RasClient、イベントIDに 20226 を入力します。

  5. 操作タブでアクションを設定。「新しい操作」をクリックし、「プログラムの開始」を選択します。プログラム/スクリプトに C:/vpn-route-demo/add-vpn-route.bat を入力します。

  6. 「OK」をクリックしてタスクを保存します。

手順 3: 動作確認

1. VPNに接続します。

2. コマンドプロンプトを開き、以下を実行してルートが正しく追加されているか確認します。

route print

追加したルートがリストに表示されていれば成功です。

注意点

ルートを永続的にする場合は、route add コマンドに /p オプションを付けてください。

route -p add 198.51.100.0 mask 255.255.255.0 192.0.2.1 metric 1

ただし、VPN接続時のみ有効なルートを追加したい場合は、このオプションを使用しない方が適切です。

必要に応じて、VPN切断時にルートを削除するタスクも設定可能です(イベントID 20225 をトリガーに設定)。



ユーザー

複数VPN設定があって特定のVPNのみで設定したい場合はどうする?

アシスタント

複数のVPN設定がある場合、特定のVPN接続時のみルートを追加する方法として、以下の手順を利用できます。VPNの名前(プロファイル名)を判別することで対応します。

方法 1: VPNプロファイル名を条件にスクリプトを変更する

1. VPNのプロファイル名を確認

Windowsのコマンドプロンプトで以下を実行して、接続しているVPNの名前を取得します。

rasdial

結果として以下のような出力が得られます(例):

接続名 : myVpn
デバイス : VPN
状態 : 接続中

この場合、「接続名」がVPNプロファイル名です(例: myVpn)。

2. スクリプトを改良する

次に、以下のような条件分岐をスクリプトに追加します。

@echo off
rem VPN接続状態を取得
for /f "tokens=1 delims=:" %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
if "%VPN_NAME%"==" myVpn" (
    rem 特定のVPNに接続している場合のみルートを追加
    route add 198.51.100.0 mask 255.255.255.0 192.0.2.1 metric 1
    echo ルートを追加しました。
) else (
    echo このVPNではルートを追加しません。
)
  • myVpn を、先ほど確認したVPNプロファイル名に置き換えてください。

  • 必要に応じて複数のルートを追加できます。

方法 2: タスクスケジューラでVPNプロファイル名を条件にする

1. イベントログの内容を確認

VPN接続時に生成されるイベントログには、接続したVPNプロファイル名が含まれます。以下の手順で確認します。

  1. イベントビューアを開く。スタートメニューで「イベントビューア」を検索して開きます。

  2. ログを表示する。左側で「Windowsログ > アプリケーション」を選択し、ソースを RasClient に絞り込みます。

  3. VPN接続時のログを確認。イベントID 20226 の詳細を開き、VPNの名前(プロファイル名)が含まれるか確認します。

2. 特定のVPN名に基づいたアクションを設定

タスクスケジューラで「フィルター」の「XMLタブ」を使用して、VPNプロファイル名を条件に加えることができます。

<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">
      *[System[Provider[@Name='RasClient'] and (EventID=20226)]]
      and
      *[EventData[Data[@Name='EntryName']='myVpn']]
    </Select>
  </Query>
</QueryList>

方法 3: PowerShellで高度な制御

PowerShellを使用すると、特定のVPN接続時にルートを追加するスクリプトを作成できます。

$VPNName = "myVpn"
$RouteAdded = $false

while ($true) {
    # VPN接続状態を取得
    $VpnStatus = rasdial | Select-String -Pattern $VPNName
    if ($VpnStatus -and -not $RouteAdded) {
        # ルートを追加
        route add 198.51.100.0 mask 255.255.255.0 192.0.2.1 metric 1
        Write-Host "ルートを追加しました。"
        $RouteAdded = $true
    } elseif (-not $VpnStatus -and $RouteAdded) {
        # VPN切断時にフラグをリセット
        Write-Host "VPNが切断されました。"
        $RouteAdded = $false
    }
    Start-Sleep -Seconds 5
}
  • myVpn を特定のVPNプロファイル名に置き換えます。

  • このスクリプトはループで実行されるため、特定のタイミングで終了させるか、サービスとして登録すると便利です。

これらの方法で、特定のVPN接続時にのみルートを追加できるようになります。どの方法を採用するかは、環境や好みに応じて選んでください!



ユーザー

うまく動かない場合は何をシアべればいい?

アシスタント

スクリプトや設定がうまく動作しない場合、問題の原因を特定するために以下の情報を確認し、共有するとトラブルシューティングが進めやすくなります。

確認すべき情報

1. VPN接続の状態

VPN接続が正常に動作しているか確認します。以下のコマンドで現在のVPN接続状態を取得します。

rasdial

出力にVPNプロファイル名が含まれているか確認してください。期待するVPNの名前が出ない場合、VPN接続そのものに問題がある可能性があります。

2. スクリプトの実行結果

作成したバッチやPowerShellスクリプトを手動で実行してみます。実行時のエラーメッセージや予期しない挙動をメモしてください。

add-vpn-route.bat

メッセージが出ない場合、スクリプトに echo を追加して、進捗や条件判定の結果を表示するようにします。

@echo off
rem VPN接続状態のデバッグ
for /f "tokens=1 delims=:" %%i in ('rasdial') do (
    echo %%i
)
pause

3. ルートの状態

ルートが正しく追加されているか確認します。

route print

必要なルートが見つからない場合、追加するゲートウェイやネットワークアドレス、サブネットマスクが正しいかを見直します。

4. タスクスケジューラの動作

  1. タスクの履歴を有効化しているか確認し、履歴タブでエラーが発生していないか確認する。

  2. スクリプトが管理者権限で実行されるよう設定されているか確認する。

  3. イベントログに期待するVPNプロファイル名やイベントIDが記録されているか確認する。

5. イベントログの内容

  1. イベントビューアを開きます(eventvwr.msc)。

  2. 「Windowsログ > アプリケーション」を選択します。

  3. ソースが RasClient のエントリを探します。

  4. 該当するエントリがない場合、VPN接続が正しく検出されていない可能性があります。

問題が起きた際に提供すべき情報

  1. VPN接続状態。rasdial の結果やVPNが正常に接続されているか。

  2. スクリプトの内容と実行結果。表示されたメッセージやエラー。

  3. 追加されたルートの状態。route print の結果。

  4. タスクスケジューラの設定。一般、トリガー、操作の設定と、実行履歴やエラーコード。

  5. イベントログの内容。イベントIDやプロファイル名が一致しているか。

よくある問題と対処法

問題                         原因                         解決策
ルートが追加されない         VPN名の判定に失敗             rasdialの出力形式と判定処理を確認
スクリプトが動かない         権限不足                     管理者として実行
タスクがトリガーされない     イベントログ条件が一致しない   実際のイベントログを確認
複数VPNで意図しない動作      VPN名の区別が曖昧             VPNプロファイル名を明示

問題解決が難しい場合は、これらの情報をもとにさらに具体的なサポートを提供できます。



ユーザー

下記で動作しない

@echo off
rem VPN接続状態を取得
for /f "tokens=1 delims=:" %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
if "%VPN_NAME%"=="myVpn" (

    echo 対象ツール
    route add 203.0.113.10/32 192.0.2.1

)

アシスタント

このスクリプトで動作しない原因を考えると、以下の点を確認する必要があります。

修正すべき点

1. for ループで環境変数が設定されない

バッチファイルでは変数展開のタイミングに注意が必要です。setlocal enabledelayedexpansion を使って遅延環境変数を有効にします。

2. route add コマンドの書式ミス

CIDR表記(203.0.113.10/32)は route add ではサポートされていません。代わりに mask を使用します。

route add 203.0.113.10 mask 255.255.255.255 192.0.2.1

3. rasdial の出力形式

rasdial コマンドの出力が想定どおりであることを確認します。VPNの名前が myVpn であることを前提にしていますが、実際の名前と一致しているか確認してください。

修正版スクリプト

@echo off
setlocal enabledelayedexpansion

rem VPN接続状態を取得
for /f "tokens=1 delims=:" %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
rem VPN名を確認して処理を実行
if "!VPN_NAME!"==" myVpn" (
    echo 対象ツール
    route add 203.0.113.10 mask 255.255.255.255 192.0.2.1
    echo ルートを追加しました。
) else (
    echo VPN名が一致しません: !VPN_NAME!
)
pause

詳細なポイント

1. 遅延展開の有効化

setlocal enabledelayedexpansion を使用することで、!変数名! の形式で遅延展開が可能になります。

2. VPN名の前後の空白

rasdial の出力には余分な空白が含まれる可能性があります。たとえば myVpn が実際には「 myVpn」で返されることがあります。必要に応じて空白をトリムします。

動作確認方法

  1. rasdial を手動で実行し、VPN名が myVpn になっているか確認する。

  2. バッチファイルを手動で実行する。

  3. route print で 203.0.113.10、255.255.255.255、192.0.2.1 のルートを確認する。

エラーが続く場合

スクリプト内に次を追加してVPN_NAMEの中身を確認します。

echo VPN名: !VPN_NAME!

バッチファイルを管理者として実行してください。route add コマンドは管理者権限が必要です。

ログを取得する例:

add-vpn-route.bat > log.txt 2>&1

これでも動作しない場合は、出力結果やエラー内容を確認します。



ユーザー

文字化けした

アシスタント

文字化けが発生する原因として、スクリプトの文字コードやコマンドプロンプトの文字セットが適切でない可能性があります。以下の解決手順を試してください。

原因と対処方法

1. バッチファイルの文字コード

Windowsのバッチファイルは、通常 Shift-JIS(ANSIコード)で保存する必要があります。ファイルがUTF-8で保存されていると文字化けすることがあります。

メモ帳などで「名前を付けて保存」を選択し、文字コードを ANSI に指定して保存します。Visual Studio Codeの場合は、右下のエンコーディングからShift-JISを選択して再保存します。

2. コマンドプロンプトの文字セット

コマンドプロンプトのコードページがスクリプトと一致していない場合に文字化けが発生します。

chcp 932

現在のコードページを確認する方法:

chcp
  • 932: Shift-JIS(日本語)

  • 65001: UTF-8

3. 出力をファイルに保存して確認

add-vpn-route.bat > output.txt 2>&1

output.txt をテキストエディタで開き、正しい文字コードを確認します。

4. 文字化けの回避

出力に日本語を含めず、英数字のみでメッセージを記述する方法があります。

@echo off
setlocal enabledelayedexpansion

for /f "tokens=1 delims=:" %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
if "!VPN_NAME!"==" myVpn" (
    echo Adding route for target tool.
    route add 203.0.113.10 mask 255.255.255.255 192.0.2.1
    echo Route added successfully.
) else (
    echo VPN name does not match: !VPN_NAME!
)
pause

動作確認後に提供してほしい情報

  1. chcp 実行結果

  2. スクリプトを保存した文字コード

  3. 具体的に文字化けした文字列やエラー内容



ユーザー

VPN名が一致しませんとでる

アシスタント

「VPN名が一致しません」と表示される場合、主に以下の原因が考えられます。

1. rasdial の出力フォーマットが予想と異なる

コマンドプロンプトで rasdial を実行し、出力内容とVPN名を確認します。

rasdial

出力例:

接続名 : myVpn
デバイス : WAN Miniport (IKEv2)
ユーザー名 : example_user
状態 : 接続完了

2. スクリプトのVPN名取得処理を修正

@echo off
setlocal enabledelayedexpansion

rem VPN接続状態を取得し、VPN名を抽出
for /f "tokens=3 delims=: " %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
if "!VPN_NAME!"=="myVpn" (
    echo 対象ツール
    route add 203.0.113.10 mask 255.255.255.255 192.0.2.1
    echo ルートを追加しました。
) else (
    echo VPN名が一致しません: !VPN_NAME!
)
pause

3. VPN名の余分な空白を取り除く

@echo off
setlocal enabledelayedexpansion

for /f "tokens=3 delims=: " %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    for /f "delims= " %%j in ("!VPN_NAME!") do set VPN_NAME=%%j
    goto :check_name
)

:check_name
if "!VPN_NAME!"=="myVpn" (
    echo 対象ツール
    route add 203.0.113.10 mask 255.255.255.255 192.0.2.1
    echo ルートを追加しました。
) else (
    echo VPN名が一致しません: !VPN_NAME!
)
pause

動作確認手順

  1. rasdial を実行してVPNが接続中か確認する。

  2. スクリプトにVPN名のデバッグ表示を追加して、取得値を確認する。

  3. route print で追加されたルートを確認する。

これでも動作しない場合は、rasdial の実際の出力内容と、VPN_NAMEに格納された値を確認します。



ユーザー

PS C:/Users/user> rasdial
次のサーバーに接続しました。
myVpn
コマンドは正常に終了しました。

アシスタント

rasdial の出力を確認すると、VPN名が myVpn として取得されています。ただし、スクリプト内で正しく処理されていない理由として、VPN名が2行目にそのまま表示されているため、スクリプトが正しく2行目を取得する必要があります。

修正版スクリプト

@echo off
setlocal enabledelayedexpansion

rem rasdialの出力から2行目を取得
for /f "skip=1 tokens=*" %%i in ('rasdial') do (
    set "VPN_NAME=%%i"
    goto :check_name
)

:check_name
rem 空白をトリム
for /f "tokens=* delims= " %%j in ("!VPN_NAME!") do set "VPN_NAME=%%j"

rem VPN名を確認して処理を実行
if "!VPN_NAME!"=="myVpn" (
    echo 対象ツール
    route add 203.0.113.10 mask 255.255.255.255 192.0.2.1
    echo ルートを追加しました。
) else (
    echo VPN名が一致しません: !VPN_NAME!
)
pause

スクリプトのポイント

  1. rasdialの出力から2行目を取得する。

  2. 余分な空白を削除する。

  3. 取得したVPN_NAMEが myVpn と一致するか判定する。

デバッグ方法

echo 抽出したVPN名: "!VPN_NAME!"

実行結果の確認

スクリプト実行後、route print で 203.0.113.10、255.255.255.255、192.0.2.1 のルートを確認します。

これでも動作しない場合は、スクリプト実行時の出力と、抽出したVPN名の内容を確認します。



ユーザー

scriptはうまく動いたが、タスクスケジューラがうまく動いていない

VPN接続してもスクリプトが動かない

アシスタント

タスクスケジューラでスクリプトが動作しない原因は、設定や環境の問題である可能性が高いです。以下にタスクスケジューラを正しく動作させるためのチェックポイントと解決方法を示します。

チェックポイントと解決方法

1. タスクスケジューラの「トリガー」設定

VPN接続時にスクリプトを実行する場合、「イベントログ」に基づくトリガーを設定する必要があります。

設定手順:

  1. 新しいタスクを作成。タスクスケジューラを開き、「タスクの作成」を選択します。

  2. 「トリガー」を設定。「新規」をクリックし、「イベントで開始」を選択します。

  3. ログに Microsoft-Windows-NetworkProfile/Operational、ソースに NetworkProfile、イベントIDに10000(接続)または10001(切断)を設定します。

補足: イベントIDは接続に関連する動作で発生しますが、具体的なVPNの接続イベントを調べるために、イベントビューアーで関連ログを確認してください。

2. 「アクション」の設定

スクリプトを実行するアクションを正しく設定します。

  1. 「アクション」タブで「新規」をクリックします。

  2. 「操作を開始する」で「プログラムの開始」を選択します。

  3. プログラム/スクリプトに、バッチファイルのフルパス C:/vpn-route-demo/add-vpn-route.bat を指定します。

  4. 開始(オプション)に、スクリプトが存在するフォルダ C:/vpn-route-demo を指定します。

3. 「全般」の設定

権限と条件を確認してください。

  • 「最上位の特権で実行する」をチェックする。route add などの管理者権限が必要なコマンドを実行するためです。

  • 「ログオンしているかどうかにかかわらず実行する」を選択する。

  • 実行に使用するアカウントが管理者権限を持っているか確認する。

4. タスクが実行されない場合のデバッグ方法

スクリプトの実行結果をログファイルに出力することで、問題を特定します。

@echo off
rem 実行時刻をログに記録
echo [%date% %time%] スクリプト開始 >> C:/vpn-route-demo/vpn-route.log

rem 実行内容の結果を記録
rasdial >> C:/vpn-route-demo/vpn-route.log 2>&1
route add 203.0.113.10 mask 255.255.255.255 192.0.2.1 >> C:/vpn-route-demo/vpn-route.log 2>&1
echo [%date% %time%] スクリプト終了 >> C:/vpn-route-demo/vpn-route.log

C:/vpn-route-demo/vpn-route.log にスクリプトの動作履歴が記録されます。VPN接続時にこのログが生成されるか確認してください。

5. イベントビューアーでのログ確認

  1. Win + X から「イベントビューアー」を選択します。

  2. Windowsログ > システムを開きます。

  3. エラーや警告を確認し、タスクが正常に起動しているかを確認します。

6. スクリプトの手動テスト

タスクスケジューラではなく、手動で以下のコマンドを実行してスクリプトが期待どおり動作するかを確認します。

C:/vpn-route-demo/add-vpn-route.bat
  • スクリプトが正常に動作する場合は、タスクスケジューラの設定に問題があります。

  • スクリプトが動作しない場合は、スクリプト自体に問題がある可能性があります。



まとめ

タスクスケジューラの「トリガー」「アクション」「全般」を正しく設定。

スクリプトの実行ログを記録して動作確認。

イベントビューアーでエラーを確認し、問題を特定。

これでも問題が解決しない場合、タスクスケジューラの設定内容やログ出力を共有いただければ、さらに具体的にサポートします!



いいなと思ったら応援しよう!