wingetコマンドでChromeなどのソフト・アプリをインストールする方法(対話式のPowerShell関数も紹介)
新しいWindows OSでセットアップする時にわざわざ手作業でダウンロードやインストールする作業、面倒じゃないですか?
PowerShellでwinget
コマンドを使えば自動でインストールが可能です。
Windows初期状態で導入する機会も多いブラウザ「Google Chrome」を対象に手順を紹介します。
シナリオ・検証環境
買いたてホヤホヤのWindows OSのパソコン。コマンドで Microsoft Edgeをアンインストール(👈仕様により不可でした) してから Google Chromeをインストール しちゃおう!
なぜMicrosoft Edgeをアンインストールできないのか? | Microsoft公式
検証環境の一覧 < ここをクリックすると折りたたみが開く >
PS C:\Users\XXXX> Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber | Format-Table -AutoSize
Caption Version BuildNumber
------- ------- -----------
Microsoft Windows 10 Pro 10.0.19045 19045
PS C:\Users\XXXX>
PS C:\Users\XXXX> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.5486
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.5486
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\Users\XXXX>
対応方法
wingetコマンドでソフトウェア・アプリをインストール
winget install --id "対象ソフトウェアのID(winget上のID)"
実際に“Google Chrome(ID:Google.Chrome)”をインストールしてみます。
はじめてwingetコマンドを使用する場合は同意を求められます。
これは、はじめてwingetコマンドを実行した時に表示される同意を求めるメッセージ。
これに対して「y」でEnterキーを押すことで同意と見なされます。
同意した後は、問題なくwingetの検索コマンドが機能し結果が表示されました。
PS C:\Users\XXXX> winget search -q "google chrome"
'msstore' ソースでは、使用する前に次の契約を表示する必要があります。
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
ソースが正常に機能するには、現在のマシンの 2 文字の地理的リージョンをバックエンド サービスに送信する必要があります (例: "US")。
すべてのソース契約条件に同意しますか?
[Y] はい [N] いいえ: y
名前 ID バージョン 一致 ソース
-----------------------------------------------------------------------------------------------
Google Chrome (EXE) Google.Chrome.EXE 134.0.6998.89 ProductCode: google chrome winget
Google Chrome Google.Chrome 134.0.6998.89 winget
Google Chrome Beta Google.Chrome.Beta 135.0.7049.17 winget
Google Chrome Beta (EXE) Google.Chrome.Beta.EXE 135.0.7049.17 winget
Google Chrome Canary Google.Chrome.Canary 136.0.7075.0 winget
Google Chrome Dev Google.Chrome.Dev 136.0.7064.0 winget
Google Chrome Dev (EXE) Google.Chrome.Dev.EXE 136.0.7064.0 winget
PS C:\Users\XXXX>
PS C:\Users\XXXX> winget install --id "google.chrome"
見つかりました Google Chrome [Google.Chrome] バージョン 134.0.6998.89
このアプリケーションは所有者からライセンス供与されます。
Microsoft はサードパーティのパッケージに対して責任を負わず、ライセンスも付与しません。
ダウンロード中 https://dl.google.com/dl/chrome/install/googlechromestandaloneenterprise64.msi
██████████████████████████████ 125 MB / 125 MB
インストーラーハッシュが正常に検証されました
パッケージのインストールを開始しています...
インストーラーは管理者として実行するように要求するため、プロンプトが表示されます。
インストールが完了しました
PS C:\Users\XXXX>
これで無事インストール完了です。
(切り戻し手順)wingetコマンドでソフトウェア・アプリをアンインストール
下記はアンインストールコマンドです。
もともと今回の記事でMicrosoft Edgeを消すこともテーマにしようとしていましたが、いつの間にかWindows OSの仕様でMicrosoft Edgeがアンインストールできなくなっていました。
前述で紹介したとおり、Windows OSでは動作を保証する為に最低限入れておくべきソフトウェアがあるとのこと。
そのソフトウェアの中にMicrosoft Edgeが含まれていて、GUIのマウス操作でもCLI操作でもアンインストールができなくなったということのようです。
Microsoft Edgeをアンインストールしようとwingetコマンドを実行するとエラーが発生
PS C:\Users\XXXX> winget uninstall --id "microsoft.edge"
見つかりました Microsoft Edge [Microsoft.Edge]
パッケージのアンインストールを開始しています...
アンインストールは次の終了コードで失敗しました: 93
PS C:\Users\XXXX>
winget uninstall --id "対象ソフトウェアのID(winget上のID)"
PS C:\Users\XXXX> winget uninstall --id "google.chrome"
見つかりました Google Chrome [Google.Chrome]
パッケージのアンインストールを開始しています...
正常にアンインストールされました
PS C:\Users\XXXX>
wingetコマンドでソフトウェア・アプリのIDを検索する方法
winget search -q "google chrome"
PS C:\WINDOWS\system32> winget search -q "google chrome"
名前 ID バージョン 一致 ソース
-----------------------------------------------------------------------------------------------
Google Chrome (EXE) Google.Chrome.EXE 134.0.6998.89 ProductCode: google chrome winget
Google Chrome Google.Chrome 134.0.6998.89 winget
Google Chrome Beta Google.Chrome.Beta 135.0.7049.17 winget
Google Chrome Beta (EXE) Google.Chrome.Beta.EXE 135.0.7049.17 winget
Google Chrome Canary Google.Chrome.Canary 136.0.7075.0 winget
Google Chrome Dev Google.Chrome.Dev 136.0.7064.0 winget
Google Chrome Dev (EXE) Google.Chrome.Dev.EXE 136.0.7064.0 winget
PS C:\WINDOWS\system32>
補足情報:既定のブラウザの変更は仕様上できませんでした
前述したとおり、Microsoft Edgeのアンインストールが仕様上できませんでした。
そこで既定のブラウザをコマンドで変更できないか検討するも断念しました。
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\URLAssociations\http\UserChoice" -Name ProgId -Value "ChromeHTML"
上記のコマンドレットでレジストリに登録している既定の「MSEdgeHTM
」を「ChromeHTML
」に変更しょうとしました。
結果、管理者ユーザーでもUserChoice配下のアクセスを拒否されてしまい既定のブラウザ変更も不可という結論に。
ここだけGUI操作になってしまいますが、「Winキー + R」で開く“ファイル名を指定して実行”の名前(O)
欄に「ms-settings:defaultapps
」を入力しEnterを押すことで既定のアプリが開きます。
ms-settings:defaultapps
応用技術:パッケージを検索してインストールできるFunction
Windows PowerShell ウィンドウに貼り付けて実行するだけで、名前もしくはIDでパッケージを検索しIDとバージョンを指定することで、
インストールできるFunctionを作りました。
下記が実際に動かしている画面です。
Function Install-WingetPackage {
param (
[Parameter(Mandatory = $false)]
[string]$PackageId, # インストール対象のパッケージ ID(任意)
[Parameter(Mandatory = $false)]
[string]$Version, # 指定があればそのバージョンをインストール
[Parameter(Mandatory = $false)]
[string]$Source = "winget" # 指定があればソースも選択
)
$statusCode = 0
# コンソールのエンコーディングをUTF-8に設定
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# パッケージ ID が指定されていない場合、パッケージリストを取得
if (-Not $PackageId) {
Write-Host ""
Write-Host "> 利用可能なパッケージのリストを取得中..." -ForegroundColor Yellow
Write-Host ""
Write-Host "> Wingetパッケージで検索する名前もしくはIDを入力しEnterキーを押してください。(例: chrome)"
$query = Read-Host
$wingetListOutput = (winget search -q $query | Out-String)
if (-Not $wingetListOutput) {
Write-Error "wingetコマンドが実行できないか、指定された条件でデータを取得できませんでした。"
$statusCode = -11
return $statusCode
}
# パッケージリストを整形して表示
$lines = ($wingetListOutput -split "`r?`n")
# 名前やID、バージョンなどの情報があるデータと区切り線のみを抜粋
$availablePackages = $lines | Where-Object { $_ -match "^\S+\s+\S+" -or $_ -match "^-{2,}" }
if (-Not $availablePackages) {
Write-Error "> 利用可能なデータが見つかりませんでした。条件を見直して再試行してください。"
$statusCode = -12
return $statusCode
}
Write-Host ""
Write-Host "> 取得したパッケージ情報の一覧を表示します。:" -ForegroundColor Green
$availablePackages | ForEach-Object { Write-Host $_ }
# ユーザーに ID を入力させる
Write-Host ""
Write-Host "> インストールするパッケージの「ID」を入力しEnterキーを押してください。(例: google.chrome)"
$selectedId = Read-Host
if (-Not $selectedId) {
Write-Error "未入力です。処理を終了します。"
$statusCode = -13
return $statusCode
}
}
else {
$selectedId = $PackageId
}
# 選択されたパッケージのバージョンを確認
Write-Host ""
Write-Host "> 利用可能なバージョンを確認中($selectedId)..." -ForegroundColor Yellow
$wingetOutput = (winget show --id $selectedId --versions | Out-String)
if (-Not $wingetOutput) {
Write-Error "パッケージ '$selectedId' が見つかりませんでした。"
$statusCode = -21
return $statusCode
}
# バージョン情報のみを抽出し一覧を作成
$lines = ($wingetOutput -split "`r?`n")
$availableVersions = ($lines -replace "\s+", "" | Where-Object { $_ -ne "" -and $_ -match "^\d" } | Sort-Object)
if (-Not $availableVersions) {
Write-Error "パッケージ '$selectedId' のバージョン情報を取得できませんでした。"
$statusCode = -22
return $statusCode
}
Write-Host ""
Write-Host "> 取得したバージョン情報の一覧を表示します。:" -ForegroundColor Green
($availableVersions | ForEach-Object { Write-Host $_ })
if (-Not $Version) {
# ユーザーにバージョンを入力させる(空の場合は最新版を使用)
Write-Host ""
Write-Host "> インストールするバージョンを入力しEnterキーを押してください。(未入力の場合は最新バージョンを選択)"
$selectedVersion = Read-Host
# バージョンが未指定の場合、最新版を選択
if (-Not $selectedVersion) {
$selectedVersion = $availableVersions[-1]
Write-Host ""
Write-Host "> 最新版 '$selectedVersion' をインストールします。" -ForegroundColor Yellow
}
}
else {
$selectedVersion = $Version
}
if (-Not ($availableVersions -contains $selectedVersion)) {
Write-Error "指定されたバージョン '$selectedVersion' は一覧にありません。"
$statusCode = -23
return $statusCode
}
Write-Host ""
Write-Host "> $selectedId のバージョン $selectedVersion のダウンロードとインストールを開始します..." -ForegroundColor Green
# 標準出力を破棄してインストール処理を実行
(winget install --id $selectedId --version $selectedVersion --source $Source --silent | Out-Null)
$wingetExitcode = $LASTEXITCODE
if ($wingetExitcode -eq 0) {
Write-Host "> $selectedId バージョン $selectedVersion のインストールが完了しました。" -ForegroundColor Green
} else {
Write-Error "インストール中にエラーが発生しました。winget 終了コード: $wingetExitcode"
$statusCode = -24
return $statusCode
}
return $statusCode
}
# Functionの実行
Install-WingetPackage
このFunctionは、基本的に対話型を目的 としています。
下記のように引数を指定するとすべて自動で処理が進みますが、このように引数をすべて指定するのであれば winget
コマンドを直接使った方が手っ取り早いでしょう。
Install-WingetPackage -PackageId "microsoft.powershell" -Version "7.5.0.0"
このFunctionで唯一、優位性があるのは「文字コードをUTF-8
で指定」しているぐらいでしょうが、作業者の方が毎回すべて引数を指定するのであれば冗長的な関数になってしまいます。利用される際はご注意ください。
“パッケージを検索してインストールできるFunction”のソース部分のみ抜粋
Function Install-WingetPackage {
param (
[Parameter(Mandatory = $false)]
[string]$PackageId, # インストール対象のパッケージ ID(任意)
[Parameter(Mandatory = $false)]
[string]$Version, # 指定があればそのバージョンをインストール
[Parameter(Mandatory = $false)]
[string]$Source = "winget" # 指定があればソースも選択
)
$statusCode = 0
# コンソールのエンコーディングをUTF-8に設定
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# パッケージ ID が指定されていない場合、パッケージリストを取得
if (-Not $PackageId) {
Write-Host ""
Write-Host "> 利用可能なパッケージのリストを取得中..." -ForegroundColor Yellow
Write-Host ""
Write-Host "> Wingetパッケージで検索する名前もしくはIDを入力しEnterキーを押してください。(例: chrome)"
$query = Read-Host
$wingetListOutput = (winget search -q $query | Out-String)
if (-Not $wingetListOutput) {
Write-Error "wingetコマンドが実行できないか、指定された条件でデータを取得できませんでした。"
$statusCode = -11
return $statusCode
}
# パッケージリストを整形して表示
$lines = ($wingetListOutput -split "`r?`n")
# 名前やID、バージョンなどの情報があるデータと区切り線のみを抜粋
$availablePackages = $lines | Where-Object { $_ -match "^\S+\s+\S+" -or $_ -match "^-{2,}" }
if (-Not $availablePackages) {
Write-Error "> 利用可能なデータが見つかりませんでした。条件を見直して再試行してください。"
$statusCode = -12
return $statusCode
}
Write-Host ""
Write-Host "> 取得したパッケージ情報の一覧を表示します。:" -ForegroundColor Green
$availablePackages | ForEach-Object { Write-Host $_ }
# ユーザーに ID を入力させる
Write-Host ""
Write-Host "> インストールするパッケージの「ID」を入力しEnterキーを押してください。(例: google.chrome)"
$selectedId = Read-Host
if (-Not $selectedId) {
Write-Error "未入力です。処理を終了します。"
$statusCode = -13
return $statusCode
}
}
else {
$selectedId = $PackageId
}
# 選択されたパッケージのバージョンを確認
Write-Host ""
Write-Host "> 利用可能なバージョンを確認中($selectedId)..." -ForegroundColor Yellow
$wingetOutput = (winget show --id $selectedId --versions | Out-String)
if (-Not $wingetOutput) {
Write-Error "パッケージ '$selectedId' が見つかりませんでした。"
$statusCode = -21
return $statusCode
}
# バージョン情報のみを抽出し一覧を作成
$lines = ($wingetOutput -split "`r?`n")
$availableVersions = ($lines -replace "\s+", "" | Where-Object { $_ -ne "" -and $_ -match "^\d" } | Sort-Object)
if (-Not $availableVersions) {
Write-Error "パッケージ '$selectedId' のバージョン情報を取得できませんでした。"
$statusCode = -22
return $statusCode
}
Write-Host ""
Write-Host "> 取得したバージョン情報の一覧を表示します。:" -ForegroundColor Green
($availableVersions | ForEach-Object { Write-Host $_ })
if (-Not $Version) {
# ユーザーにバージョンを入力させる(空の場合は最新版を使用)
Write-Host ""
Write-Host "> インストールするバージョンを入力しEnterキーを押してください。(未入力の場合は最新バージョンを選択)"
$selectedVersion = Read-Host
# バージョンが未指定の場合、最新版を選択
if (-Not $selectedVersion) {
$selectedVersion = $availableVersions[-1]
Write-Host ""
Write-Host "> 最新版 '$selectedVersion' をインストールします。" -ForegroundColor Yellow
}
}
else {
$selectedVersion = $Version
}
if (-Not ($availableVersions -contains $selectedVersion)) {
Write-Error "指定されたバージョン '$selectedVersion' は一覧にありません。"
$statusCode = -23
return $statusCode
}
Write-Host ""
Write-Host "> $selectedId のバージョン $selectedVersion のダウンロードとインストールを開始します..." -ForegroundColor Green
# 標準出力を破棄してインストール処理を実行
(winget install --id $selectedId --version $selectedVersion --source $Source --silent | Out-Null)
$wingetExitcode = $LASTEXITCODE
if ($wingetExitcode -eq 0) {
Write-Host "> $selectedId バージョン $selectedVersion のインストールが完了しました。" -ForegroundColor Green
} else {
Write-Error "インストール中にエラーが発生しました。winget 終了コード: $wingetExitcode"
$statusCode = -24
return $statusCode
}
return $statusCode
}
まとめ
-
コマンドでソフトウェア・アプリをインストールするコマンド
インストールするコマンドwinget install --id "対象ソフトウェアのID(winget上のID)"
-
コマンドでソフトウェア・アプリをアンインストールするコマンド
アンインストールするコマンドwinget uninstall --id "対象ソフトウェアのID(winget上のID)"
-
コマンドでwingetパッケージの情報を検索するコマンド
パッケージの情報を検索するコマンドwinget search -q "対象のソフトウェア名・アプリ名"
-
パッケージを検索してインストールできるFunction
wingetに慣れていない方にも対話式で使用できるFunction「Install-WingetPackage
」を作れた!
参考文献
Discussion