特集

年末のPC大掃除を効率化! OS初期化後の環境の再構築を自動化しよう

環境変数、WSL、VPNの設定もスクリプトでやってしまおう

OS初期化後の環境の再構築を自動化しよう

 OSを初期化したあとの環境再構築をスクリプトで自動化する本企画。後編となる今回は、アプリのインストール以外にもよく必要となりそうな処理を、スクリプトで自動化していきたいと思います。

 とはいえ、これ以上バッチファイルを書きたくはないので、本稿からは「PowerShell」を利用していきます。前回作成したバッチファイルとの連携は、最後に説明することにしましょう。

環境変数を編集する

Windows 10の環境変数エディター。かなり改善されたとはいえ、GUIでの編集はやっぱり面倒

 わざわざ「Chocolatery」を使ってアプリをインストールしなくても、ポータブルアプリをオンラインストレージへまとめておけば簡単に元のアプリ環境を復元できます。アップデートが面倒である点を除けば、なかなか便利な方法と言えるでしょう。

 その場合にやっておきたいのが、いわゆる“パスを通す”という作業です。ポータブルアプリのフォルダーを環境変数“PATH”に書き込んでおくことで、フルパスを渡さなくても実行ファイル名だけでアプリを起動できるようになります。

 「PowerShell」で環境変数を書き換えるには、「.NET Framework」のAPIを利用します。たとえば“C:¥PortableApps¥”に保存した「Foo」アプリのフォルダーにパスを通すには、以下のようにします。

$path = [Environment]::GetEnvironmentVariable('PATH', 'Machine')
$path += ';' + 'C:\PortableApps\Foo'
[Environment]::SetEnvironmentVariable('PATH', $path, 'Machine')

 “Machine”を“User”に換えれば、システムの環境変数ではなくユーザーの環境変数を書き換えることができます。

 なお、このスクリプトを実行するには管理者権限が必要です。また、書き換えた環境変数を「PowerShell」へ反映させるには、「PowerShell」を再起動させる必要があります。

シンボリックリンクを張る

 最近のWindowsでは、[Windows]+[PrintScreen]キーでデスクトップをキャプチャーし、“C:¥Users¥(ユーザー名)¥Pictures¥Screenshots”フォルダーにファイルとして保存できます。筆者の場合、これを「OneDrive」でクロスデバイス共有しておきたいので、“Screenshots”フォルダーを“OneDrive¥Screenshots”フォルダーへのシンボリックに置き換えています。こうすれば、[Windows]+[PrintScreen]キーで保存されたスクリーンショットが「OneDrive」で同期されます。

Set-Location "$Home\Pictures"
Remove-Item "Screenshots"
New-Item -Type SymbolicLink -Path "Screenshots" -Value "$Home\OneDrive\Screenshots"

 なお、このスクリプトを実行するには管理者権限が必要です。

 コマンドレットの名前が“***-Folder”ではなく“***-Item”となっているのは、フォルダー・ファイル以外にもレジストリなどを総合的に扱えるからのようですね。慣れればセットアップスクリプトで任意のフォルダー・ファイルを作成したり、リンクを張ったり、自分の使いやすいようにフォルダー構造を変更できます。

Windows 10の機能を有効化する

[Windows の機能]ダイアログ(Windows の機能の有効化または無効化)

 Windows 10で特定の機能――たとえば、「Hyper-V」や「WSL」――を有効化するには、通常[Windows の機能]ダイアログ(Windows の機能の有効化または無効化)を使いますが、これもスクリプトで行えます。

 たとえば、「WSL」の場合は以下の通りです。

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

 機能の名前(FeatureName)や現在の状態(有効・無効)を調べたい場合は、“Get-WindowsOptionalFeature -Online”を使います。

 なお、このスクリプトを実行するには管理者権限が必要です。また、OSの再起動が必要になることがあるので、セットアップスクリプトの最後の方に記述し、完了後は一旦再起動するようにした方がよいでしょう。

「WSL」をスクリプトでセットアップする

 前項で「WSL」をスクリプトで有効化する方法を紹介しましたが、WSL/Linuxディストリビューションのインストールもスクリプトで行えます。

 たとえば、「Ubuntu 16.04」の場合は以下の通り。現行のWindows 10では「curl」がサポートされていますので、「curl」でアプリパッケージ(*.appx)をダウンロードし、“Add-AppxPackage”コマンドレットでシステムに追加します。

curl.exe -L -o ubuntu-1604.appx https://aka.ms/wsl-ubuntu-1604
Add-AppxPackage .\ubuntu-1604.appx

 ちなみに、現在サポートされているディストリビューションとその取得先は以下の通りです。

  • Ubuntu 18.04:https://aka.ms/wsl-ubuntu-1804
  • Ubuntu 18.04 ARM:https://aka.ms/wsl-ubuntu-1804-arm
  • Ubuntu 16.04:https://aka.ms/wsl-ubuntu-1604
  • Debian GNU/Linux:https://aka.ms/wsl-debian-gnulinux
  • OpenSUSE Leap 42:https://aka.ms/wsl-opensuse-42
  • SUSE Linux Enterprise Server 12:https://aka.ms/wsl-sles-12
  • Fedora Remix for WSL:https://github.com/WhitewaterFoundry/WSLFedoraRemix/releases/

 適宜URLを置き換えて、試してみてください。カスタマイズしたディストリビューションを利用したい場合は、MicrosoftのScott Hanselman氏が直伝するインポート・エクスポート方法が参考になるでしょう。

VPNをセットアップする

 会社によっては、リモート勤務のためにVPNをセットアップしなければならないことがあるかもしれません。これもGUIで行うよりも、「PowerShell」スクリプトで行った方が手軽でしょう(キーやURL、認証方式などは環境に合わせて変更してください)。

$PreKey = "***"

$VpnUrl = "***"
$VpnName = "テスト"

Add-VpnConnection -Name $VpnName `
                  -ServerAddress $VpnUrl `
                  -RememberCredential -L2tpPsk $PreKey `
                  -AuthenticationMethod Chap,MSChapv2 `
                  -EncryptionLevel Maximum `
                  -TunnelType L2tp `
                  -Force

 ユーザー名とパスワードまでは登録できないのが残念ですが、平文でスクリプトに書いておくべきものでもないので仕方ないですね。

まとめ

 以上、環境の再構築時によく行いそうなセットアップ処理をいくつかピックアップして紹介してみました。これをPowerShellスクリプト(“Setup.ps1”など)にまとめておけば、次回からは環境構築の手間を大幅に省くことができるでしょう。前編で作成した(管理者権限で起動済みの)バッチファイルからキックする(バッチファイルを呼び出す)ようにしておけば、管理者権限でスクリプトを実行するのを忘れることもありません。

@REM セキュリティを一時的に緩める
powershell Set-ExecutionPolicy RemoteSigned

@REM 「Chocolatey」をインストール
powershell iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

@REM 他のセットアップ処理を記述したPSスクリプトをキック(アプリのインストールもここでやるとよいでしょう)
powershell "%~dp0setup.ps1"

@REM セキュリティ設定を元に戻す
powershell Set-ExecutionPolicy Restricted

@ECHO "すべての処理が完了しました。"

PAUSE

 なお、今回示したのはサンプルに過ぎません。エラーを十分に考慮していなかったり、もっとよい方法もあるでしょう。もし公開しても差し支えのないものでしたら、“GitHub”などで共有していただけると、他のユーザーの助けにもなると思います。

 それでは、よいお年を。