PowerShellモジュールパス:コピー&ペーストなしで再利用可能なコード

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コマンドを使用して確認することができます。

Listing modules with Get-Module

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

後のバージョンでもImport-Moduleを使用する場合もあります。モジュールをインストールした後にモジュールをインポートしたい場合は、次のようにImport-Moduleを使用できます。

Importing modules with Import-Module

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

Listing all available modules with Get-Module -ListAvailable

デフォルトではすべてのコマンドが表示されません

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

モジュールの作成者は、関数を非表示にしたい場合があります。それは他の関数をサポートするために使用されるもので、ユーザーには表示されません。関数を非表示にするために、作成者はマニフェストのFunctionsToExport配列からそれを除外します。ここでは、ExportedCommandsプロパティの拡張ビューが表示されています。

Viewing exported commands

モジュールのインポート

モジュールを使用するための多くの方法があります。モジュールファイルのパスを使用して手動でモジュールをインポートすることができます。これにより、モジュールのテストや更新をする際に多くの作業をする必要がなくなります。しかし、この方法ではモジュールのパスを正確に指定する必要があるため、移植性にはあまり適していません。また、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には独自のモジュールパスに含まれるモジュールがあります。

Viewing module paths with $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モジュールがインストールされていない場合に得られるものですが、それをインポートしようとします。

Module not installed

リモートモジュールをインポートするには、まずPSSessionを作成する必要があります。New-PSSessionを使用してセッションを作成できます。その後、Import-ModulePSSessionパラメーターを使用してリモートデバイス上で利用可能なモジュールをインポートします。

PS51> $AdminServer = New-PSSession -ComputerName $AdminServerName -Credential (Get-Credential)
PS51> Import-Module -Name ActiveDirectory -PSSession $AdminServer -Prefix 'Rmt'

この方法でリモートモジュールをインポートすることで、分散環境でのコードの実行が高速化されます。たとえば、自分のコンピュータで作業しているが、作業しているサーバーが米国にある場合、特定のコマンドをローカルでサーバーに対して実行するのにかかる時間はかなり長くなる可能性があります。一方、コマンドをサーバー上で実行し、出力をローカルセッションに送信すると、はるかに高速です。

モジュールのプレフィックスの追加

リモートマシンからインポートされた関数には、接頭辞を付けることもできます。このオプションは、ローカルモジュールをインポートする際に使用できますが、モジュールの異なるバージョンをテストする場合以外ではほとんど使用されません。

上記のインポートコマンドを実行した場合、コマンドを確認すると、次のように表示されます:

Viewing all available commands in a module

この場合、プレフィックスを使用してローカルモジュールでないことを示すことができます。これは、ローカルにも利用可能なモジュールをインポートする場合に使用できます。プレフィックスを追加することで、コードがどこで実行されているのかの混乱を減らすことができます。

モジュールの削除

Remove-Moduleを使用せずに、現在のセッションからモジュールを削除することもできます。これにより、モジュールファイルは削除せずに、ローカルセッションからモジュールが削除されます。モジュールを使用するためにリモートセッションを使用していた場合に使用することができます。セッションをクリーンアップしてリモートセッションを切断するために、Remove-Moduleを使用できます。

Removing a module from the session

Remove-Moduleの別の使用方法は、モジュールに変更を加える場合で、新しいPowerShellセッションを起動したくない場合です。この場合、Remove-Moduleを使用してからImport-Moduleを使用して再度ロードします。または、Import-ModuleForceパラメータを使用することもできます。これにより、モジュールのアンロードと再ロードが完了します。

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を使用しても問題は起こらないかもしれませんが、他のモジュール名との競合を引き起こす可能性があります。

これらのガイドラインを使用すると、レジストリと対話する一連の関数がある場合、次のような形式にすることができます:

function Get-ATARegistryKey {...}

function Set-ATARegistryKey {...}

モジュールマニフェスト

テキストモジュールファイルを拡張するために、モジュールマニフェストを含めることもできます。これらのファイルはPSD1拡張子を持ち、モジュールに関するメタデータが含まれます。ここには、作者の情報、モジュールの説明、他の必要なモジュールなどの情報を含めることができます。リポジトリに公開する場合、AuthorDescriptionのフィールドを入力する必要があります。

