この記事は 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 の両方で動作させることができます。*1 この方法の一番の問題は 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 化されていないと厳しいと思います。
(2019/12/25 追記)
コメントいただきました。PowerShellStandard.Library を参照するのが正しい方法とのことです。
まとめ
依存関係もまとめて解決できるので、マニフェスト ファイルで制御するのが最も確実な方法になります。とはいえ、他の方法も悪いというわけではないので、状況に応じて使っていただければよいかと思います。
*1:これは Az モジュールが使っている方法になります。