Работает ли #Requires в скриптах модуля?

Рассмотрим следующий скрипт модуля:

MyWebApp.psm1:

#Requires -Version 4
#Requires -Modules WebAdministration

function Test-MyWebApp() {
    return ((Get-WebApplication 'myapp') -ne $null)
}

(Export-ModuleMember опущен для простоты. Скрипт все еще работает как модуль без него.)

Если бы это было ps1 сценарий #Requires комментарии вверху заставят PowerShell выдавать ошибку, если

  • Версия была ниже 4
  • Модуль WebAdministration не может быть загружен (импортирован)

Но если я попытаюсь импортировать это с помощью Import-Module, они имеют какой-либо эффект? #Requires в документации просто говорится "сценарии", но не уточняется, считаются ли модули сценариев "сценариями" или нет. Что я могу сделать вместо этого, если нет?

1 ответ

Решение

Нет, это воспринимается как нормальный комментарий

Нет, #Requires комментарии не обрабатываются, когда psm1 Сценарий выполняется путем вызова Import-Module,

Если мы сохраним сценарий в вопросе как MyWebApp.psm1 а также MyWebApp.ps1 на машине, которой не хватает WebAdministration По модулю получаем следующий результат:

PS> .\MyWebApp.ps1
.\MyWebApp.ps1 : The script 'MyWebApp.ps1' cannot be run because the following modules that are specified by the
"#requires" statements of the script are missing: WebAdministration.
At line:1 char:1
+ .\MyWebApp.ps1
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException
    + FullyQualifiedErrorId : ScriptRequiresMissingModules

PS> Import-Module .\MyWebApp.psm1
PS>

Импорт модуля завершен успешно, и теперь функция существует в текущей области. Но функция потерпит неудачу:

PS> Test-MyWebApp
Get-WebApplication : The term 'Get-WebApplication' is not recognized as the name of a cmdlet, function, script file,
or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
try again.
At .\MyWebApp.psm1:5 char:14
+     return ((Get-WebApplication 'myapp') -Eq $null)
+              ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-WebApplication:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Даже -Version проверка игнорируется. Если мы увеличим его до 5 на машине с PowerShell 4:

PS> .\MyWebApp.ps1
.\MyWebApp.ps1 : The script 'MyWebApp.ps1' cannot be run because it contained a "#requires" statement for Windows
PowerShell 5.0. The version of Windows PowerShell that is required by the script does not match the currently running
version of Windows PowerShell 4.0.
At line:1 char:1
+ .\MyWebApp.ps1
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException
    + FullyQualifiedErrorId : ScriptRequiresUnmatchedPSVersion

PS> Import-Module .\MyWebApp.psm1
PS>

Используйте Манифест модуля

Единственный способ правильно проверить требования - использовать манифест модуля. К сожалению, это должен быть отдельный файл вместе с psm1 файл. Следующий манифест достигнет того, что #Requires комментарии предназначены для:

MyWebApp.psd1:

#
# Module manifest for module 'MyWebApp'
#

@{
ModuleVersion = '1.0'
PowerShellVersion = '4.0'
RequiredModules = @('WebAdministration')
RootModule = @('.\MyWebApp.psm1')
}

Импорт этого файла дает ошибку, которую мы хотим:

PS> Import-Module .\MyWebApp.psd1
Import-Module : The required module 'WebAdministration' is not loaded. Load the module or remove the module from 'RequiredModules' in the file 
'.\MyWebApp.psd1'.
At line:1 char:1
+ Import-Module .\MyWebApp.psd1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (.\MyWebApp.psd1:String) [Import-Module], MissingMemberException
    + FullyQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.ImportModuleCommand

К сожалению, вы не можете объявить функцию в одном файле. Вы должны использовать отдельный psd1 файл, а затем явно объявить оригинал psm1 Скрипт как "корневой модуль". Корневой модуль указывается как путь относительно psd1 файл.

Другие атрибуты:

  • ModuleVersion необходимо. Это должно присутствовать.
  • PowerShellVersion выполняет то, что #Requires -Version 4 намерена.
  • RequiredModules выполняет то, что #Requires -Modules WebAdministration намерена.

Обратите внимание, что Test-MyWebApp экспортируется неявно в обоих psm1 и psd1 файл. Обычно это контролируется Export-ModuleMember -Function в psm1 файл; эквивалент в манифесте модуля FunctionsToExport, Я считаю, что проще просто опустить FunctionsToExport из манифеста и контролировать то, что экспортируется с помощью Export-ModuleMember в psm1 скрипт.

Другие вопросы по тегам