PowerShellモジュールとの作業は、PowerShellの自動化の重要な要素です。PowerShellの学習を始めるとき、最初のステップは通常、単一のコマンドの使用です。これにより、スクリプトの作成が可能になり、それに続いて関数の作成が可能になります。
関数を使用することで、スクリプトをよりモジュール化することができます。これにより、同じコードをコピーして貼り付けることなく、多くの場所で同じコードを使用することができます。関数を使用すると、同じコードの同じ編集を行うために使用されるすべての場所で時間を節約することができます。代わりに、コードを単一の場所で改善することに取り組むことができます。
さらに、これらの関数をモジュールに組み合わせることで、関数をさらに活用することができます。
A module is a collection of functions in a text file with a psm1 extension. There are some optional additions, such as a module manifest and comment-based or external help that may also be included. These will be covered later on.
前提条件
I’ll be using Windows PowerShell 5.1 in this article. If you’re using an older version or PowerShell Core, your mileage may vary as to results you see.
モジュールの操作
PowerShellセッションを最初に開始すると、2つのモジュールが使用可能になります。最初のモジュールはMicrosoft.PowerShell.Utilityで、既に使用している多くの基本的なPowerShellの関数が含まれています。もう1つのモジュールはPSReadlineです。これらの開始モジュールは、Get-Module
コマンドを使用して確認することができます。

ただし、これは利用可能なすべてのモジュールの完全なリストではありません。PowerShell 3以降、インストールされたモジュールは必要に応じてインポートされます。古いバージョンのPowerShellを実行している場合は、コマンドを使用してモジュールを最初にインポートする必要があります。Import-Module
コマンドを使用します。
後のバージョンでもImport-Module
を使用する場合もあります。モジュールをインストールした後にモジュールをインポートしたい場合は、次のようにImport-Module
を使用できます。

Get-Module
を使用すると、インポートされているすべてのモジュールが表示されますが、まだインポートされていないモジュールは表示されません。その後、ListAvailable
パラメータを使用して、利用可能な他のモジュールを表示することができます。

Get-Module -ListAvailable
デフォルトではすべてのコマンドが表示されません
ExportedCommands
プロパティには、モジュールからエクスポートされた利用可能なコマンドのリストが含まれています。このリストとモジュールファイルの内容にはいくつかの違いがある場合があります。エクスポートされたコマンドは、関数を非表示にするためのモジュールマニフェストに組み込まれた機能です。モジュールの作成者は、Export-ModuleMember
コマンドレットを使用することもありますが、それはこの記事の範囲外です。
モジュールの作成者は、関数を非表示にしたい場合があります。それは他の関数をサポートするために使用されるもので、ユーザーには表示されません。関数を非表示にするために、作成者はマニフェストのFunctionsToExport
配列からそれを除外します。ここでは、ExportedCommands
プロパティの拡張ビューが表示されています。

モジュールのインポート
モジュールを使用するための多くの方法があります。モジュールファイルのパスを使用して手動でモジュールをインポートすることができます。これにより、モジュールのテストや更新をする際に多くの作業をする必要がなくなります。しかし、この方法ではモジュールのパスを正確に指定する必要があるため、移植性にはあまり適していません。また、PowerShellは$env:PSModulePath
変数にないモジュールを自動的にインポートしません。
コマンドの選択的なインポート
Import-Module
を使用して、Function
パラメータを使ってモジュール全体ではなく特定の関数のみをインポートすることができます。これは、Office 365モジュールなどのリモートシステムからモジュールをインポートする際に時間を節約することができます。
すべてのユーザーモジュール
すべてのユーザーのためにインストールされたモジュールは、C:\Program Files\WindowsPowerShell\Modulesに配置されます。このディレクトリには、Install-Module
を使用してデフォルトのスコープAllUsers
でインストールされたモジュールが含まれています。
現在のユーザーモジュール
モジュールをインストールするが、単一のユーザーのみが使用する場合は、CurrentUser
スコープがあります。これにより、モジュールファイルはドキュメントフォルダにC:\Users\<username>\Documents\WindowsPowerShell\Modulesとして配置されます。これは、ドキュメントフォルダにフォルダのリダイレクトを使用する環境で便利です。
この場合、1台のコンピューターにモジュールをインストールして、別のコンピューターで使用することができます。なぜなら、両方のコンピューターが同じドキュメントフォルダを共有しているからです。
システムモジュール
完全性のために、C:\Windows\System32\WindowsPowerShell\1.0\Modulesにもモジュールディレクトリがあります。技術的には、このパスに配置されたモジュールは他のパスと同様にインポートされますが、これはMicrosoftのシステムモジュールに予約されているため、推奨されません。
名前付けが重要です
モジュールをデフォルトで新しいセッションで利用可能にするために、手動でモジュールをこれらのパスのいずれかに配置することもできますが、モジュールの必要な名前付けルールに従っていることを確認する必要があります。モジュールファイルが配置されるフォルダは、psm1モジュールファイルと、psd1モジュールマニフェストがある場合は同じ名前でなければなりません。
前述したGet-Module -ListAvailable
を使用すると、これらのパスが参照されます。すべてのモジュールパスは$env:PSModulePath -Split ';'
を使用して表示できます。ここで表示されている以外のパスもリストに表示される場合があります。多くのプログラムはインストール時に独自のモジュールパスを追加します。その一例がSQLであり、SQLには独自のモジュールパスに含まれるモジュールがあります。