以下は、登録モジュールのマニフェストの例です。

#モジュール 'ATARegistry' のモジュールマニフェスト
#生成者:Tyler
#生成日:2019/8/11
@{
	#このマニフェストと関連するスクリプトモジュールまたはバイナリモジュールファイル
	RootModule = 'ATARegistry'
	#このモジュールのバージョン番号
	ModuleVersion = '1.0'
	#サポートされている PSEdition
	#CompatiblePSEditions = @()
	#このモジュールを一意に識別するためのID
	GUID = 'fef619fa-016d-4b11-a09d-b222e094de3e'
	#このモジュールの作成者
	Author = 'Tyler Muir'
	#このモジュールの会社またはベンダー
	CompanyName = 'Adam the Automator'
	#このモジュールの著作権表示
	Copyright = '(c) 2019 tyler. All rights reserved.'
	#このモジュールが提供する機能の説明
	Description = 'This is a test module.'
	#このモジュールに必要なWindows PowerShellエンジンの最小バージョン
	#PowerShellVersion = ''
	#このモジュールに必要なWindows PowerShellホストの名前
	#PowerShellHostName = ''
	#このモジュールに必要なWindows PowerShellホストの最小バージョン
	#PowerShellHostVersion = ''
	#このモジュールに必要なMicrosoft .NET Frameworkの最小バージョン。これはPowerShell Desktopエディションのみに適用されます。
	#DotNetFrameworkVersion = ''
	#このモジュールに必要な共通言語ランタイム(CLR)の最小バージョン。これはPowerShell Desktopエディションのみに適用されます。
	#CLRVersion = ''
	#このモジュールに必要なプロセッサアーキテクチャ(None、X86、Amd64)
	#ProcessorArchitecture = ''
	#このモジュールをインポートする前に、グローバル環境にインポートする必要のあるモジュール
	#RequiredModules = @()
	#このモジュールをインポートする前にロードする必要のあるアセンブリ
	#RequiredAssemblies = @()
	#このモジュールをインポートする前に呼び出し元の環境で実行されるスクリプトファイル(.ps1)
	#ScriptsToProcess = @()
	#このモジュールをインポートする際にロードするタイプファイル(.ps1xml)
	#TypesToProcess = @()
	#このモジュールをインポートする際にロードするフォーマットファイル(.ps1xml)
	#FormatsToProcess = @()
	#RootModule/ModuleToProcessで指定されたモジュールの内部モジュールとしてインポートするモジュール
	#NestedModules = @()
	#このモジュールからエクスポートする関数。最高のパフォーマンスのために、ワイルドカードを使用せず、エントリを削除せず、関数がない場合は空の配列を使用してください。
	FunctionsToExport = @('Get-RegistryKey','Set-RegistryKey')
	#このモジュールからエクスポートするCmdlet。最高のパフォーマンスのために、ワイルドカードを使用せず、エントリを削除せず、Cmdletがない場合は空の配列を使用してください。
	CmdletsToExport = @()
	#このモジュールからエクスポートする変数VariablesToExport = '*'
	#このモジュールからエクスポートするエイリアス。最高のパフォーマンスのために、ワイルドカードを使用せず、エントリを削除せず、エイリアスがない場合は空の配列を使用してください。
	AliasesToExport = @()
	#このモジュールからエクスポートするDSCリソース
	#DscResourcesToExport = @()
	#このモジュールとパッケージ化されたすべてのモジュールのリスト
	#ModuleList = @()
	#このモジュールとパッケージ化されたすべてのファイルのリスト
	#FileList = @()
	#RootModule/ModuleToProcessで指定されたモジュールに渡すプライベートデータ。これには、PowerShellによって使用される追加のモジュールメタデータを持つPSDataハッシュテーブルが含まれる場合もあります。
	PrivateData = @{
		PSData = @{
			#このモジュールに適用されるタグ。これらはオンラインギャラリーでのモジュールの検索に役立ちます。
			#Tags = @()
			#このモジュールのライセンスのURL
			#LicenseUri = ''
			#このプロジェクトのメインウェブサイトのURL
			#ProjectUri = ''
			#このモジュールを表すアイコンのURL
			#IconUri = ''
			#このモジュールのリリースノート
			#ReleaseNotes = ''
		} 
		#PSDataハッシュテーブルの終わり
	} 
	#PrivateDataハッシュテーブルの終わり
	#このモジュールのヘルプ情報URI
	#HelpInfoURI = ''
	#このモジュールからエクスポートされるコマンドのデフォルト接頭辞。デフォルトの接頭辞は、Import-Module -Prefixを使用してオーバーライドします。
	#DefaultCommandPrefix = ''
}

