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
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?
present tense third-person singular of do.
"She does her homework before she goes out to play." "She does many after school activities." "He does a lot of chores around the house." "He does the dishes every night."
“Does” is used for singular subjects like “he,” “she,” “it,” “this,” “that,” or “John.” “Do” is used to form imperative sentences, or commands.
The Verb to do: do, does and did They are all forms of the verb to do. The verb to do can be used as an action verb and also as an auxiliary verb.
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>
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With