$env:PSModulePath
別のプロセスでインストールする必要があるモジュールもあります。最も重要な例の一つがActiveDirectoryモジュールです。Windows 7からWindows 10 1803までは、Remote Server Administration Tools(RSAT)インストーラを使用してこれをインストールする必要がありました。
Windows 10の新しいバージョン(1809以降)では、これはFeatures On Demandを通じてのみ利用可能です。RSATをインストールすると、ActiveDirectoryモジュールと、他の多くのWindowsのロールを管理するために使用するモジュールもインストールされます。Windows Server OSでは、これらのモジュールはServer Managerを介してインストールされます。
リモートモジュールのインポート(暗黙のリモーティング)
ローカルでモジュールを実行することが実用的ではない場合があります。代わりにリモートデバイスに接続し、そこにインストールされているモジュールをインポートする方が良いです。これにより、コマンドは実際にリモートマシンで実行されます。これは、マイクロソフトのOffice 365モジュールと頻繁に使用されます。これらのモジュールの多くはOffice 365サーバーに接続し、その後モジュールをインポートします。コマンドを実行すると、リモートサーバー上で実行され、その出力がセッションに送信されます。
リモートモジュールをインポートする別の用途は、ローカルにモジュールがインストールされていない場合です。これは、ActiveDirectoryモジュールがインストールされていない場合に得られるものですが、それをインポートしようとします。

リモートモジュールをインポートするには、まずPSSessionを作成する必要があります。New-PSSession
を使用してセッションを作成できます。その後、Import-Module
でPSSessionパラメーターを使用してリモートデバイス上で利用可能なモジュールをインポートします。
この方法でリモートモジュールをインポートすることで、分散環境でのコードの実行が高速化されます。たとえば、自分のコンピュータで作業しているが、作業しているサーバーが米国にある場合、特定のコマンドをローカルでサーバーに対して実行するのにかかる時間はかなり長くなる可能性があります。一方、コマンドをサーバー上で実行し、出力をローカルセッションに送信すると、はるかに高速です。
モジュールのプレフィックスの追加
リモートマシンからインポートされた関数には、接頭辞を付けることもできます。このオプションは、ローカルモジュールをインポートする際に使用できますが、モジュールの異なるバージョンをテストする場合以外ではほとんど使用されません。
上記のインポートコマンドを実行した場合、コマンドを確認すると、次のように表示されます:

この場合、プレフィックスを使用してローカルモジュールでないことを示すことができます。これは、ローカルにも利用可能なモジュールをインポートする場合に使用できます。プレフィックスを追加することで、コードがどこで実行されているのかの混乱を減らすことができます。
モジュールの削除
Remove-Module
を使用せずに、現在のセッションからモジュールを削除することもできます。これにより、モジュールファイルは削除せずに、ローカルセッションからモジュールが削除されます。モジュールを使用するためにリモートセッションを使用していた場合に使用することができます。セッションをクリーンアップしてリモートセッションを切断するために、Remove-Module
を使用できます。