最初は intimidating に見えるかもしれませんが、Microsoft にはモジュールマニフェストを生成するために使用できる便利な cmdlet があります。含まれるコマンドは New-ModuleManifest です。上記のマニフェストを生成するには、次のように使用します:

PS51> New-ModuleManifest -Path .\Scripts\TestModule.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule 'TestModule.psm1' -FunctionsToExport @('Get-RegistryKey','Set-RegistryKey') -Description 'This is a test module.'

外部ヘルプファイル

一部のモジュールには外部ヘルプファイルも含まれている場合があります。これらはファイル名の末尾にある <ModuleName>-Help.xml で識別できます。これらの外部ヘルプファイルには、通常、関数定義のコマンドベースのヘルプに含まれる情報が含まれています。

モジュールをインポートした後、Get-Help コマンドを使用する場合、関数に # .ExternalHelp <ModulePath>-Help.xml を追加する必要もあります。非常に大きなモジュールには通常、外部ヘルプファイルが含まれており、そのためスコープ外となっています。

これらはモジュールで見られる最も一般的なファイルのタイプですが、これら以外にもファイルが存在する場合があります。テキストモジュールに加えてバイナリファイルや他の依存関係も存在することがあります。モジュールパスを探索することで、モジュール内のさまざまな追加ファイルの例を見つけることができます。

非標準のモジュールファイルを正しく公開するためには、モジュールマニフェストの FileList パラメータに他のファイルを含める必要があります。

モジュールのマニフェスト内には、現在空の多くの他のパラメータがあることに気付くでしょう。これらを使用して、モジュールの使用に関する他の要件を定義することができます。たとえば、モジュールが動作するPowerShellのバージョンを定義することができます。サポートされていないPowerShellのバージョンでモジュールをインポートしようとすると、次のようなエラーメッセージが表示されます:

Requiring certain versions of PowerShell

PSRepositories

モジュールの主要な配布オプションの1つは、PSRepositoryです。1000フィートから見ると、PSRepositoryは複数の人や複数のデバイスがモジュールファイルにアクセスできる場所です。これらは、ファイルを公開できるウェブサーバーがよく使用されます。

リポジトリにはディレクトリも使用できますが、これによりリポジトリの機能が制限されます。PSRepositoryを自分でホストすることもできますし、PowerShell Galleryのようなインターネット上で利用可能な多くのオプションを利用することもできます。自分のPSRepositoriesは、Get-PSRepositoryコマンドを使用して表示できます。

Default PowerShell NuGet repositories

デフォルトでは、エントリは1つだけであり、PowerShell Galleryになります。信頼されていないと表示されることがあるかもしれません。これは、PowerShellがPowerShell Galleryを使用すると、Microsoftによって書かれて承認されたコードを使用していない可能性があることを示すためです。これは、モジュールがそれからインストールされる前に明示的な許可を与える必要があることを意味します。

PSRepositoriesの追加

自分自身のリポジトリを追加することもできます。PowerShell Galleryを信頼するには、Get-PSRepository -Name PSGallery | Set-PSRepository -InstallationPolicy Trustedを実行するか、PowerShell Galleryからモジュールを初めてインストールする際に警告を受け入れることができます。

これらの PSRepositories との対話に使用するすべてのコマンドは、PowerShellGet モジュールにあります。関数はこちらで確認できます:

Commands in the PowerShellGet module

特定のリポジトリとの対話する前に、PowerShellGet モジュールを更新する必要がある場合があります。

モジュールの検索

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

Finding modules on the PowerShell Gallery

