Help us understand the problem. What is going on with this article?

WindowsのPackageManagementについての知見まとめ

More than 1 year has passed since last update.

概要

Windowsをクリーンインストールする際にソフトを入れ直すのが大変です。
PackageManagementを利用すればコマンド一つでソフトをインストールできます!
が、PackageManagementの使い方に癖があるので、いつも使い方を忘れて、結局手動でインストールしたほうが早かったんじゃ、、と思ってしまうので、ここに今まで得た知見や自分なりの解釈をまとめます。間違いもあるかもしれない。

用語

PackageManagementの使い方を理解するために必要な用語

PackageManagement
Microsoft Windows上で動作するパッケージ管理システムである。以前はOneGetという名称であった。Powershellから標準で利用することができる。
Module
ここでいうModuleとはPowerShellへ機能を追加するための機構。ModuleをインポートするとそのModuleに含まれるコマンドレットを使用することができるようになったりPowershellをカスタマイズできる拡張機能がつかえるようになったりする。
Package
PackageManagementでインストールされる単位。あるパッケージが他のパッケージに依存している場合は依存しているパッケージもインストールされる(パッケージによってはされない場合もある)。
Source
よく分かってない
Provider
PackageManagementにPackageを提供するもの。ソフトウェアとPackageManagementとの橋渡しをする。一つのProviderに複数のSourceを登録することができるらしいが、利用シーンは不明。
NuGet
.Netやjavascriptのライブラリがあるパッケージマネージャー。VisualStudioから利用できたりする。PackageManagementのProviderでもある。また、PackageManagementのProviderをインストールするときもNuGetのProviderからインストールを行っているようである。
PowerShellGet(Module)
PowerShellGetというModuleはInstall-ModuleといったModuleをインストールするコマンドレットが含まれる。
PowerShellGet(Provider)
PowerShellGetという名前のProviderも存在する。つまりPowerShellGet(Module)のInstall-ModuleコマンドレットでインストールできるModuleはPowerShellGetをプロバイダとして指定すればPackageManagementからもPackageとしてインストールできる。
Chocolatey
Windowsで最も利用されていると思われるパッケージマネージャ。有名なソフトならだいたいここからインストールできる。ChocolateyというProviderがあり、PackageManagementからChocolateyのパッケージをインストールできる。
ChocolateyGet
ChocolateyというProviderはインストールがよく失敗するのでこっちがメインで利用するProviderである。が、ChocolateyにはあるがChocolateyGetにはないパッケージも存在する。

知見1:ExecutionPolicyを忘れずに設定しよう

Powershellスクリプトの実行ポリシー(ExecutionPolicy)はよく分からない人がうっかり変なスクリプトを実行しないようにデフォルトでは実行が行えないようRestrictedになっている。日常的にPowerShellを利用する人はPolicyをRemoteSignedとかにするのが常識のようになっているが、Windowsをクリーンインストールしたときとかは忘れがちである。下記コマンドを打てば設定は変更できる。

Set-ExecutionPolicy -Force RemoteSigned

知見2:とりあえずProviderのインストールとアップデートをしよう

PackageManagementはProvider経由でソフトウェアをインストールするが、Providerはインストールしなければ使えない。また、標準でPowerShellGetのProviderはインストールされているが、Provider自体のバージョンが古いとインストールがうまくいかない事がある。ProviderのインストールはNuGet Providerから行っているようなので、まずNuGet Providerをインストールする必要がある。Powershellを管理者権限で実行し下記コマンドを入力すれば各Providerをインストールできる。

$providerList = @(
'NuGet',
'ChocolateyGet',
'PowerShellGet',
'Chocolatey'
)
$providerList|
%{Install-PackageProvider $_ -Force}

PowerShellGetはInstall-PackageProviderコマンドレットで新しいバージョンをインストールしても、そのPowerShellセッションでは古いバージョンのままなので、一旦PowerShellを開き直す必要がある。

知見3:PackageをインストールするときはProviderを指定しよう

様々なProviderから統一的なインターフェースでPackageをインストールできるのがPackageManagementの利点ではあるのだが、現状、PackageをインストールするときはProviderを指定したほうが良さそう。同じPackage名が複数のProviderに存在するとインストールできないし、Providerの優先順位をつけるような機能もなさそうである。特にChocolateyとChocolateyGetには同じ名前のPackageがたくさんあるので、都度どっちからインストールするか指定する必要がある。また、ProviderをインストールしたあとにPowerShellを開き直すとProviderをImport-Providerコマンドレットでインポートしなければならないが、Packageインストール時にProviderを指定する場合はインポートする必要はない。
例えばGoogleChromeをインストールするときは下記のようにする。