Remove-Module
の別の使用方法は、モジュールに変更を加える場合で、新しいPowerShellセッションを起動したくない場合です。この場合、Remove-Module
を使用してからImport-Module
を使用して再度ロードします。または、Import-Module
にForce
パラメータを使用することもできます。これにより、モジュールのアンロードと再ロードが完了します。
PowerShellモジュールの構成要素
A module can consist of one or more files. To meet the minimum requirements for a module, you must have a module file. This can be a PSM1 file or any other module file such as a binary module file. To build upon that, your psm1 should have functions defined in it, or it will not be much use to anyone.
機能の見た目や動作には特定の要件はありませんが、いくつかのガイドラインが存在します。通常、同じコンセプトを中心にしたモジュール内にすべての関数を配置することが望ましいです。
モジュールには関連する関数を含めます。
例えば、ActiveDirectoryモジュールには、Active Directoryと対話する関数のみが含まれます。通常、関数名には接頭辞が含まれます。先ほどのActiveDirectoryモジュールを例にすると、関数名の名詞はすべてADで始まります。
これらのガイドラインを使用すると、関数の発見性が向上します。新しいモジュールをインポートして関数をタブで切り替えたい場合、関数の名前構造が似ていると便利です。モジュールはしばしばPSで始まることがありますが、この接頭辞は公式にはMicrosoftモジュール専用です。モジュールの先頭にPSを使用しても問題は起こらないかもしれませんが、他のモジュール名との競合を引き起こす可能性があります。
これらのガイドラインを使用すると、レジストリと対話する一連の関数がある場合、次のような形式にすることができます:
モジュールマニフェスト
テキストモジュールファイルを拡張するために、モジュールマニフェストを含めることもできます。これらのファイルはPSD1拡張子を持ち、モジュールに関するメタデータが含まれます。ここには、作者の情報、モジュールの説明、他の必要なモジュールなどの情報を含めることができます。リポジトリに公開する場合、Author
とDescription
のフィールドを入力する必要があります。
以下は、登録モジュールのマニフェストの例です。
最初は intimidating に見えるかもしれませんが、Microsoft にはモジュールマニフェストを生成するために使用できる便利な cmdlet があります。含まれるコマンドは New-ModuleManifest
です。上記のマニフェストを生成するには、次のように使用します:
外部ヘルプファイル
一部のモジュールには外部ヘルプファイルも含まれている場合があります。これらはファイル名の末尾にある <ModuleName>-Help.xml で識別できます。これらの外部ヘルプファイルには、通常、関数定義のコマンドベースのヘルプに含まれる情報が含まれています。
モジュールをインポートした後、Get-Help
コマンドを使用する場合、関数に # .ExternalHelp <ModulePath>-Help.xml
を追加する必要もあります。非常に大きなモジュールには通常、外部ヘルプファイルが含まれており、そのためスコープ外となっています。
関連ファイル
これらはモジュールで見られる最も一般的なファイルのタイプですが、これら以外にもファイルが存在する場合があります。テキストモジュールに加えてバイナリファイルや他の依存関係も存在することがあります。モジュールパスを探索することで、モジュール内のさまざまな追加ファイルの例を見つけることができます。
非標準のモジュールファイルを正しく公開するためには、モジュールマニフェストの FileList
パラメータに他のファイルを含める必要があります。
モジュールのマニフェスト内には、現在空の多くの他のパラメータがあることに気付くでしょう。これらを使用して、モジュールの使用に関する他の要件を定義することができます。たとえば、モジュールが動作するPowerShellのバージョンを定義することができます。サポートされていないPowerShellのバージョンでモジュールをインポートしようとすると、次のようなエラーメッセージが表示されます:

PSRepositories
モジュールの主要な配布オプションの1つは、PSRepositoryです。1000フィートから見ると、PSRepositoryは複数の人や複数のデバイスがモジュールファイルにアクセスできる場所です。これらは、ファイルを公開できるウェブサーバーがよく使用されます。
リポジトリにはディレクトリも使用できますが、これによりリポジトリの機能が制限されます。PSRepositoryを自分でホストすることもできますし、PowerShell Galleryのようなインターネット上で利用可能な多くのオプションを利用することもできます。自分のPSRepositoriesは、Get-PSRepository
コマンドを使用して表示できます。

