移植可能なモジュール

Windows PowerShell が .NET Framework 用であるのに対し、PowerShell Core は .NET Core 用に作成されています。 移植可能なモジュールとは、Windows PowerShell と PowerShell Core の両方で動作するモジュールです。 .NET Framework と .NET Core の間には高い互換性がありますが、使用可能な API には違いがあります。 また、Windows PowerShell と PowerShell Core でも使用できる API が異なります。 両方の環境で使用するモジュールを作成するときは、これらの違いを意識する必要があります。

既存のモジュールの移植

PSSnapIn の移植

PowerShell スナップインは、PowerShell Core ではサポートされていません。 ただし、PSSnapIn を PowerShell モジュールに変換するのは簡単です。 通常、PSSnapIn の登録コードは、PSSnapIn の派生クラスの単一のソース ファイルに含まれます。 このソース ファイルは、必要ありませんので、ビルドから削除します。

New-ModuleManifest を使って、PSSnapIn 登録コードに必要なものを置き換える新しいモジュール マニフェストを作成します。 PSSnapIn の一部の値 (Description など) は、モジュール マニフェスト内で再利用できます。

モジュール マニフェストの RootModule プロパティは、コマンドレットを実装するアセンブリ (.dll) の名前に設定する必要があります。

.NET Portability Analyzer (別名 APIPort)

Windows PowerShell 用に記述されたモジュールを PowerShell Core で動作するように移植するには、最初に .NET Portability Analyzer を使用します。 コンパイル済みアセンブリに対してこのツールを実行し、モジュールで使われている .NET API が .NET Framework、.NET Core、および他の .NET ランタイムと互換性があるかどうかを判断します。 このツールでは、代替 API がある場合は指摘されます。 それ以外の場合は、ランタイム チェックを追加し、特定のランタイムで使用できない機能を制限することが必要な場合があります。

新しいモジュールの作成

新しいモジュールを作成する場合に推奨されるのは、.NET CLI の使用です。

PowerShell の標準モジュール テンプレートのインストール

.NET CLI をインストールした後、簡単な PowerShell モジュールを生成するためのテンプレート ライブラリをインストールします。 そのモジュールは、Windows PowerShell、PowerShell Core、Windows、Linux、および macOS と互換性を持つようになります。

次の例では、テンプレートのインストール方法を示します。

dotnet new install Microsoft.PowerShell.Standard.Module.Template
The following template packages will be installed:
   Microsoft.PowerShell.Standard.Module.Template

