やりたいこと
- オフライン環境のWindows11数十台に複数のアプリを一括インストールしたい
- このとき可能な限り手作業は減らしたい
- サイレントインストールで行いたい
- 必要なオプション等を可能な限り自動で取得したい
オンラインでインストールできる場合
例として次の10種のアプリをインストールするとき、オンライン環境ならばパッケージマネージャ「winget」を用いて、以下のように winget install
のコマンドで一括インストールできる。
winget install --silent --scope machine --id Google.JapaneseIME
winget install --silent --scope machine --id Google.Chrome
winget install --silent --scope machine --id 7zip.7zip
winget install --silent --scope machine --id voidtools.Everything
winget install --silent --scope machine --id Adobe.Acrobat.Reader.64-bit
winget install --silent --scope machine --id PDFsam.PDFsam
winget install --silent --id TrackerSoftware.PDF-XChangeEditor
winget install --silent --scope machine --id Microsoft.VisualStudioCode
winget install --silent --id DuongDieuPhap.ImageGlass
winget install --silent --scope machine --id VideoLAN.VLC
方針
- オンライン環境でWindowsのパッケージマネージャ「winget」を用いて、インストーラおよびマニフェストをダウンロード
- ダウンロードしたインストーラおよびマニフェストをインストール対象にコピー
- マニフェストから必要なオプションを抽出してインストールコマンドを出力
- 出力したインストールコマンドを必要に応じて微調整してから実行
wingetでインストーラをダウンロードする
wingetのdownloadコマンドでインストーラおよびマニフェストをダウンロードする。デフォルトでは [ダウンロード] フォルダへアプリ名のフォルダ単位で保存される。
なお、依存関係あるものもサブフォルダに自動的にダウンロードされる。
このときに、ダウンロードするパソコンとインストールするパソコンについてプラットフォームやアーキテクチャ等が異なる場合には、インストールするパソコンに合わせた --platform
や --architecture
のオプションを指定することで最適なインストーラをダウンロードできる。細かいオプションについては公式サイトを参照。
winget download --scope machine --id Google.JapaneseIME
winget download --scope machine --id Google.Chrome
winget download --scope machine --id 7zip.7zip
winget download --scope machine --id voidtools.Everything
winget download --scope machine --id Adobe.Acrobat.Reader.64-bit
winget download --scope machine --id PDFsam.PDFsam
winget download --id TrackerSoftware.PDF-XChangeEditor
winget download --scope machine --id Microsoft.VisualStudioCode
winget download --id DuongDieuPhap.ImageGlass
winget download --scope machine --id VideoLAN.VLC
ダウンロードしたものをインストール対象にコピーする
ダウンロードしたインストーラおよびマニフェストをフォルダごとインストール対象のパソコンにコピーする。
今回は例として、インストール対象にAdministratorでログインして、[デスクトップ] > [installer] に各種フォルダをコピーすることとする。
C: Users/Administrator/Desktop/installer/
├ 7zip.7zip_24.09/
│ ├ 7-Zip_24.09_Machine_X64_exe_en-US.exe
│ └ 7-Zip_24.09_Machine_X64_exe_en-US.yaml
├ Adobe.Acrobat.Reader.64-bit_24.005.20421/
│ ├ Adobe Acrobat Reader (64-bit)_24.005.20421_Machine_X64_exe_en-US.exe
│ └ Adobe Acrobat Reader (64-bit)_24.005.20421_Machine_X64_exe_en-US.yaml
├ DuongDieuPhap.ImageGlass_9.2.0.1208/
│ ├ Dependencies/
│ │ ├ Microsoft .NET Windows Desktop Runtime 8.0_8.0.13_X64_burn_en-US.exe
│ │ └ Microsoft .NET Windows Desktop Runtime 8.0_8.0.13_X64_burn_en-US.yaml
│ ├ ImageGlass_9.2.0.1208_X64_msi_en-US.msi
│ └ ImageGlass_9.2.0.1208_X64_msi_en-US.yaml
├ Google.Chrome_133.0.6943.142/
│ ├ Google Chrome_133.0.6943.142_Machine_X64_wix_en-US.msi
│ └ Google Chrome_133.0.6943.142_Machine_X64_wix_en-US.yaml
├ Google.JapaneseIME_2.30.5620.0/
│ ├ Google 日本語入力_2.30.5620.0_Machine_X64_wix_en-US.msi
│ └ Google 日本語入力_2.30.5620.0_Machine_X64_wix_en-US.yaml
├ Microsoft.VisualStudioCode_1.97.2/
│ ├ Microsoft Visual Studio Code_1.97.2_Machine_X64_inno_en-US.exe
│ └ Microsoft Visual Studio Code_1.97.2_Machine_X64_inno_en-US.yaml
├ PDFsam.PDFsam_5.3.0/
│ ├ PDFsam Basic_5.3.0_Machine_X64_wix_en-US.msi
│ └ PDFsam Basic_5.3.0_Machine_X64_wix_en-US.yaml
├ TrackerSoftware.PDF-XChangeEditor_10.5.2.395/
│ ├ PDF-XChange Editor_10.5.2.395_X64_wix_en-US.msi
│ └ PDF-XChange Editor_10.5.2.395_X64_wix_en-US.yaml
├ VideoLAN.VLC_3.0.21/
│ ├ VLC media player_3.0.21_Machine_X64_nullsoft_en-US.exe
│ └ VLC media player_3.0.21_Machine_X64_nullsoft_en-US.yaml
├ voidtools.Everything_1.4.1.1026/
│ ├ Everything_1.4.1.1026_Machine_X64_wix_en-US.msi
│ └ Everything_1.4.1.1026_Machine_X64_wix_en-US.yaml
└ builder.ps1
一括インストール用のスクリプトをビルドする
インストーラをそのまま実行すると対話形式でインストールが開始されてしまうためサイレントインストールのオプションを指定する。このとき、YAML形式で記述されたマニフェストファイルに、サイレントインストールのオプションが「Silent」キーにマッピングされているためこれを利用した。同じく、各アプリに応じて必要なオプションは「Custom」キーにマッピングされているためこちらも利用した。
また、.exeや.msiの実行コマンドを並べただけだと、他のインストールプロセスの終了を待たずに同時実行するため、Start-Process
を用いて-Wait -NoNewWindow -PassThru
のオプションを指定することで、インストールを逐次実行するようにした。
$installerName = "installer.ps1"
# インストール順序をディレクトリ名の降順にすることで、サブディレクトリに保存されている依存関係のあるものを先にインストールしている
$f = ((Get-ChildItem * -Recurse | Where-Object { $_.PSIsContainer }).fullname | Sort-Object -Descending)
(Write-Output "# This installer was generated on ") + (Get-date -f "[yyyy/MM/dd HH:mm:ss.ff]") > $installerName
for ($i=0; $i -lt $f.length; $i++){
Write-Output ("Write-Output {0}" -f $f[$i]) >> $installerName
$installerPath = $f[$i] + "\" + (Get-ChildItem $f[$i] -include *.msi,*.exe -Name)
$installerPath = "`"" + (Convert-Path $installerPath) + "`""
$installerArgv = ((Get-Content (Get-ChildItem $f[$i]*.yaml).fullname) -like "*Silent:*").split(":")[1]
$installerArgv = $installerArgv + ("$i" + ((Get-Content (Get-ChildItem $f[$i]*.yaml).fullname) -like '*Custom:*')).split(":")[1]
$isExe = (Get-ChildItem $f[$i] -include *.exe -Name)
if($isExe){
$installerArgv = "`"" + $installerArgv + "`""
Write-Output "Start-Process -FilePath $installerPath -ArgumentList $installerArgv -Wait -NoNewWindow -PassThru" >> $installerName
}else{
$installerPath = "`'/i " + $installerPath + $installerArgv + "`'"
Write-Output "Start-Process -FilePath msiexec -ArgumentList $installerPath -Wait -NoNewWindow -PassThru" >> $installerName
}
}
cd C:\Users\Administrator\Desktop\installer
.\2_builder.ps1
一括インストールを実行
生成した一括インストール用スクリプトについて、マニフェストから取得できないオプション等を指定する場合には手動で書き換えてから実行する。
# This installer was generated on [2025/03/02 01:02:14.68]
Write-Output C:\Users\Administrator\Desktop\installer\voidtools.Everything_1.4.1.1026
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\voidtools.Everything_1.4.1.1026\Everything_1.4.1.1026_Machine_X64_wix_en-US.msi" /quiet /norestart' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\VideoLAN.VLC_3.0.21
Start-Process -FilePath "C:\Users\Administrator\Desktop\installer\VideoLAN.VLC_3.0.21\VLC media player_3.0.21_Machine_X64_nullsoft_en-US.exe" -ArgumentList " /S" -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\TrackerSoftware.PDF-XChangeEditor_10.5.2.395
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\TrackerSoftware.PDF-XChangeEditor_10.5.2.395\PDF-XChange Editor_10.5.2.395_X64_wix_en-US.msi" /quiet /norestart' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\PDFsam.PDFsam_5.3.0
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\PDFsam.PDFsam_5.3.0\PDFsam Basic_5.3.0_Machine_X64_wix_en-US.msi" /qn SKIPTHANKSPAGE=Yes' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\Microsoft.VisualStudioCode_1.97.2
Start-Process -FilePath "C:\Users\Administrator\Desktop\installer\Microsoft.VisualStudioCode_1.97.2\Microsoft Visual Studio Code_1.97.2_Machine_X64_inno_en-US.exe" -ArgumentList " /SP- /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /mergetasks=!runcode" -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\Google.JapaneseIME_2.30.5620.0
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\Google.JapaneseIME_2.30.5620.0\Google 日本語入力_2.30.5620.0_Machine_X64_wix_en-US.msi" /quiet /norestart' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\Google.Chrome_133.0.6943.142
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\Google.Chrome_133.0.6943.142\Google Chrome_133.0.6943.142_Machine_X64_wix_en-US.msi" /quiet /norestart' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\DuongDieuPhap.ImageGlass_9.2.0.1208\Dependencies
Start-Process -FilePath "C:\Users\Administrator\Desktop\installer\DuongDieuPhap.ImageGlass_9.2.0.1208\Dependencies\Microsoft .NET Windows Desktop Runtime 8.0_8.0.13_X64_burn_en-US.exe" -ArgumentList " /quiet /norestart" -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\DuongDieuPhap.ImageGlass_9.2.0.1208
Start-Process -FilePath msiexec -ArgumentList '/i "C:\Users\Administrator\Desktop\installer\DuongDieuPhap.ImageGlass_9.2.0.1208\ImageGlass_9.2.0.1208_X64_msi_en-US.msi" /quiet /norestart' -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\Adobe.Acrobat.Reader.64-bit_24.005.20421
Start-Process -FilePath "C:\Users\Administrator\Desktop\installer\Adobe.Acrobat.Reader.64-bit_24.005.20421\Adobe Acrobat Reader (64-bit)_24.005.20421_Machine_X64_exe_en-US.exe" -ArgumentList " -sfx_nu /sAll /rs /msi" -Wait -NoNewWindow -PassThru
Write-Output C:\Users\Administrator\Desktop\installer\7zip.7zip_24.09
Start-Process -FilePath "C:\Users\Administrator\Desktop\installer\7zip.7zip_24.09\7-Zip_24.09_Machine_X64_exe_en-US.exe" -ArgumentList " /S" -Wait -NoNewWindow -PassThru
cd C:\Users\Administrator\Desktop\installer
.\installer.ps1
所感
今回、実際の作業では数十台のクリーンインストールされたwindoswに30種類近くのアプリのインストールを求められた。作業環境は10mbps程度の回線速度が確保できず、wingetで一括インストールを行うと非常に時間がかかりタイムアウトするケースもあったためオフラインインストールで行った。wingetの本来の使い方ではないが、こういった使い方はある程度需要があるかと思い記録に残してみた。
同じような境遇で苦労されている方がいましたら、ぜひ参考にしてみてください。