#Requires是否适用于模块脚本?

时间:2017-02-16 19:30:47

标签: powershell powershell-module

考虑以下模块脚本:

MyWebApp.psm1

#Requires -Version 4
#Requires -Modules WebAdministration

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

(为了简单起见省略了Export-ModuleMember。该脚本仍然可以作为没有它的模块。)

如果这是ps1脚本,则顶部的#Requires条评论会强制PowerShell抛出错误

  • 版本低于4
  • 无法加载(导入)Web管理模块

但是如果我尝试使用Import-Module导入它,这些会有效吗? The #Requires documentation只是说"脚本",但它并没有澄清脚本模块是否算作"脚本"或不在这里。如果没有,我该怎么办?

1 个答案:

答案 0 :(得分:9)

不,它被视为正常评论

不,通过调用#Requires执行psm1脚本时,不会处理Import-Module条评论。

如果我们在缺少MyWebApp.psm1模块的计算机上将问题中的脚本同时保存为MyWebApp.ps1WebAdministration,我们会得到以下结果:

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检查也会被忽略。如果我们在只有PowerShell 4的机器上将其提升到5:

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>

使用模块清单

正确验证要求的唯一方法是使用module manifest。不幸的是,这必须是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脚本显式声明为&#34;根模块。&#34;根模块表示为相对于psd1文件的路径

其他属性:

  • ModuleVersion是必需的。它必须存在。
  • PowerShellVersion完成了#Requires -Version 4的意图。
  • RequiredModules完成了#Requires -Modules WebAdministration的意图。

请注意,Test-MyWebApppsm1文件中都会隐式导出psd1。这通常由Export-ModuleMember -Function文件中的psm1控制;模块清单中的等价物是FunctionsToExport。我发现从清单中省略FunctionsToExport并使用Export-ModuleMember脚本中的psm1控制导出的内容会更简单。