Windows PowerShell と PowerShell Core に対応した PowerShell モジュールを作成する
この記事は PowerShell Advent Calendar 2019 に参加しています。
はじめに
PowerShell の新しいバージョンである PowerShell Core が提供されて久しいですが、PowerShell モジュールを開発して一般に提供するような場合、互換性を考えて、旧来の Windows PowerShell をサポートしなければならないことがあります。Windows PowerShell は .NET Framework で動作し、PowerShell Core は .NET Core で動作するので、両方に対応したモジュールを作成するにはちょっとした工夫が必要です。
モジュールを PowerShell スクリプトで記述する
PowerShell スクリプト (この場合は .psm1
) は実行される PowerShell のバージョンの影響を受けないため、Windows PowerShell と PowerShell Core のどちらでも動作します。ただし PowerShell Core での破壊的変更には注意する必要があります。
また、PowerShell スクリプトが外部のライブラリ (.dll
ファイル) に依存する場合、そのライブラリが .NET Standard で作られている必要があります。
マニフェスト ファイルで動的にモジュールを読み込む
モジュールをバイナリ (.dll
ファイル) で開発する場合、マニフェスト ファイル (.psd1
ファイル) では RootModule の宣言に対して関数を受けられるようになっており、その中で $PSEdition を判断して読み込むモジュールを変更することができます。.NET Framework と .NET Core の両方でビルドする必要はありますが、安全にモジュールを読み込むことができます。詳細については以下に記載されています。
モジュールを .NET Standard で作成する
モジュールを .NET Standard (netstandard2.0
) でビルドすることで Windows PowerShell と PowerShell Core の両方で動作させることができます。これは Az モジュールが使っている方法になります。この方法の一番の問題は PowerShell のコア ライブラリである System.Management.Automation.dll
の参照になるのですが、以下のように GAC をパス指定で強引に読み込むことで解決します。実行時には必ず System.Management.Automation.dll
は読み込まれているので、問題になることはありません。
<ItemGroup>
<Reference Include="System.Management.Automation">
<HintPath>C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
この場合も、依存関係のある外部のライブラリについても .NET Standard 化されていないと厳しいと思います。
おわりに
依存関係もまとめて解決できるので、マニフェスト ファイルで制御するのが最も確実な方法になります。とはいえ、他の方法も悪いというわけではないので、状況に応じて使っていただければよいかと思います。
Discussion