Манифест модуля PowerShell - автоматическая загрузка необходимого модуля

Я создаю модуль, который зависит от нескольких других модулей, которые мне нужно загрузить в глобальную среду. Я попытался создать сценарий и использовать ScriptsToProcess для импорта модулей, но похоже, что проверка RequiredModules происходит до запуска ScriptstoProcess.

Есть ли в манифесте модуля хороший и понятный способ одновременно требовать модуль и загружать его автоматически, если он еще не загружен? Если модуль не может быть загружен, RequiredModule выдаст ошибку.


person Andy Schneider    schedule 30.03.2011    source источник


Ответы (2)


В PowerShell 3 и более поздних версиях RequiredModules загружаются автоматически.

Это также единственный способ убедиться, что люди, использующие PowerShellGet (т. Е. галерею PowerShell), устанавливают ваши зависимости, если вы собираетесь распространять модуль.

Он все равно не сработает, если требуемые модули отсутствуют, но в остальном работает именно так, как вы этого хотите.

В PowerShell 2 нет возможности автоматически загружать RequiredModules.

В любом случае пользователи могут вручную загрузить требования, набрав Import-Module RequiredModule, YourModule - они не получат второй экземпляр, если он уже импортирован ...

Вместо этого вы также можете указать модуль в NestedModules. Даже в PowerShell 2 они загружаются «внутри» вашего модуля, но не кажется отрицательно влиять на ресурсы, когда они уже загружены. Однако, как напомнил мне @JasonMArcher, в PowerShell 2 NestedModules выгружаются вместе с вашим модулем, если ваш модуль выгружается (через Remove-Module), и это происходит , даже если они были предварительно загружены отдельно с помощью пользователь, что может привести к созданию действительно странных отчетов об ошибках, поскольку ваши пользователи этого не ожидают.

Другой вариант, который работает во всех версиях PowerShell, - это вызвать Import-Module в верхней части вашего модуля (в сценарии psm1 после проверки, чтобы убедиться, что модуль еще не загружен) с установленным -ErrorAction Stop так что импорт вашего модуля не удастся, если импорт зависимого модуля не удастся.

if (!(Get-Module Dependency)) { ## Or check for the cmdlets you need
    ## Load it nested, and we'll automatically remove it during clean up
    Import-Module Dependency -ErrorAction Stop
}

Собственно, если вы хотите проверить версии ...

if (!(Get-Module Dependency | Where { $_.Version -ge "2.5" )) { 
    ## Load version 2.5 (or newer), or die 
    Import-Module Dependency -Version 2.5 -ErrorAction Stop
}

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

person Community    schedule 30.03.2011
comment
Но вложенные модули удаляются, если удаляется ваш модуль. - person JasonMArcher; 30.03.2011
comment
Да, даже, если они были загружены (вручную) до загрузки вашего модуля. Потенциально некрасивая ошибка. Позвольте мне добавить второй вариант ... - person Jaykul; 30.03.2011
comment
Повторный импорт мало что даст, за исключением того, что он сделает модуль вложенным, если вы не используете флаг -Global. - person JasonMArcher; 30.03.2011
comment
Я считаю, что сейчас это устарело. - person jpmc26; 17.02.2017
comment
Спасибо @ jpmc26, я обновил его, чтобы включить информацию о версии. - person Jaykul; 23.02.2017

PowerShell V3 работает несколько иначе. Требуемые модули теперь загружаются при загрузке манифеста с указанным ключом. Кроме того, удаление модуля не выгружает требуемый модуль, независимо от того, как этот модуль был загружен. Интересно, что -Force, похоже, не показывает автозагрузку требуемых модулей.


Изменить: если ваш модуль не находится в одном из местоположений по умолчанию, вам нужно будет добавить путь к этому модулю (или родительской папке, в которой находится модуль) в переменную $env:PSModulePath.


Боковое примечание: начиная с PSv3 есть поддержка команды #Requires в скриптах. Вы можете использовать это, чтобы (1) попытаться загрузить зависимость модуля в ваш скрипт и (2) завершить работу, если модуль не загружен / не может быть загружен.

#Requires -Modules ModuleName1,ModuleName2

Для этого также необходимо, чтобы модули находились где-то в $env:PSModulePath, который должен быть установлен перед запуском скрипта.

person tfl    schedule 10.05.2012
comment
Для этого может потребоваться, чтобы модули находились по одному из путей в $env:PSModulePath, иначе PowerShell не найдет требуемый модуль. - person Charlie Joynt; 02.03.2016