デフォルトでは、エントリは1つだけであり、PowerShell Galleryになります。信頼されていないと表示されることがあるかもしれません。これは、PowerShellがPowerShell Galleryを使用すると、Microsoftによって書かれて承認されたコードを使用していない可能性があることを示すためです。これは、モジュールがそれからインストールされる前に明示的な許可を与える必要があることを意味します。
PSRepositoriesの追加
自分自身のリポジトリを追加することもできます。PowerShell Galleryを信頼するには、Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trusted
を実行するか、PowerShell Galleryからモジュールを初めてインストールする際に警告を受け入れることができます。
これらの PSRepositories との対話に使用するすべてのコマンドは、PowerShellGet モジュールにあります。関数はこちらで確認できます:

特定のリポジトリとの対話する前に、PowerShellGet モジュールを更新する必要がある場合があります。
モジュールの検索
PSRepository を使用するもう一つの重要な機能は、モジュールの検索です。これは Find-Module
コマンドを使用して行います。特定の条件でフィルタリングして目的のモジュールを検索する方法は複数ありますが、今回は VMware のモジュールを検索する方法を示します:

これにより、VMware で始まるすべてのモジュールが表示されます。これらのほとんどは VMware のものですが、モジュールの公開者を確認するために author 属性を確認する必要があります。
PowerShell Gallery には誰でもアップロードできるため、数千ものモジュールが利用可能です。つまり、使用するケースに適さないモジュールも見つかる可能性があります。見つけたモジュールの多くはオープンソースであり、モジュールの機能性を向上させるために貢献することができます。
モジュールのインストール
Install-Module
コマンドを使用するには、モジュールをホストする信頼できるPSRepository が必要です。これは PowerShell Gallery、他のインターネットの PSRepository、または自己ホストサイトのいずれかです。インストールする前に Find-Module
コマンドのパイプラインからモジュールを確認することもできます。

MinimumVersion
、MaximumVersion
、または RequiredVersion
パラメータを使用してモジュールのバージョンを定義することもできます。
Install-Module
を使用してインストールされたすべてのモジュールを表示するには、Get-InstalledModule
を使用します。これにより、AllUsers
スコープまたはCurrentUser
スコープにインストールされたすべてのモジュールがリストされます。
モジュールのアンインストール
モジュールをインストールできるようにするだけでなく、モジュールをアンインストールすることもできます。モジュールがInstall-Module
コマンドを使用してインストールされていない場合、Uninstall-Module
コマンドを使用してアンインストールすることはできません。

Uninstall-Module
ここで、ActiveDirectoryモジュールをアンインストールしようとしています。このモジュールはInstall-Module
でインストールされていないため、Uninstall-Module
を使用しようとするとエラーが発生します。このモジュールをアンインストールするには、モジュールのインストールに使用した方法を逆に使用してアンインストールする必要があります。
モジュールの正常なアンインストールを確認するためには、先にインストールしたVMware.PowerCLIモジュールをアンインストールすることができます。

VMware.PowerCLIをアンインストールしたとしても、まだ多くの依存関係がインストールされていることがわかります。すべてのモジュールをアンインストールしたい場合は、Get-InstalledModule VMware.* | Uninstall-Module -Force
を使用できます。
このモジュールを完全にアンインストールするのが困難な理由は、多くの依存関係が存在するためです。さらに、これらのモジュールの一部は互いに依存しているため、Force
パラメータが必要です。
モジュールの更新
インストールおよびアンインストール方法を理解したので、インストール済みのモジュールを更新する方法について知りたいと思うかもしれません。
他のプロセスと同様に、モジュールがInstall-Module
を使用してインストールされていない場合、PowerShellコマンドを使用して更新することはできません。最新のリリースまたは新しい特定のバージョンにモジュールを更新するには、Update-Module
を使用できます。
また、AllowPreRelease
スイッチを使用すると、公式にリリースされていないバージョンに更新することができます。これは、経験しているバグの修正や使用したい新機能が追加された可能性があるため、役に立つ場合があります。

