#Requires 在模块脚本中工作吗? [英] Does #Requires work in module scripts?

查看:55
本文介绍了#Requires 在模块脚本中工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下模块脚本:

MyWebApp.psm1:

#Requires -Version 4#Requires -Modules WebAdministration功能测试MyWebApp(){返回 ((Get-WebApplication 'myapp') -ne $null)}

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

如果这是一个 ps1 脚本,顶部的 #Requires 注释将强制 PowerShell 抛出错误

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

但是如果我尝试使用 Import-Module 导入它,这些有什么影响吗?#Requires 文档 只是说脚本",但并没有说明脚本模块在这里是否算作脚本".如果没有,我该怎么办?

解决方案

不,它被视为普通评论

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

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

PS>.\MyWebApp.ps1.\MyWebApp.ps1 :脚本MyWebApp.ps1"无法运行,因为由缺少脚本的#requires"语句:WebAdministration.在行:1 字符:1+ .\MyWebApp.ps1+ ~~~~~~~~~~~~~~+ CategoryInfo : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException+ FullQualifiedErrorId : ScriptRequiresMissingModulesPS>导入模块 .\MyWebApp.psm1PS>

导入模块成功,该函数现在存在于当前作用域中.但是函数会失败:

PS>测试-MyWebAppGet-WebApplication :术语Get-WebApplication"未被识别为 cmdlet、函数、脚本文件的名称,或可运行的程序.检查名称的拼写,或者如果包含路径,请验证路径是否正确并且再试一次.在 .\MyWebApp.psm1:5 字符:14+ return ((Get-WebApplication 'myapp') -Eq $null)+ ~~~~~~~~~~~~~~~~~~+ CategoryInfo : ObjectNotFound: (Get-WebApplication:String) [], CommandNotFoundException+ FullQualifiedErrorId : CommandNotFoundException

即使是 -Version 检查也被忽略.如果我们在一台只有 PowerShell 4 的机器上将它提高到 5:

PS>.\MyWebApp.ps1.\MyWebApp.ps1 :脚本MyWebApp.ps1"无法运行,因为它包含适用于 Windows 的#requires"语句PowerShell 5.0.脚本所需的 Windows PowerShell 版本与当前运行的不匹配Windows PowerShell 4.0 版本.在行:1 字符:1+ .\MyWebApp.ps1+ ~~~~~~~~~~~~~~+ CategoryInfo : ResourceUnavailable: (MyWebApp.ps1:String) [], ScriptRequiresException+ FullQualifiedErrorId : ScriptRequiresUnmatchedPSVersionPS>导入模块 .\MyWebApp.psm1PS>

使用模块清单

正确验证要求的唯一方法是使用 模块清单.不幸的是,这必须是与 psm1 文件一起的单独文件.以下清单将实现 #Requires 注释的目的:

MyWebApp.psd1:

<预><代码>## 模块MyWebApp"的模块清单#@{模块版本 = '1.0'PowerShellVersion = '4.0'RequiredModules = @('WebAdministration')RootModule = @('.\MyWebApp.psm1')}

导入这个文件给出了我们想要的错误:

PS>导入模块 .\MyWebApp.psd1导入模块:未加载所需的模块WebAdministration".加载模块或从文件中的RequiredModules"中移除模块'.\MyWebApp.psd1'.在行:1 字符:1+ 导入模块 .\MyWebApp.psd1+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : ResourceUnavailable: (.\MyWebApp.psd1:String) [Import-Module], MissingMemberException+ FullQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.ImportModuleCommand

很遗憾,您不能在同一个文件中声明该函数.您必须使用单独 psd1 文件,然后将原始psm1 脚本明确声明为根模块".根模块表示为相对于 psd1 文件的 path.

其他属性:

  • ModuleVersion 是必需的.它必须存在.
  • PowerShellVersion 实现了 #Requires -Version 4 的意图.
  • RequiredModules 实现了 #Requires -Modules WebAdministration 的意图.

请注意,Test-MyWebApp 是在 psm1psd1 文件中隐式导出的.这通常由 psm1 文件中的 Export-ModuleMember -Function 控制;模块清单中的等效项是 FunctionsToExport.我发现从清单中省略 FunctionsToExport 并控制使用 psm1 脚本中的 Export-ModuleMember 导出的内容更简单.

Consider the following module script:

MyWebApp.psm1:

#Requires -Version 4
#Requires -Modules WebAdministration

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

(Export-ModuleMember omitted for simplicity. The script still works as a module without it.)

If this were a ps1 script, the #Requires comments at the top would force PowerShell to throw an error if

  • The version were lower than 4
  • The WebAdministration module could not be loaded (imported)

But if I try to import this using Import-Module, do these have any effect? The #Requires documentation just says "scripts", but it doesn't clarify whether script modules count as "scripts" or not here. What can I do instead, if not?

解决方案

No, it's treated as a normal comment

No, #Requires comments are not processed when a psm1 script is executed by calling Import-Module.

If we save the script in the question as both MyWebApp.psm1 and MyWebApp.ps1 on a machine that lacks the WebAdministration module, we get the following result:

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>

Importing the module succeeds, and the function now exists in the current scope. But the function will fail:

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

Even the -Version check is ignored. If we bump it up to 5 on a machine with only 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>

Use a Module Manifest

The only way to get the requirements validated properly is to use a module manifest. Unfortunately, this must be a separate file alongside the psm1 file. The following manifest will achieve what the #Requires comments are intended to do:

MyWebApp.psd1:

#
# Module manifest for module 'MyWebApp'
#

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

Importing this file gives the error we want:

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

Unfortunately, you cannot declare the function in the same file. You must use a separate psd1 file and then explicitly declare the original psm1 script as the "root module." The root module is indicated as a path relative to the psd1 file.

Other attributes:

  • The ModuleVersion is required. It must be present.
  • PowerShellVersion accomplishes what #Requires -Version 4 intends.
  • RequiredModules accomplishes what #Requires -Modules WebAdministration intends.

Note that Test-MyWebApp is exported implicitly in both the psm1 and the psd1 file. This is normally controlled by Export-ModuleMember -Function in a psm1 file; the equivalent in a module manifest is FunctionsToExport. I find it simpler to just omit FunctionsToExport from the manifest and control what's exported using Export-ModuleMember in the psm1 script.

这篇关于#Requires 在模块脚本中工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