Почему при импорте с параметром -MaximumVersion, установленным на более низкую версию, запускается более новая версия модуля PowerShell?

У меня есть сценарий сборки, который зависит от более старой версии одного из наших модулей. Версия 1.0.1. Я добавил -MaximumVersion 1.0.1 к команде Import-Module. Когда запускается сценарий сборки, он не работает, и ошибка показывает, что выполняется код версии 2.1.0 модуля.

Import-Module DrilQuip.Build -MaximumVersion 1.0.1 -Force

Создание следующего номера версии ... Свойство VersionFilePath не может быть найдено для этого объекта. Убедитесь, что свойство существует. В C: \ Users \ svcTFSBuildProd \ Documents \ WindowsPowerShell \ Modules \ DrilQuip.Build \ 2.1.0 \ DrilQuip.Build.psm1: 253 символа: 5

Я пробовал с переключателем -Force и без него, но это не имеет значения.

Я использовал Get-Module DrilQuip.Build -ListAvailable, чтобы убедиться, что на компьютере установлена ​​версия 1.0.1.

Как я могу гарантировать, что скрипт импортирует и использует старую версию модулей?

Обновление 1

Добавлен переключатель -Verbose, чтобы получить более подробную информацию о том, что происходит. Вот результаты:

VERBOSE: загрузка модуля из пути 'C: \ Program Files \ WindowsPowerShell \ Modules \ DrilQuip.Build \ 1.0.1 \ DrilQuip.Build.psd1'. VERBOSE: заполнение свойства RepositorySourceLocation для модуля DrilQuip.Build.

Создание следующего номера версии ... Свойство VersionFilePath не может быть найдено для этого объекта. Убедитесь, что свойство существует. В папке C: \ Users \ svcTFSBuildProd \ Documents \ WindowsPowerShell \ Modules \ DrilQuip.Build \ 2.1.0 \ DrilQuip.Build.psm1: 253 символа: 5 + $ Matches = Select-String -Path $ global : BuildConfig.VersionFilePat ...

Это показывает, что один и тот же модуль был установлен в 2 разных местах. Расположение C: \ Users \ svcTFSBuildProd ..., похоже, превосходит расположение C: \ Program Files \ WindowsPowerShell ...

Я думаю, что это связано с областью Machine vs User при установке модуля. Я вернусь и удалю модули с пользовательской областью действия и установлю все версии модуля с областью действия компьютера и посмотрю, поможет ли это.

Обновление 2

Я удалил все версии модуля из папки пользовательской области, а затем снова попробовал сценарий. Он по-прежнему не работает, но теперь обе версии модуля поступают из одной и той же папки модуля.

VERBOSE: загрузка модуля из пути 'C: \ Program Files \ WindowsPowerShell \ Modules \ DrilQuip.Build \ 1.0.1 \ DrilQuip.Build.psd1'. VERBOSE: заполнение свойства RepositorySourceLocation для модуля DrilQuip.Build. Создание следующего номера версии ... Свойство VersionFilePath не может быть найдено для этого объекта. Убедитесь, что свойство существует. В папке C: \ Program Files \ WindowsPowerShell \ Modules \ DrilQuip.Build \ 2.0.4 \ DrilQuip.Build.psm1: 251 символ: 5

Поскольку новая версия все еще превосходит максимальную версию, я попросил мою теорию о том, что область действия пользователя превосходит объем машины, не является реальной проблемой. Что-то еще происходит.

Я снова запустил Get-Module -Name DrilQuip.Build -ListAvailable и заметил, что ModuleType отличается. В версии 1.0.1 типом является Манифест, но в версиях 1.1.1 и 2.0.4 типом является Скрипт. Возможно, эта разница является причиной проблемы.

ModuleType Version    Name          
---------- -------    ----          
Script     2.0.4      DrilQuip.Build
Script     1.1.1      DrilQuip.Build
Manifest   1.0.1      DrilQuip.Build

Я удалю все модули и переустановлю их из репозитория.