Install-Package GoogleChrome -Force -ProviderName ChocolateyGet

知見4:基本はChocolateyGetで、なければChocolateyを利用しよう

Chocolateyはインストールが失敗することが多い。全てChocolateyGetで網羅してくれればいいのだが、そうもいかないらしい。

PS C:\Windows\system32> Find-Package googlechrome|%{$_.Name +":"+ $_.ProviderName}
GoogleChrome:Chocolatey
GoogleChrome:ChocolateyGet
PS C:\Windows\system32> Find-Package googlejapaneseinput|%{$_.Name +":"+ 
$_.ProviderName}
GoogleJapaneseInput:Chocolatey

GoogleChromeはChocolateyにもChocolateyGetにもあるけどGoogle日本語入力はChocolateyにしかないことが分かる。
普通にFind-Packageだけ打つとPackageは見つけてくれるのだがProviderを表示してくれない。上記例のようにFind-Packageの結果をパイプで渡しProviderNameを表示する。

知見5:Package名はWebで探したほうが良いかもしれぬ

知見にもなっていないのだけど、Find-Packageで見つからないからと言って本当にないとは限らない。Package名が完全一致でないと引っかからなかったりする。Providerによって検索ロジックがちがうのだろうか。正直まだよくわかっていない。Package名をWebで探したほうが確実かもしれぬ。

PS C:\Windows\system32> Find-Package "nodejs*" ←これだと見つかるのに

Name                           Version          Source           Summary
----                           -------          ------           -------
nodejs.install                 10.12.0          https://www.c...
nodejs                         10.11.0          https://www.c...
nodejs-lts                     8.12.0           https://www.c...
nodejs.commandline             6.11.0           https://www.c...

PS C:\Windows\system32> Find-Package "node*" ←これだと見つからない
PS C:\Windows\system32>

まとめ

クリーンインストールしたWindowsにChocolateyにあるソフトをインストールするには
1.ExecutionPolicyを設定する
2.Providerのインストールを行いPowerShellを開き直す
3.Web(https://chocolatey.org/)で欲しいソフトを検索
4.インストールしたいパッケージ名を特定
5.特定したパッケージ名でChocolateyGetを指定しインストールを行う
6.5で失敗したらChocolateyを指定しインストールを行う

とやるのが今の所一番早い。Find-Packageをもう少し使いこなせればいいんだけどな。

豆知識

以下、いろいろ調べているうちに得たはいいけど知らなくてもいいかなって知識

Find-PackageProviderとGet-PackageProviderは返ってくるオブジェクトの型が違う。

PS C:\Windows\system32> Find-PackageProvider|select -First 1|%{$_.GetType().fullname}
Microsoft.PackageManagement.Packaging.SoftwareIdentity
PS C:\Windows\system32> Get-PackageProvider|select -First 1|%{$_.GetType().fullname}
Microsoft.PackageManagement.Implementation.PackageProvider

GetとFindの違いはインポートしているかどうかだけの違いだと思っていたので混乱した。

beta版のPSReadLineを入れたいときは-AllowPrereleaseVersionsと-Force

PSReadLineというModuleが標準でインストールされている。ちなみにこのPSReadLineはバージョンが1.2でPackageManagement経由でもPowerShellGet経由でもないのでコマンドレットでアンインストールはできなかった。
バージョン1.2ではなくbata版のPSReadLineを使いたい場合はInstall-Packageコマンドレットに-AllowPrereleaseVersionsオプションと-Forceオプションをつけるとインストールできる。

PS C:\Windows\system32> Install-Package -AllowPrereleaseVersions PSReadLine -Force
Name                           Version          Source           Summary
----                           -------          ------           -------
PSReadLine                     2.0.0-beta3      PSGallery        Great command line editing in the PowerShell consol...

PS C:\Windows\system32> Get-Package "PSReadline"
Name                           Version          Source                           ProviderName
----                           -------          ------                           ------------
PSReadLine                     2.0.0-beta3      https://www.powershellgallery... PowerShellGet

PS C:\Windows\system32> Get-Module "PSReadline"
ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.2        PSReadline                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PS...

上記のように1.2とbata版が両方入ることになる。PowerShellを開き直すと自動的にbata版のほうがImportされるようです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away