これにより、VMware で始まるすべてのモジュールが表示されます。これらのほとんどは VMware のものですが、モジュールの公開者を確認するために author 属性を確認する必要があります。

PowerShell Gallery には誰でもアップロードできるため、数千ものモジュールが利用可能です。つまり、使用するケースに適さないモジュールも見つかる可能性があります。見つけたモジュールの多くはオープンソースであり、モジュールの機能性を向上させるために貢献することができます。

モジュールのインストール

Install-Module コマンドを使用するには、モジュールをホストする信頼できるPSRepository が必要です。これは PowerShell Gallery、他のインターネットの PSRepository、または自己ホストサイトのいずれかです。インストールする前に Find-Module コマンドのパイプラインからモジュールを確認することもできます。

Finding modules installed from a PSRepository

MinimumVersionMaximumVersion、または RequiredVersion パラメータを使用してモジュールのバージョンを定義することもできます。

Install-Moduleを使用してインストールされたすべてのモジュールを表示するには、Get-InstalledModuleを使用します。これにより、AllUsersスコープまたはCurrentUserスコープにインストールされたすべてのモジュールがリストされます。

モジュールのアンインストール

モジュールをインストールできるようにするだけでなく、モジュールをアンインストールすることもできます。モジュールがInstall-Moduleコマンドを使用してインストールされていない場合、Uninstall-Moduleコマンドを使用してアンインストールすることはできません。

Uninstalling modules installed from a PSRepository with Uninstall-Module

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

モジュールの正常なアンインストールを確認するためには、先にインストールしたVMware.PowerCLIモジュールをアンインストールすることができます。

Uninstalling a module downloaded from the PowerShell Gallery

VMware.PowerCLIをアンインストールしたとしても、まだ多くの依存関係がインストールされていることがわかります。すべてのモジュールをアンインストールしたい場合は、Get-InstalledModule VMware.* | Uninstall-Module -Forceを使用できます。

このモジュールを完全にアンインストールするのが困難な理由は、多くの依存関係が存在するためです。さらに、これらのモジュールの一部は互いに依存しているため、Forceパラメータが必要です。

モジュールの更新

インストールおよびアンインストール方法を理解したので、インストール済みのモジュールを更新する方法について知りたいと思うかもしれません。

他のプロセスと同様に、モジュールがInstall-Moduleを使用してインストールされていない場合、PowerShellコマンドを使用して更新することはできません。最新のリリースまたは新しい特定のバージョンにモジュールを更新するには、Update-Moduleを使用できます。

また、AllowPreReleaseスイッチを使用すると、公式にリリースされていないバージョンに更新することができます。これは、経験しているバグの修正や使用したい新機能が追加された可能性があるため、役に立つ場合があります。

Updating modules with Update-Module

モジュールの検査/保存

使用前にモジュールを検証する際に非常に役立つ、あまり使われないコマンドの1つがSave-Moduleです。このコマンドを使用すると、モジュールをインストールせずにパスにダウンロードすることができます。

その後、ファイルを検査し、モジュールがバイナリモジュールでない場合はコードを開いてモジュールを構成するコードを確認することができます。これは、モジュールが悪意のある操作を行っていないことを確認するだけでなく、他の人々がモジュールをどのように構造化しているかを学ぶためにも役立ちます。

Downloading modules with Save-Module

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

VMware.PowerCLI module contents

これは、エンドユーザーライセンス契約などの非標準のモジュールファイルがモジュールに含まれる場合があることを示す良い例です。

独自のモジュールの作成

他人のモジュールとの対話方法を学びました。次は、自分自身のモジュールを作成して、スケーラビリティのためにコードを最適化する方法を学びます。

テンプレートファイルの作成

まず、モジュールファイルを格納するためのフォルダを作成する必要があります。コンテナを作成したら、モジュールファイルを作成する必要があります。モジュールファイルの名前は、フォルダの名前と同じである必要があります。そうしないと、モジュールを公開しようとしたときにPowerShellがモジュールを正しく検出できません。

PS51> New-Item -Path .\Scripts -Name ATARegistry -ItemType Directory
PS51> New-Item -Path .\Scripts\ATARegistry -Name ATARegistry.psm1