Update-Module
モジュールの検査/保存
使用前にモジュールを検証する際に非常に役立つ、あまり使われないコマンドの1つがSave-Module
です。このコマンドを使用すると、モジュールをインストールせずにパスにダウンロードすることができます。
その後、ファイルを検査し、モジュールがバイナリモジュールでない場合はコードを開いてモジュールを構成するコードを確認することができます。これは、モジュールが悪意のある操作を行っていないことを確認するだけでなく、他の人々がモジュールをどのように構造化しているかを学ぶためにも役立ちます。

Save-Module
この例では、VMware.PowerCLIモジュールだけでなく、すべての依存関係もダウンロードされます。以下は、VMware.PowerCLIフォルダに表示される内容です:

これは、エンドユーザーライセンス契約などの非標準のモジュールファイルがモジュールに含まれる場合があることを示す良い例です。
独自のモジュールの作成
他人のモジュールとの対話方法を学びました。次は、自分自身のモジュールを作成して、スケーラビリティのためにコードを最適化する方法を学びます。
テンプレートファイルの作成
まず、モジュールファイルを格納するためのフォルダを作成する必要があります。コンテナを作成したら、モジュールファイルを作成する必要があります。モジュールファイルの名前は、フォルダの名前と同じである必要があります。そうしないと、モジュールを公開しようとしたときにPowerShellがモジュールを正しく検出できません。
また、マニフェストも使用したい場合は、コンテナとモジュールファイルと同じ名前にする必要があります。
コンテナ、モジュールファイル、マニフェストファイルがあれば、完全に機能するモジュールができます。このモジュールをPSRepositoryに公開し、任意の場所にインストールすることができます。ただし、モジュールファイルが空であるため、あまり役立たないかもしれません。それでも、これらのファイルを使用してリポジトリが正常に動作するかをテストすることはできます。
PSRepositoryの登録
モジュールを公開する前に、別のPSRepositoryをセッションに追加する必要があります。テストには、ローカルパスをPSRepositoryとして使用できます。セットアップと解除が容易です。
通常、ディレクトリを使用してPSRepositoryを設定する場合、複数のコンピュータからアクセスできるようにする必要があります。次のようにしてローカルリポジトリを作成できます:
ただし、PSRepositoryからのダウンロードのみで、公開しない場合は、PublishLocation
パラメータを除外できます。
モジュールの公開
インストールポリシーを信頼済みに設定しているため、リポジトリからモジュールをインストールする際に確認のメッセージは表示されません。新しいPSRepositoryを使用して、Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo
コマンドを使用してモジュールを公開できます。
モジュールを公開した後は、上記のコマンドを使ってモジュールを検索し、インストールすることができます。
モジュールをインストールしたので、Get-Module
コマンドを使用してローカルセッションにインポートされたモジュールを確認できます。マニフェストのFunctionsToExport
配列に関数を追加していないため、ExportedCommands
プロパティは空です。

モジュールへの追加
モジュールを公開およびインストールできることがわかったので、機能を追加してみましょう。次のように、レジストリキーを返す関数を追加できます:
マニフェストをそのままにして新しいモジュールをアップロードしようとすると、2つの問題が発生します。まず、マニフェストファイルでモジュールのバージョンを変更していないため、モジュールのバージョンが既にリポジトリに存在するというエラーが表示されます。
モジュールの関数のエクスポート
もう一つの問題は、モジュールをインポートした後でもExportedCommands
プロパティに関数が表示されないことです。なぜなら、新しい関数をマニフェストに追加していないからです。
FunctionsToExport
リストに関数をリストアップしなくても、関数は使用できますが、見つけるのが困難になります。
空の配列を定義しない限り、
@()
を使用してFunctionsToExport
を定義しないと、すべての関数、変数、エイリアスがデフォルトでエクスポートされます。
これらの2つの問題を修正するには、次のようにモジュールファイルを更新します:
関数をモジュールに追加し、マニフェストをこれらの変更に反映することができたら、前と同じコマンドを使用して新しいバージョンのモジュールを公開できます。
FunctionsToExportとExport-ModuleMemberの選択
PowerShellのモジュールメンバーのエクスポートには、2つの類似した機能があります。どちらを選ぶかは、ニーズに応じて異なりますが、どちらも正しい方法です。
関数のエクスポートを動的に制御する場合は、関数のリストを渡すことができるExport-ModuleMember
を使用します。通常、これは複数の個別の関数PS1ファイルをドットソース化する場合に使用されます。内部関数をプライベートフォルダに分け、エクスポート可能な関数をパブリックフォルダに分けることで、パブリック関数をすべてExport-ModuleMember
関数に渡すことで簡単にエクスポートできます。
A few notes about Export-ModuleMember:
Export-ModuleMember
はFunctionsToExport
の動作を上書きするため、Export-ModuleMember
コマンドが使用されると、FunctionsToExportは効果を持ちません。Export-ModuleMember
は、明示的に定義しない限り、変数やエイリアスをエクスポートしませんが、FunctionsToExport
はそれらの値をエクスポートします。- 複数の
Export-ModuleMember
コマンドを使用でき、優先度ではなくスタックされます。
機能リストに変更がない場合、モジュールマニフェストのFunctionsToExport
構成を使用すると、明示的に変数やエイリアスをエクスポートする必要はありません。
モジュールの更新
次に、セッション内のモジュールを更新して、更新されたファイルを使用できるようにします。 Update-Module ATARegistry
を使用して、リポジトリに公開した更新をダウンロードします。