person Matthew MacFarland    schedule 27.02.2019    source источник
comment
Добавьте -Verbose к вызову Import-Module, чтобы убедиться, что он хотя бы утверждает, что загружает правильную версию в этот момент. Возможно, более поздний код импортирует более новую версию модуля, например с помощью оператора using module.   -  person mklement0    schedule 28.02.2019
comment
Что, если вы попытаетесь загрузить конкретный модуль? Get-Module DrilQuip.Build -ListAvailable | Where-Object {$ _. Version -eq 1.0.1} | Импорт-Модуль-Force   -  person halv    schedule 28.02.2019
comment
@ mklement0 Это очень хорошее предложение по устранению неполадок! Я добавил переключатель -Verbose, и он подтверждает, что версия 1.0.1 загружается, но затем код, вызывающий функцию, по-прежнему получает версию 2.1.0 в соответствии с выводом ошибки. Я добавил подробности в раздел обновлений своего вопроса.   -  person Matthew MacFarland    schedule 28.02.2019


Ответы (1)


Более старая версия модуля 1.0.1 имеет тип Манифест, а все последующие версии имеют тип Скрипт. Следующая версия модуля 1.0.2 также совместима с моим сценарием сборки, поэтому я изменил параметр -MaximumVersion на 1.0.2.

Перед тем, как попробовать это, я также удалил все версии модуля на компьютере, а затем установил только версии 1.0.2 и 2.1.0, которые действительно необходимы. Я запустил PowerShell от имени администратора, поэтому оба модуля были установлены в папку C:\Program Files\WindowsPowerShell\Modules

PS C:\Program Files\WindowsPowerShell\Modules\DrilQuip.Build> get-module DrilQuip.Build -li

    Directory: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     2.1.0      DrilQuip.Build                      {Start-Build, Write-FileCopyResult, Invoke-MSBuild, New-Da...
Script     1.0.2      DrilQuip.Build                      {Get-NextVersion, Set-TfsWorkspaceFileTime}

После этих изменений сценарий сборки работает и использует версию кода 1.0.2, как и ожидалось.

VERBOSE: Loading module from path 'C:\Program 
Files\WindowsPowerShell\Modules\DrilQuip.Build\1.0.2\DrilQuip.Build.psd1'.
VERBOSE: Populating RepositorySourceLocation property for module 
DrilQuip.Build.
VERBOSE: Loading module from path 'C:\Program 
Files\WindowsPowerShell\Modules\DrilQuip.Build\1.0.2\DrilQuip.Build.psm1'.
VERBOSE: Importing function 'Get-NextVersion'.
VERBOSE: Importing function 'Set-TfsWorkspaceFileTime'.

Creating next version number...
New version: 10.2.10928.11004

Основываясь на комментарии mklement0, похоже, что вся проблема в том, что версия 1.0.1 была неправильно настроена, и поэтому никакие функции не были импортированы. Подробный вывод Import-Module подтверждает это. Когда скрипт вызывал функцию Get-NextVersion, PowerShell использовал автоматическую загрузку модуля, чтобы найти и загрузить версию модуля, у которой была эта функция.

В манифесте версии 1.0.1 отсутствовало значение для RootModule. Эта ошибка была исправлена ​​в версии 1.0.2. Модуль использует Export-ModuleMember для экспорта функций вместо параметра FunctionsToExport в манифесте. Поскольку в 1.0.1 не было корневого модуля, установленного в файл psm1, у него не было возможности экспортировать функции.

person Matthew MacFarland    schedule 28.02.2019
comment
Модуль Manifest - это модуль, у которого нет записи RootModule (устаревшая: ModuleToProcess) в его файле манифеста (*.psd1), который обычно требует заполнения NestedModules. Если вы попробуете свой 1.0.1 модуль изолированно, он действительно будет работать? Обратите внимание, что ваш подробный вывод при загрузке 1.0.1 не показывает никаких команд, импортируемых в сеанс. - person mklement0; 28.02.2019
comment
Так что, возможно, произошло следующее: ваш импорт 1.0.1 был успешным, но никакие команды не были добавлены в сеанс. Когда вы позже попытались выполнить команду, которая, как вы думала, была импортирована через 1.0.1, механизм автоматической загрузки модуля мог обнаружить эту команду, а затем неявно загрузить самый последний модуль, который содержит эту команду. - person mklement0; 28.02.2019
comment
@ mklement0 Звучит как очень хорошее объяснение того, что произошло на самом деле. - person Matthew MacFarland; 28.02.2019