Windows PowerShell: Windows PowerShell のカスタム ツールをパッケージ化して配布する

ドット ソース形式でファイルを読み込んで興味深い操作を実行することは可能ですが、注意しないと制限事項につまづくことがあります。

Don Jones

ドット ソース形式でファイルを読み込むのは便利な手段ですが、後で不要になったり、他のものと競合することが判明したときに、コマンドを削除するのが困難であるという難点があります。先月のコラムでは、コマンドをスタンドアロンのパラメーター化した再利用可能なツールにする方法を紹介しましたが、対処しなければならない注意事項が 2 つあることが判明しました。

このツールは、Windows PowerShell の高度な関数 (通称、スクリプト コマンドレット) として作成しました。1 つ目の問題は、スクリプト自体が少し使用しづらいことです。スクリプトには関数が含まれているので、単にスクリプトを実行しただけでは何も起こりません。スクリプトを変更して、関数を実行するのに必要なコマンドを追加するか、ドット ソース形式でシェルにスクリプトを読み込んで、関数をグローバル コマンドとして使用できるようにする必要があります。

2 つ目の問題は、スクリプトに 2 つの関数が含まれていることです。1 つ目の Get-OSInfo 関数は、皆さんにご利用いただきたいもので、2 つ目の OSInfoWorker 関数では、実際の処理が行われます。問題は、OSInfoWorker が直接実行する関数ではないことです。ドット ソース形式を使用した場合、OSInfoWorker 関数を隠す (プログラミング用語では、プライベート関数にする) 方法がありません。ですが、スクリプトをスクリプト モジュールにすると、どちらの問題にも対応できます。

モジュールについて

Windows PowerShell では、バイナリ、スクリプト、およびマニフェストという 3 つの基本的な種類のモジュールがサポートされています。バイナリ モジュールは、コマンドレットやプロバイダーなどの要素をシェルに追加する Visual Studio に組み込まれている DLL で構成されています。スクリプト モジュールは、シェルに 1 つ以上の関数を追加できる単体のスクリプトです。マニフェスト モジュールには、バイナリ拡張、スクリプトなど複数のコンポーネントを含めることができます。ここでは、最も簡単に作成できるスクリプト モジュールを使用することにしました。

スクリプト モジュールには、次の 3 つの要件があります。

  1. シェルに追加される関数が主な構成要素となっている有効な Windows PowerShell スクリプトであること
  2. .ps1 ではなく .psm1 というファイル拡張子を使用していること
  3. コンピューターの特定のフォルダーに配置されていること

実際のところ、最後の要件は、利便性を考慮した提案のようなものです。Windows PowerShell では、インストール時に、PSModulePath という名前のシステム全体で有効な環境変数が定義されます。この環境変数は、システムの Path 環境変数と同じように機能します。シェルでは、名前でモジュールを検索するときに、この環境変数に格納されているフォルダーを自動的に検索します。

既定では、2 つのモジュール パスが定義されています。1 つは System32 フォルダー階層にあります。これは、マイクロソフトが提供するモジュール用のパスです。もう 1 つは、ドキュメント フォルダーにあります。こちらは、皆さんが独自に作成したモジュール用のパスです。ここでは後者を使用します。もちろん、このパスは変更可能で、PSModulePath 環境変数に新しいパスを追加することもできます。たとえば、共有モジュールの格納に使用する一元管理されたパスを定義できます。

ここで使用するパスは \[マイ ]ドキュメント\WindowsPowerShell\Modules です。Windows XP では、"マイ ドキュメント" と表示されますが、Windwos Vista 以降では "ドキュメント" と表示されます。WindowsPowerShell フォルダーは、既定で存在するものではなく、自分で作成する必要があります。また、Modules サブフォルダーも同様に既定では存在しないので、このフォルダーも自分で作成する必要があります。

PSModulePath 環境変数に格納されている場所にモジュールを配置しない場合は、モジュールを読み込むときに完全なパスとファイル名を指定する必要がありますが、必要な作業は、それだけです。頻繁に使用するモジュールの完全なパスを指定しなければならないと不便なので、個人的には、PSModulePath 環境変数で定義されているパスを使用することが多いです。

モジュールを作成する

先月のスクリプトの最後に 3 つのコマンドを追加します (変更したスクリプトは、ここからダウンロードできます)。

New-Alias goi Get-OSInfo
Export-ModuleMember -function Get-OSInfo
Export-ModuleMember -alias goi

1 つ目のコマンドでは goi というエイリアスを定義しています。これは Get-OSInfo 関数のエイリアスです。残り 2 つは、スクリプト モジュール内で使用した場合にのみ有効なコマンドです。

既定では、シェルにモジュールを読み込むと、そのモジュールに含まれる関数は、すべて使用できるようになります。ですが、Export-ModuleMember コマンドレットを使用すると、明示的に指定した関数とそのエイリアスのみが使用できるようになります。

このモジュールを使用しているユーザーは、goi エイリアスと Get-OSInfo 関数が表示されるようになります。指定しなかった OSInfoWorker 関数は非表示になります。モジュール内からであれば任意の関数で OSInfoWorker 関数を呼び出せますが、OSInfoWorker 関数は、プライベート関数なので直接アクセスすることはできません。

スクリプトには 3 つのコマンドを追加したので、スクリプトに適切な名前を付けて、然るべき場所に格納する必要があります。たとえば、このモジュールに MyModule という名前を付けたとしましょう。この場合、このスクリプト ファイルは、\[マイ ]ドキュメント\WindowsPowerShell\Modules\MyModule\MyModule.psm1 に配置する必要があります。

スクリプトは、Modules フォルダーのサブフォルダーに配置する必要があります。また、サブフォルダーとスクリプト ファイルの両方にモジュールの名前を付ける必要があることにも注意してください。この処理が終わったら、Import-Module MyModule というコマンドを実行して作成したモジュールをシェルに読み込めます。

これは他のユーザーにスクリプトを簡単かつ効率的に配布できる方法です。1 つのスクリプト ファイルに含められる関数とエイリアスの数に制限はありません。適切な場所 (だれかがフル パスを指定することを望んでいる場合は、そのパスも適切な場所であると見なします) に配置されていれば、他のユーザーが簡単にモジュールを読み込んで、スクリプトに含まれる関数を使用することができます。

Don Jones

Don Jones は、Concentrated Technology の創設者で、ConcentratedTech.com (英語) で Windows PowerShell や他のテクノロジに関する質問に答えています。また、Nexus.Realtimepublishers.com (英語) の創設者でもあり、このサイトでは、彼の多くの著書が無料でオンライン ブックとして提供されています。

補足情報

今月のコラムでは、補足資料としてサンプル コードを提供しています。ここからダウンロードして、ご利用ください。

Don Jones が TechMentor Spring 2011 で担当する 3 日間の実践的なワークショップへの登録締め切りまで、あとわずかです。詳細については、TechMentorEvents.com (英語) を参照してください。

関連コンテンツ