また、マニフェストも使用したい場合は、コンテナとモジュールファイルと同じ名前にする必要があります。

PS51> New-ModuleManifest -Path .\Scripts\ATARegistry\ATARegistry.psd1 -Author 'Tyler Muir' -CompanyName 'Adam the Automator' -RootModule ATARegistry.psm1 -Description 'Used for interacting with registry keys'

コンテナ、モジュールファイル、マニフェストファイルがあれば、完全に機能するモジュールができます。このモジュールをPSRepositoryに公開し、任意の場所にインストールすることができます。ただし、モジュールファイルが空であるため、あまり役立たないかもしれません。それでも、これらのファイルを使用してリポジトリが正常に動作するかをテストすることはできます。

PSRepositoryの登録

モジュールを公開する前に、別のPSRepositoryをセッションに追加する必要があります。テストには、ローカルパスをPSRepositoryとして使用できます。セットアップと解除が容易です。

通常、ディレクトリを使用してPSRepositoryを設定する場合、複数のコンピュータからアクセスできるようにする必要があります。次のようにしてローカルリポジトリを作成できます:

PS51> New-Item -Path C:\ -Name Repo -ItemType Directory
PS51> Register-PSRepository -Name 'LocalRepo' -SourceLocation 'C:\Repo' -PublishLocation 'C:\Repo' -InstallationPolicy Trusted

ただし、PSRepositoryからのダウンロードのみで、公開しない場合は、PublishLocationパラメータを除外できます。

モジュールの公開

インストールポリシーを信頼済みに設定しているため、リポジトリからモジュールをインストールする際に確認のメッセージは表示されません。新しいPSRepositoryを使用して、Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepoコマンドを使用してモジュールを公開できます。

モジュールを公開した後は、上記のコマンドを使ってモジュールを検索し、インストールすることができます。

モジュールをインストールしたので、Get-Moduleコマンドを使用してローカルセッションにインポートされたモジュールを確認できます。マニフェストのFunctionsToExport配列に関数を追加していないため、ExportedCommandsプロパティは空です。

No exported commands

モジュールへの追加

モジュールを公開およびインストールできることがわかったので、機能を追加してみましょう。次のように、レジストリキーを返す関数を追加できます:

function Get-ATARegistryKey {
    param (
        [string]$Path
    )
    Get-Item $Path
}

マニフェストをそのままにして新しいモジュールをアップロードしようとすると、2つの問題が発生します。まず、マニフェストファイルでモジュールのバージョンを変更していないため、モジュールのバージョンが既にリポジトリに存在するというエラーが表示されます。

モジュールの関数のエクスポート

もう一つの問題は、モジュールをインポートした後でもExportedCommandsプロパティに関数が表示されないことです。なぜなら、新しい関数をマニフェストに追加していないからです。

FunctionsToExportリストに関数をリストアップしなくても、関数は使用できますが、見つけるのが困難になります。

空の配列を定義しない限り、@()を使用してFunctionsToExportを定義しないと、すべての関数、変数、エイリアスがデフォルトでエクスポートされます。

これらの2つの問題を修正するには、次のようにモジュールファイルを更新します:

ModuleVersion = '1.1'
FunctionsToExport = 'Get-RegistryKey'

関数をモジュールに追加し、マニフェストをこれらの変更に反映することができたら、前と同じコマンドを使用して新しいバージョンのモジュールを公開できます。

PS51> Publish-Module -Name .\Scripts\ATARegistry -Repository LocalRepo.

FunctionsToExportとExport-ModuleMemberの選択

PowerShellのモジュールメンバーのエクスポートには、2つの類似した機能があります。どちらを選ぶかは、ニーズに応じて異なりますが、どちらも正しい方法です。

関数のエクスポートを動的に制御する場合は、関数のリストを渡すことができるExport-ModuleMemberを使用します。通常、これは複数の個別の関数PS1ファイルをドットソース化する場合に使用されます。内部関数をプライベートフォルダに分け、エクスポート可能な関数をパブリックフォルダに分けることで、パブリック関数をすべてExport-ModuleMember関数に渡すことで簡単にエクスポートできます。

