#Requires 在模块脚本中工作吗?
Does #Requires work in module scripts?
考虑以下模块脚本:
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
导入它,这些有什么影响吗? The #Requires
documentation 只是说 "scripts",但这里并没有说明脚本模块是否算作 "scripts"。如果不行,我能做什么?
否,按普通评论处理
否,当通过调用 Import-Module
执行 psm1
脚本时,不会处理 #Requires
注释。
如果我们在缺少 WebAdministration
模块的机器上将问题中的脚本同时保存为 MyWebApp.psm1
和 MyWebApp.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
注释的目的:
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
脚本显式声明为 "root module." 根模块表示为 相对于 psd1
文件的路径。
其他属性:
-
ModuleVersion
是必需的。它必须存在。
PowerShellVersion
实现了 #Requires -Version 4
的意图。
RequiredModules
实现了 #Requires -Modules WebAdministration
的意图。
请注意 Test-MyWebApp
在 psm1
和 psd1
文件中隐式导出。这通常由 psm1
文件中的 Export-ModuleMember -Function
控制;模块清单中的等效项是 FunctionsToExport
。我发现从清单中省略 FunctionsToExport
并在 psm1
脚本中使用 Export-ModuleMember
控制导出的内容更简单。
考虑以下模块脚本:
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
导入它,这些有什么影响吗? The #Requires
documentation 只是说 "scripts",但这里并没有说明脚本模块是否算作 "scripts"。如果不行,我能做什么?
否,按普通评论处理
否,当通过调用 Import-Module
执行 psm1
脚本时,不会处理 #Requires
注释。
如果我们在缺少 WebAdministration
模块的机器上将问题中的脚本同时保存为 MyWebApp.psm1
和 MyWebApp.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
注释的目的:
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
脚本显式声明为 "root module." 根模块表示为 相对于 psd1
文件的路径。
其他属性:
-
ModuleVersion
是必需的。它必须存在。 PowerShellVersion
实现了#Requires -Version 4
的意图。RequiredModules
实现了#Requires -Modules WebAdministration
的意图。
请注意 Test-MyWebApp
在 psm1
和 psd1
文件中隐式导出。这通常由 psm1
文件中的 Export-ModuleMember -Function
控制;模块清单中的等效项是 FunctionsToExport
。我发现从清单中省略 FunctionsToExport
并在 psm1
脚本中使用 Export-ModuleMember
控制导出的内容更简单。