概要
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されるようです。