これで、新しいバージョンのモジュールが表示され、マニフェストで定義した関数が表示されることがわかります。
ヘルプコンテンツの作成
早期に紹介されたオプションの1つは、PowerShellに組み込まれたヘルプシステムです。おそらく、関数に対してGet-Help
を使用したことがあるかもしれません。この情報は、2つの主要な方法で追加できます。
最初の方法は、コメントベースのヘルプを関数定義に追加することです。これは、多くのモジュール作成者が実装する方法です。もう1つの方法は、外部のヘルプファイルを使用することです。 Full
パラメータを使用して、ヘルプが提供するすべての情報を表示できます。

Get-Help
ご覧のように、実際にはあまり情報がなく、手に入る情報もおそらく誰にとっても役に立たないでしょう。
これらのフィールドをヘルプシステムで埋めるために、モジュールファイルにコメントベースのヘルプを追加することができます。コメントベースのヘルプのすべてのオプションについては、Get-Help about_Comment_Based_Help
を使用して読むことができます。
今は、関数を以下のように更新できます。これは最も一般的に使用されるヘルプパラメータのリストですが、これらはすべてオプションであり、代わりに追加できる他のパラメータもあります。
今の関数は以下のようになります:
特別なヘルプパラメータもあります、例えば.FORWARDHELPTARGETNAMEです。このオプションは、すべての入力されたヘルプリクエストを別のコマンドに転送します。これは、複数のコマンドで同じ情報を表示する必要がある場合に使用できます。
ヘルプを追加したので、モジュールマニフェストのバージョンを更新し、新しいバージョンを公開し、セッションのインストールされているバージョンも以前と同じように更新できます。
関数のヘルプを確認すると、より多くの情報が利用可能であることがわかります。これは、コードを見てモジュールが何をしているかをすばやく理解できない経験の浅い人にとって、関数の使用方法に関するドキュメントを含める素晴らしい方法です。

Get-Help
外部のヘルプファイルの場合、追加される情報は同じですが、情報は別のファイルに配置され、関数内でリンクされます。
AllUsers
モジュールパスを参照すると、モジュールのバージョンとインストールしたモジュールファイルのすべてが表示されます。

以前に作成した PSRepository パス C:\Repo に戻ると、たくさんの NUPKG ファイルが表示されます。これらは、Publish-Module
を使用して公開したものの圧縮バージョンです。
概要
PowerShellコンソール、PowerShell言語、スクリプトの作成に慣れたら、独自のモジュールの作成が最後のステップです。モジュールを使用すると、PowerShellで有用なツールの開発が始められます。モジュールを単一の目的に向けて設計し、正しく構築することで、時間の経過とともにコードの記述量が減少していくでしょう。コード内でモジュールの関数を参照し、そこから構築することで、コードの繰り返しを抽象化することができます。これらは後で参照するための「ラベル」であり、以前に目標を達成した方法を再考することなく、いつでも呼び出すことができます。モジュールは、既に解決済みの問題に時間を浪費しないように、同じようなコードをグループ化するための最終的な「パッケージング」です。