【仕事の効率が 0.01 % 上がる！】リモートワークのときだけ自動で VPN に接続してくれるスクリプト

コロナ禍でリモートワークが広まりましたが、最近では在宅と出社のハイブリッド体制となっているところも多いようです。
中では在宅勤務で VPN への接続が必要になることもあるかと思います。

VPN につないで在宅勤務していた方の中で、出社した際は VPN につなぐ必要がないのにうっかり VPN に接続してしまい、その分の時間を無駄にしてしまった方もいらっしゃるのではないでしょうか。

今回はそんな時間の無駄を削減するために私が普段使っているスクリプトをご紹介します。

## 条件

今回は次のような条件を仮定します。

- リモートワークで自宅等の場所で作業するときは、 VPN に接続する必要がある
- VPN はサーバ名または IP アドレスで設定し、ユーザー名とパスワードで接続する
- 会社の Wi-Fi に接続している (IP アドレスが指定した値と一致する) ときは VPN に接続する必要がない
- たまに出社したとき、自宅にいるときと同じノリで VPN に接続しようとしてしまう

作業環境は以下の通りとなります。

- Windows
- PowerShell

また、これから説明する手順を実際にやってみる場合、~~作業中は同じ Wi-Fi をご利用ください~~リモートワーク環境下で実施するとスムーズです。

## このようなものを作ります

```powershell:vpn-connect.ps1
$officeIp = 'xxx.yyy.zzz.www'
$vpnName = 'vpn name'
$username = 'vpn username'

$resp = Invoke-WebRequest -Uri https://api.ipify.org?format=json | ConvertFrom-Json
if ($resp.ip -eq $officeIp) {
    echo 'You are at office!'
    exit 0
}

echo 'You are at home! Trying to connect to the vpn...'
rasdial $vpnName $username
exit 0
```

## VPN に接続する

### VPN 接続先を設定する

Windows の「設定」を開き、「ネットワークとインターネット」→「VPN」から「VPN を追加」をクリックして VPN の設定を行ってください。

:::note info
ここでは VPN の接続をスクリプト化するので、「サインイン情報を保存する」にチェックを入れて設定します。
:::

PowerShell で直接設定することも可能です。

以下は PowerShell で事前共有キーを使った L2TP に対応する VPN を登録する例です。

```powershell
Add-VpnConnection -Name "sample" -ServerAddress "example.com" -TunnelType L2tp -L2tpPsk some_psk -RememberCredential -PassThru
```

https://docs.microsoft.com/en-us/powershell/module/vpnclient/add-vpnconnection?view=windowsserver2022-ps

### VPN に接続する

PowerShell で rasdial コマンドを使って接続してみます。

```powershell
rasdial sample username
```

ユーザ名とパスワードをあらかじめ保存している場合は `rasdial ${VPN 名} ${ユーザ名}` となります。保存していない場合は `rasdial ${VPN 名} ${ユーザ名} *` と入力し、その後パスワードを入力します。

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/ff859533(v=ws.11)

以下のようになれば接続できています。

```text
sample に接続中...
ユーザー名とパスワードを確認中...
ネットワークにコンピューターを登録中...
sample に正常に接続しました。
コマンドは正常に終了しました。
```

### 切断する

VPN から切断するには `rasdial ${VPN 名} /DISCONNECT` を実行します。

```powershell
rasdial sample /DISCONNECT
```

```text
コマンドは正常に終了しました。
```

### 接続情報を削除する

もし、接続情報を削除する場合は、設定画面から削除するか `Remove-VpnConnvection` コマンドを使用します。

```powershell
Remove-VpnConnvection sample
```

```text
確認
Deleting VPN connection sample2. Do you want to continue?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):
```

## 自分の IP を調べる

スクリプトに組み込みますので、 API の形で利用できるものがおすすめです。
今回は [ipify](https://www.ipify.org/) というサービスを採用します。

### IP を調べる

次のコマンドで IP を調べることが可能です。
JSON 形式で取得し、パースまでをまとめてやってしまいます。

```powershell
Invoke-WebRequest -Uri https://api.ipify.org?format=json | ConvertFrom-Json
```

出力例

```text
ip
--
xxx.yyy.zzz.www
```

### IP が特定の値の場合に処理する

条件分岐を使って処理をします。
拡張子が `ps1` であるようなファイルを作成し、次のように記述します。
`xxx.yyy.zzz.www` の部分は先ほど出力された IP に置き換えてください。

```powershell:sample.ps1
$resp = Invoke-WebRequest -Uri https://api.ipify.org?format=json | ConvertFrom-Json
if ($resp.ip -eq 'xxx.yyy.zzz.www') {
    echo 'You are at office!'
}
```

`.\sample.ps1` で実行して `You are at office!` と表示されれば成功です。

## スクリプトを作成する

スクリプトを作成します。あらかじめ変数の値を書き換えてください。

- `$officeIp`: オフィスの IP
- `$vpnName`: VPN の接続名
- `$username`: VPN に接続するユーザ名

```powershell:vpn-connect.ps1
$officeIp = 'xxx.yyy.zzz.www'
$vpnName = 'vpn name'
$username = 'vpn username'

$resp = Invoke-WebRequest -Uri https://api.ipify.org?format=json | ConvertFrom-Json
if ($resp.ip -eq $officeIp) {
    echo 'You are at office!'
    exit 0
}

echo 'You are at home! Trying to connect to the vpn...'
rasdial $vpnName $username
exit 0
```

ファイルができたら、以下のコマンドで実行します。

```powershell
.\vpn-connect.ps1
```

以下のような出力がされれば成功です。

```text
PS C:\Users\user> .\vpn-connect.ps1
You are at home! Trying to connect to the vpn...
sample に接続中...
ユーザー名とパスワードを確認中...
ネットワークにコンピューターを登録中...
sample に正常に接続しました。
コマンドは正常に終了しました。
```

もしスクリプトが実行できない場合、以下の記事で PowerShell スクリプトの実行ポリシーをご確認ください。

https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750

## コマンドプロンプト経由で実行するように設定する

上記ファイルを PowerShell で起動するように設定しても、パスの関係でうまくいかない場合がありますので、コマンドプロンプト経由でファイルを呼び出すようにしておきます。

```cmd:vpn-connect.cmd
powershell .\vpn-connect.ps1
```

あとは、このファイルをスタートアップのフォルダに入れて、次回起動時にちゃんと動くか確認するだけです。
仕事が始まるのが楽しみですね！わくわく🥰

## 所感

PowerShell に慣れてないので、スクリプトを書くのが大変でした。
でも書き始めると意外と便利だなと思ったので、これからも PowerShell をたまに使っていきたいです。