#Requires 在模块脚本中工作吗? [英] Does #Requires work in module scripts?
问题描述
考虑以下模块脚本:
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.psm1
和 MyWebApp.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
:
导入这个文件给出了我们想要的错误:
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
是在 psm1
和 psd1
文件中隐式导出的.这通常由 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屋!