Success: Microsoft.PowerShell.Standard.Module.Template::0.1.3 installed the following templates:
Template Name               Short Name  Language  Tags
--------------------------  ----------  --------  -------------------------
PowerShell Standard Module  psmodule    [C#]      Library/PowerShell/Module

新しいモジュール プロジェクトの作成

テンプレートをインストールした後は、そのテンプレートを使用して新しい PowerShell モジュール プロジェクトを作成できます。 この例のサンプル モジュールの名前は "myModule" です。

PS> mkdir myModule

    Directory: C:\Users\Steve

Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 8/3/2018 2:41 PM myModule

PS> cd myModule
PS C:\Users\Steve\myModule> dotnet new psmodule
The template "PowerShell Standard Module" was created successfully.

Processing post-creation actions...
Restoring  C:\Users\Steve\myModule\myModule.csproj:
  Determining projects to restore...
  Restored C:\Users\Steve\myModule\myModule.csproj (in 184 ms).
Restore succeeded.

モジュールのビルド

標準の .NET CLI コマンドを使用して、プロジェクトをビルドします。

dotnet build
PS C:\Users\Steve\myModule> dotnet build
MSBuild version 17.6.3+07e294721 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  PowerShellPG -> C:\Users\Steve\myModule\bin\Debug\netstandard2.0\myModule.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.36

モジュールのテスト

モジュールをビルドした後は、それをインポートしてサンプルのコマンドレットを実行できます。

Import-Module .\bin\Debug\netstandard2.0\myModule.dll
Test-SampleCmdlet -?
Test-SampleCmdlet -FavoriteNumber 7 -FavoritePet Cat
NAME
    Test-SampleCmdlet

SYNTAX
    Test-SampleCmdlet [-FavoriteNumber] <int> [[-FavoritePet] {Cat | Dog | Horse}] [<CommonParameters>]


ALIASES
    None


REMARKS
    None


FavoriteNumber FavoritePet
-------------- -----------
             7 Cat

モジュールのデバッグ

モジュールをデバッグするための Visual Studio Code の設定のガイドについては、Visual Studio Code を使用したコンパイル済みコマンドレットのデバッグに関するページを参照してください。

サポート テクノロジ

次のセクションでは、このテンプレートで使用されているテクノロジの一部について詳しく説明します。

.NET 標準ライブラリ

.NET Standard は、すべての .NET 実装で使用できる .NET API の正式な仕様です。 .NET Standard をターゲットとするマネージド コードは、.NET Standard のそのバージョンと互換性のある .NET Framework および .NET Core のバージョンで動作します。

注意

.NET Standard に API が存在していても、.NET Core での API の実装で実行時に PlatformNotSupportedException がスローされる可能性があるので、Windows PowerShell および PowerShell Core との互換性を確認するため、両方の環境内でモジュールのテストを実行するのがベスト プラクティスです。 クロスプラットフォームを意図したモジュールの場合は、Linux と macOS でもテストを実行します。

.NET Standard をターゲットにすると、モジュールが進化しても、互換性のない API が誤ってモジュールに導入されないことが保証されます。 非互換性は、実行時ではなくコンパイル時に検出されます。

ただし、互換性のある API を使用してさえいれば、.NET Standard をターゲットにしなくても、モジュールは Windows PowerShell と PowerShell Core の両方で動作します。 中間言語 (IL) は、2 つのランタイムの間で互換性があります。 .NET Framework 4.6.1 をターゲットにでき、これは .NET Standard 2.0 と互換性があります。 .NET Standard 2.0 の対象外の API を使用していなければ、モジュールは再コンパイルしなくても PowerShell Core 6 で動作します。

PowerShell Standard ライブラリ

PowerShell Standard ライブラリは、その標準のバージョン以降のすべての PowerShell のバージョンで利用可能な PowerShell API の正式な仕様です。

たとえば、PowerShell Standard 5.1 は、Windows PowerShell 5.1 および PowerShell Core 6.0 以降の両方と互換性があります。

PowerShell Standard ライブラリを使用してモジュールをコンパイルすることをお勧めします。 ライブラリにより、API が使用可能で、Windows PowerShell と PowerShell Core 6 の両方で実装されていることが保証されます。 PowerShell Standard は、常に上位互換性があるように意図されています。 PowerShell Standard ライブラリ 5.1 を使用してビルドされたモジュールは、PowerShell の将来のバージョンと常に互換性があります。

モジュール マニフェスト

Windows PowerShell および PowerShell Core との互換性を示す

モジュールが Windows PowerShell と PowerShell Core の両方で動作することを検証した後は、モジュール マニフェストで CompatiblePSEditions プロパティを使用して、互換性を明示的に示す必要があります。 値 Desktop はモジュールに Windows PowerShell との互換性があることを意味し、値 Core はモジュールに PowerShell Core との互換性があることを意味します。 DesktopCore の両方を含めると、モジュールに Windows PowerShell および PowerShell Core の両方との互換性があることを意味します。

注意

Core は、てモジュールが Windows、Linux、macOS と互換性があることを自動的に意味するものではありません。 PowerShell v5 では CompatiblePSEditions プロパティが導入されました。 CompatiblePSEditions プロパティを使用しているモジュール マニフェストは、PowerShell v5 より前のバージョンに読み込むことができません。

OS の互換性を示す

最初に、モジュールが Linux と macOS で動作することを検証します。 次に、モジュール マニフェストでこれらのオペレーティング システムとの互換性を示します。 これにより、PowerShell ギャラリーに発行した後で、ユーザーがオペレーティング システム用のモジュールを見つけやすくなります。

モジュール マニフェスト内で、PrivateData プロパティには PSData サブプロパティがあります。 PSData の省略可能な Tags プロパティは、PowerShell ギャラリーに表示される値の配列を受け取ります。 PowerShell ギャラリーでは、次の互換性の値がサポートされています。

タグ 説明
PSEdition_Core PowerShell Core 6 と互換性があります
PSEdition_Desktop Windows PowerShell と互換性があります
Windows Windows と互換性があります
Linux Linux と互換性があります (特定のディストリビューションはなし)
macOS macOS と互換性があります

例:

@{
    GUID = "4ae9fd46-338a-459c-8186-07f910774cb8"
    Author = "Microsoft Corporation"
    CompanyName = "Microsoft Corporation"
    Copyright = "(C) Microsoft Corporation. All rights reserved."
    HelpInfoUri = "https://go.microsoft.com/fwlink/?linkid=855962"
    ModuleVersion = "1.2.4"
    PowerShellVersion = "3.0"
    ClrVersion = "4.0"
    RootModule = "PackageManagement.psm1"
    Description = 'PackageManagement (a.k.a. OneGet) is a new way to discover and install software packages from around the web.
 it's a manager or multiplexer of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following.
  - Manage a list of software repositories in which packages can be searched, acquired and installed
  - Discover software packages
  - Seamlessly install, uninstall, and inventory packages from one or more software repositories'

    CmdletsToExport = @(
        'Find-Package',
        'Get-Package',
        'Get-PackageProvider',
        'Get-PackageSource',
        'Install-Package',
        'Import-PackageProvider'
        'Find-PackageProvider'
        'Install-PackageProvider'
        'Register-PackageSource',
        'Set-PackageSource',
        'Unregister-PackageSource',
        'Uninstall-Package'
        'Save-Package'
    )

    FormatsToProcess  = @('PackageManagement.format.ps1xml')

    PrivateData = @{
        PSData = @{
            Tags = @('PackageManagement', 'PSEdition_Core', 'PSEdition_Desktop', 'Windows', 'Linux', 'macOS')
            ProjectUri = 'https://oneget.org'
        }
    }
}

ネイティブ ライブラリに対する依存関係

さまざまなオペレーティング システムまたはプロセッサ アーキテクチャでの使用を目的としたモジュールは、それ自体が何らかのネイティブ ライブラリに依存するマネージド ライブラリに依存する場合があります。

PowerShell 7 より前では、マネージド ライブラリが正しく検出できるように、適切なネイティブ dll を読み込むためのカスタム コードを用意する必要がありました。

PowerShell 7 では、読み込まれるネイティブ バイナリは、.NET RID カタログ 表記のサブセットに従って、マネージド ライブラリの場所内のサブフォルダー内で検索されます。

managed.dll folder
    |
    |--- 'win-x64' folder
    |       |--- native.dll
    |
    |--- 'win-x86' folder
    |       |--- native.dll
    |
    |--- 'win-arm' folder
    |       |--- native.dll
    |
    |--- 'win-arm64' folder
    |       |--- native.dll
    |
    |--- 'linux-x64' folder
    |       |--- native.so
    |
    |--- 'linux-x86' folder
    |       |--- native.so
    |
    |--- 'linux-arm' folder
    |       |--- native.so
    |
    |--- 'linux-arm64' folder
    |       |--- native.so
    |
    |--- 'osx-x64' folder
    |       |--- native.dylib