はしくれエンジニアもどきのメモ

情報系技術・哲学・デザインなどの勉強メモ・備忘録です。

Windows PowerShell でパッケージ管理(Package Management)してみる

Windows PowerShell でパッケージ管理(Package Management)してみる

PowerShell5.0(Windows10) から「Package Management(旧OneGet)」で、Windowsでもデフォでパッケージ管理ができる。

環境

Package Management とは

PowerShell5.0(Windows10) からデフォで使えるパッケージ管理システム。 Linux でいうところのyum やapit-get と同じ。 Windowsではパッケージ管理として Chocolatey などもあるが、 PackageManagement ではChocolatey やNuGet よりもレイヤとして上層で 各パッケージをインストールできるように設計されている。

参考: cartman0.hatenablog.com

PackageManagementを使う準備

PowerShell ISE で書くのがおすすめ。 VisualStudioのように、Ctrl+Space でコマンドやオプションの補完が効く。

スクリプト(.ps1) を実行するには、Policyを変更する必要がある。 最初は、スクリプトが実行できないようになっている。 Policyの確認は以下のコマンド。Restricted になっている。


Get-ExecutionPolicy

Restricted

「Remote-Signed」 であれば、オンライン上の署名付きのスクリプトとローカルのスクリプトが実行できるようになる。


Set-ExecutionPolicy Remote-Signed

参考:Tech TIPS:WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する - @IT

Package Providerの登録・確認

たいていのソフトは、Chocolatey でインストールできるので、 Chocolatey をPackage Provider として登録する。


Get-PackageProvider Chocolatey

導入済みのPackage Provider は、 Get-PackageProvider(オプションなし)のコマンドで確認できる。


Get-PackageProvider

Name                     Version          DynamicOptions
----                     -------          --------------
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSaveMode, FilterOnT...
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0
NuGet                    2.8.5.202        Destination, ExcludeVersion, Headers, FilterOnTag, Contains, AllowPrereleaseVersions, Con...
PowerShellGet            1.0.0.1          PackageManagementProvider, Type, Scope, InstallUpdate, PackageManagementProvider, Type, F...
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent

参考: Get-PackageProvider

Package の検索

Find-Package パッケージ名 で検索できる。 choco でいうところのchoco list パッケージ名choco search パッケージ名と同様である。


Find-Package パッケージ名

jdk を検索した結果。


Find-Package jdk

Name                           Version          Source                         Summary
----                           -------          ------                         -------
jdk                            8.0              chocolatey                     The JDK is a development environment for building ap...

参考:Find-Package

Package のインストール

Install-Package パッケージ名 でインストールできる。 choco install パッケージ名 と同様の操作になる。

インストールを続行するか確認があるので、「はい」を選択する。


Install-Package パッケージ名

参考: Install-Package

インストール済みPackage の確認

Get-Packageコマンドでインストール済み Packageの確認ができる。choccoでいうところのchoco list -l と同じもの。

PackageManagement では、Windows更新プラグラムなどすべてのインストールされたプログラムが表示されて見づらい。


Get-Package

オプションをつけて、Provider をChocolatey などと指定できる。


Get-Package -ProviderName Chocolatey

Name                           Version          Source                         Summary
----                           -------          ------                         -------
jdk                            8.0              C:\Chocolatey\lib\jdk.8.0\j... The JDK is a development environment for building ap...

参考:Get-Package

Package のアンインストール

Uninstall-Package コマンドでアンインストール。 choco では、choco uninstall パッケージ名に該当する。


Uninstall-Package パッケージ名

コントロールパネル→プログラムのアンインストールから、 削除してから、PackageManagementではアンインストールできず残り続ける場合があるので注意。

参考:Uninstall-Package

Packageファイルの保存

用途は低いかもしれないが、Packageファイル(.pkg)を保存できる。


Save-Package パッケージ名

保存したPackageファイル(.pkg)は、 Install-Package コマンドでインストールできる。


Install-Package パス+ファイル名.pkg

参考:Save-Package

サーバーの任意の場所に、pkgファイルを保存しておいて、 複数のPCで同じ環境を作るためにインストールという手段が取れるかもしれない。

スクリプトファイル(ps)として書くと以下のようになると思う(未確認)。


cd [pkgファイル群のあるフォルダ]
ls -Name | %{Install-Package $_}

インストール済みPackageのエクスポート(手動)