A few notes about Export-ModuleMember:

  • Export-ModuleMemberFunctionsToExportの動作を上書きするため、Export-ModuleMemberコマンドが使用されると、FunctionsToExportは効果を持ちません。
  • Export-ModuleMemberは、明示的に定義しない限り、変数やエイリアスをエクスポートしませんが、FunctionsToExportはそれらの値をエクスポートします。
  • 複数のExport-ModuleMemberコマンドを使用でき、優先度ではなくスタックされます。

機能リストに変更がない場合、モジュールマニフェストのFunctionsToExport構成を使用すると、明示的に変数やエイリアスをエクスポートする必要はありません。

モジュールの更新

次に、セッション内のモジュールを更新して、更新されたファイルを使用できるようにします。 Update-Module ATARegistryを使用して、リポジトリに公開した更新をダウンロードします。

Exported commands now show up

これで、新しいバージョンのモジュールが表示され、マニフェストで定義した関数が表示されることがわかります。

ヘルプコンテンツの作成

早期に紹介されたオプションの1つは、PowerShellに組み込まれたヘルプシステムです。おそらく、関数に対してGet-Helpを使用したことがあるかもしれません。この情報は、2つの主要な方法で追加できます。

最初の方法は、コメントベースのヘルプを関数定義に追加することです。これは、多くのモジュール作成者が実装する方法です。もう1つの方法は、外部のヘルプファイルを使用することです。 Fullパラメータを使用して、ヘルプが提供するすべての情報を表示できます。

Finding help with Get-Help

ご覧のように、実際にはあまり情報がなく、手に入る情報もおそらく誰にとっても役に立たないでしょう。

これらのフィールドをヘルプシステムで埋めるために、モジュールファイルにコメントベースのヘルプを追加することができます。コメントベースのヘルプのすべてのオプションについては、Get-Help about_Comment_Based_Helpを使用して読むことができます。

今は、関数を以下のように更新できます。これは最も一般的に使用されるヘルプパラメータのリストですが、これらはすべてオプションであり、代わりに追加できる他のパラメータもあります。

今の関数は以下のようになります:

 function Get-RegistryKey {
	<#
	    .SYNOPSIS
	    提供されたパスを使用してレジストリキーを返します。
	    .DESCRIPTION
	    この関数は、提供されたレジストリキーの情報を返すためにGet-Itemコマンドを使用します。
	    .PARAMETER Path
	    レジストリキーを検索するパスです。
	    .EXAMPLE
	    Get-RegistryKey -Path 'HKLM:\HARDWARE\DESCRIPTION\System'
	    .INPUTS
	    System.String
	    .OUTPUTS
	    Microsoft.Win32.RegistryKey
	    .NOTES
	    このモジュールは、良くドキュメント化された関数の例です。
	    .LINK
	
ATA Learning
#>
param( [string]$Path ) Get-Item $Path }

特別なヘルプパラメータもあります、例えば.FORWARDHELPTARGETNAMEです。このオプションは、すべての入力されたヘルプリクエストを別のコマンドに転送します。これは、複数のコマンドで同じ情報を表示する必要がある場合に使用できます。

ヘルプを追加したので、モジュールマニフェストのバージョンを更新し、新しいバージョンを公開し、セッションのインストールされているバージョンも以前と同じように更新できます。

関数のヘルプを確認すると、より多くの情報が利用可能であることがわかります。これは、コードを見てモジュールが何をしているかをすばやく理解できない経験の浅い人にとって、関数の使用方法に関するドキュメントを含める素晴らしい方法です。

Getting full help content with Get-Help

外部のヘルプファイルの場合、追加される情報は同じですが、情報は別のファイルに配置され、関数内でリンクされます。

AllUsers モジュールパスを参照すると、モジュールのバージョンとインストールしたモジュールファイルのすべてが表示されます。

Folder name is the module version

以前に作成した PSRepository パス C:\Repo に戻ると、たくさんの NUPKG ファイルが表示されます。これらは、Publish-Module を使用して公開したものの圧縮バージョンです。

概要

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

Source:
https://adamtheautomator.com/powershell-modules/