Import-Module Подробный вывод подразумевает, что модуль загружен дважды

У меня есть модуль (MyModule) по нестандартному пути, то есть не в обычных местах, перечисленных в $env:PSModulePath -split ";". Однако я добавил «производственный» путь к MyModule к этой переменной среды, пока продолжаю работать над «разрабатываемой» копией.

Пытаясь что-то отладить, я загрузил модуль (с $VerbosePreference = "Continue") с помощью следующей команды и сразу увидел две, казалось бы, противоречивые строки вывода Verbose:

[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'.

Я хотел бы понять, почему кажется, что Import-Module загружает модуль дважды, тем более что второй путь неверен.


ПОДРОБНЕЕ:

Структура папок для модуля:

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; это необходимо, так как я не могу быть уверен, куда будет скопирован модуль, когда я расскажу о нем.

Возвращаясь к подробному выводу, я вижу, что две строки показывают (1) правильный путь к файлу PSD1 и (2) недопустимый путь к файлу PSM1. Я заметил, что второй путь имеет имя пользователя в нижнем регистре, именно так я набрал его, когда Set-Location перед тестированием. Итак, похоже, что первый путь был выбран путем добавления MyModule.psd1 к пути, заданному командлету Import-Module, а второй - это конкатенация (Get-Location) и пути RootModule.

Это только кажется, что происходит с этим модулем. У меня есть другие в той же «корневой» папке, которые не демонстрируют такого поведения.


person Charlie Joynt    schedule 21.01.2016    source источник


Ответы (1)


Гм. OK. Возможно, я решил это, по крайней мере, частично ...

Я случайно сделал копию подпапки MyModule2 в том месте, откуда я запускал командлет Import-Module. Как только я удалил эту папку, подробный вывод стал более понятным:

[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>'.
....

То есть только одна строка «загружающий модуль», а не две строки подробного вывода. Затем я попробовал переключатель -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>'.
....

Таким образом, кажется, что две строки подробного вывода появляются, когда модуль впервые импортируется или принудительно повторно импортируется, но если он уже является частью сеанса, вы видите только первую строку.

Кроме того, я наконец заметил, что подробный вывод различает экспорт функций и импорт их. Функции экспортируются в том порядке, в котором они определены в файле PSM1, но импортируются в алфавитном порядке. Это предполагает, что используется одноэтапный или двухэтапный процесс в зависимости от того, перечитываются ли определения функций из файла PSM1, что связано с тем, видим ли мы одну или две строки подробного вывода.

Или, чтобы ответить на вопрос более прямо, кажется, что есть две строки, говорящие «Загрузка модуля ...», когда ему нужно прочитать файл .psm1, и только одна строка, когда PowerShell уже знает о модуле и его содержимом.

person Charlie Joynt    schedule 21.01.2016