Chocolatey には、ChocoGuiでインストールしたパッケージ群をxmlでエクスポートして、そのxmlファイルで一括インストールできるという機能があった。 しかし、今のところPackageManagementにはそういう機能はない。。

いろいろ調べてみた結果、手動でスクリプトを実行させてGet-Packageの中身をCSVで保存させるのがよさそう。

Windowsの初期インストール関係のプログラムは除外したいので、 Chocolatey のPackage に限定する。

Get-Package すると、Name, Version, SourceとSummary が出力される。


Get-Package -ProviderName Chocolatey

Name                           Version          Source                         Summary
----                           -------          ------                         -------
GoogleJapaneseInput            1.3.24.20141007  C:\Chocolatey\lib\GoogleJap... An input method published by Google for the entry of...
jdk                            8.0              C:\Chocolatey\lib\jdk.8.0\j... The JDK is a development environment for building ap...

この出力がどんな型なのか調べてみる。 変数に入れて、.getType でわかる。 どうやら、Object型の配列のようである。


$packages = Get-Package -ProviderName Chocolatey
$packages.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

配列のようなので、packages[0] を見てみると、 Package 1つのデータをもっているようだ。


$packages[0]

Name                           Version          Source                         Summary
----                           -------          ------                         -------
GoogleJapaneseInput            1.3.24.20141007  C:\Chocolatey\lib\GoogleJap... An input method published by Google for the entry of Japanese text on a compute...

この要素の型をみてみると、 「SoftwareIdentity」らしい。 さっきのObjectの正体はこいつのようだ。


$packages[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    SoftwareIdentity                         Microsoft.PackageManagement.Internal.Packaging.Swidtag

PowerShell では文字列でなく、オブジェクトでデータが管理されているぽい。 オブジェクトなので、ドットつけて補完でみてみると、いろいろなメンバを持っていることが分かる。 例えば、.NameではPackage名が取れるみたい!


$packages[0].Name # Package名を取得できちゃう

GoogleJapaneseInput

$packages[0].Version # パージョンもとれちゃう

1.3.24.20141007

$packages[0].Version # パージョンもとれちゃう

1.3.24.20141007

$packages[0].Source # sourceもとれちゃう

C:\Chocolatey\lib\GoogleJapaneseInput.1.3.24.20141007\GoogleJapaneseInput.1.3.24.20141007.nupkg

$packages[0].Source # sourceもとれちゃう

C:\Chocolatey\lib\GoogleJapaneseInput.1.3.24.20141007\GoogleJapaneseInput.1.3.24.20141007.nupkg

$packages[0].Summary # Summary情報もとれちゃう

An input method published by Google for the entry of Japanese text on a computer. Since its dictionaries are generated automatically from the Internet, it is much
 easier to type personal names, Internet slang, neologisms and related terms.

パッケージ名とバージョン名も取れたので、 foreach でぐるぐる回せば一括インストールできそうです。 問題は、どうやって「SoftwareIdentity」クラスのまま保存するかなんですが、 どうやらCSVにすると、クラス情報も残せるみたいです。

CSV出力は、Export-Csv -InputObject [入力Object] [出力ファイル名] コマンドが使える。パイプで渡すと以下のようになる。

参考:Windows PowerShell の機能


Get-Package -ProviderName Chocolatey | Export-Csv export.csv

catで見てみると、最初に「SoftwareIdentity」のタイプ情報が付加されていることが分かる。


cat .\export.csv
#TYPE Microsoft.PackageManagement.Packaging.SoftwareIdentity
"ProviderName","Dependencies","Source","Status","SearchKey","FullPath","PackageFilename","FromTrustedSource","Summary","SwidTags","CanonicalId","Metadata","SwidTa
gText","IsCorpus","Name","Version","VersionScheme","TagVersion","TagId","IsPatch","IsSupplemental","AppliesToMedia","Meta","Links","Entities","Payload","Evidence"
,"XmlLang","Attributes"
........

これでエクスポートはできたので、 一括インストールは、Import-Csv で読み込んで、 foreachでInstall-Packageコマンドを回せばいい。

以下のようなスクリプトファイルになると思う(未確認)。


Import-Csv .\export.csv | %{Install-Package $_.Name}

参考:Import-Csv

一応これで、ChocolateyのようなPackageのエクスポート、一括インストールの真似事はできた。