1

モジュール ( MyModule ) が非標準のパス、つまり にリストされている通常の場所の下にありません$env:PSModulePath -split ";"。ただし、 「開発」コピーの作業を続けながら、MyModuleへの「運用」パスをその環境変数に追加しました。

何かをデバッグしようとしているときに$VerbosePreference = "Continue"、次のコマンドを使用してモジュールを (で) ロードしたところ、一見矛盾するように見える 2 行の詳細出力がすぐに表示されました。

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Loading module from path 'D:\Dev\usera\MyModule2\MyModule.psm1'.

特に 2 番目のパスが正しくないため、Import-Module がモジュールを 2 回ロードしているように見える理由を理解したいと思います。


もっと詳しく:

モジュールのフォルダー構造は次のとおりです。

MyModule\MyModule.psd1
MyModule\MyModule.Test-Module.xml
MyModule\MyModule1\MyModule.psm1
MyModule\MyModule2\MyModule.psm1

注 (1) このモジュールの古い「バージョン 1」を MyModule1 サブフォルダーに保持し、更新された「バージョン 2」ファイルを MyModule2 サブフォルダーに置き、(2) .xml ファイルがカスタムによって使用されていることに注意してください。 module-testing スクリプトを使用して、テスト ケースを一覧表示します。後者は無視できると確信しています。

私のモジュール マニフェスト (.psd1) ファイルには次のものが含まれており、他のすべての行は空白またはコメントになっています。

@{
  RootModule = '.\MyModule2\MyModule.psm1'
  ModuleVersion = '2.0.0.0'
  GUID = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
  Author = 'Old Developer (v1.x) & New Developer (v2.x)'
  CompanyName = 'MyCompany'
  Copyright = '(c) 2013-2015 MyCompany. All rights reserved.'
  Description = 'Really useful functions'
  FileList = @(
    '.\MyModule.psd1'
    '.\MyModule.Test-Module.xml'
    '.\MyModule1\MyModule.psm1'
    '.\MyModule2\MyModule.psm1'
    '.\MyModule2\Examples\Archive-FilesWithCompression.ps1'
  )
}

明らかに、ファイルに相対パスを使用しました。RootModuleキー; モジュールを共有するときにモジュールがどこにコピーされるかがわからないため、これが必要です。

Verbose 出力に戻ると、2 つの行が (1) PSD1 ファイルへの正しいパスと (2) PSM1 ファイルへの無効なパスを示していることがわかります。Set-Location2 番目のパスには小文字のユーザー名が含まれていることに気付きました。これは、テスト前にたまたま入力した方法です。したがって、最初のパスは、コマンドレットに指定されたパスに MyModule.psd1 を追加することによって取得されImport-Module、2 番目のパスは (Get-Location) と RootModule パスの連結のように見えます。

これは、このモジュールでのみ発生するようです。同じ「ルート」フォルダーの下に、この動作を示さない他のフォルダーがあります。

4

1 に答える 1

0

うーん。わかった。少なくとも部分的には解決できたかもしれません...

Import-Module コマンドレットを実行していた場所の下にあるMyModule2サブフォルダーのコピーを誤って作成してしまいました。そのフォルダーを削除すると、詳細な出力がより意味のあるものになり始めました。

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....

これは、PowerShell がマニフェスト ファイル内のRootModuleを解決するときに、最初に現在のパスの下を検索し、何も見つからない場合はメイン モジュール フォルダーを検索することを意味すると思います。マニフェスト内の相対パスは常に、現在の場所ではなく、PSD1 ファイルに相対的であると予想されるため、これは直感に反するものです。

その後、すぐにモジュールを再度インポートしようとすると、次のようになります。

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Importing function '<function>'.
....

つまり、冗長出力の 2 行ではなく、「モジュールのロード」行が 1 行だけです。次に、スイッチを試した-Forceところ、次の結果が得られました。

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule -Force

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Removing the imported "<function>" function.
....
VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....
VERBOSE: Importing function '<function>'.
....

そのため、モジュールが最初にインポートされたとき、または強制的に再インポートされたときに、詳細出力の 2 行が表示されるように見えますが、モジュールが既にセッションの一部である場合は、最初の行のみが表示されます。

また、最終的に、冗長出力が関数のエクスポートとインポートを区別していることに気付きました。関数は、PSM1 ファイルで定義されている順序でエクスポートされますが、アルファベット順にインポートされます。これは、関数定義が PSM1 ファイルから再読み込みされているかどうかに応じて、1 段階または 2 段階のプロセスが使用されていることを示唆しています。

または、質問にもっと直接的に答えるために、.psm1 ファイルを読み取る必要がある場合は "モジュールを読み込んでいます..." という行が 2 行あり、PowerShell がモジュールとその内容を既に認識している場合は 1 行しかないようです。

于 2016-01-21T12:25:44.403 に答える