【问题标题】:Does #Requires work in module scripts?#Requires 是否在模块脚本中工作?
【发布时间】:2017-02-16 19:30:46
【问题描述】:

考虑以下模块脚本:

MyWebApp.psm1:

#Requires -Version 4
#Requires -Modules WebAdministration

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

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

如果这是一个 ps1 脚本,则顶部的 #Requires cmets 将强制 PowerShell 在以下情况下抛出错误

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

但是如果我尝试使用Import-Module 导入它,这些有什么影响吗? The #Requires documentation 只是说“脚本”,但没有说明脚本模块是否算作“脚本”。如果没有,我该怎么办?

【问题讨论】:

    标签: powershell powershell-module


    【解决方案1】:

    不,视为普通评论

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

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

    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 cmets 的意图:

    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 隐式导出到 psm1psd1 文件中。这通常由Export-ModuleMember -Functionpsm1 文件中控制;模块清单中的等价物是FunctionsToExport。我发现从清单中省略 FunctionsToExport 并在 psm1 脚本中使用 Export-ModuleMember 控制导出的内容会更简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-27
      • 2020-10-28
      • 2017-11-19
      • 2019-03-21
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多