When importing a module fails, it will still load the RequiredModules
defined in the .psd1 manifest.
Consider the following module files:
@{
RootModule = 'MyModule.psm1'
ModuleVersion = '1.0.0.0'
GUID = '5b058fa7-5248-4a9a-b0f3-75ba6e3a123c'
Author = 'Author'
PowerShellVersion = '5.1'
RequiredModules = @('NetConnection')
ScriptsToProcess = @('RunFirst.ps1')
PrivateData = @{ PSData = @{} }
}
#Requires -RunAsAdministrator
# <Perform misc checks, initialize environment>
PS C:\MyModule> Get-Module
ModuleType Version Name
---------- ------- ----
Manifest 3.1.0.0 Microsoft.PowerShell.Management
Manifest 3.1.0.0 Microsoft.PowerShell.Utility
Script 2.3.5 PSReadline
PS C:\MyModule> Import-Module .\MyModule.psd1
Import-Module : The script 'RunFirst.ps1' cannot be run because it contains a "#requires"
statement for running as Administrator. The current Windows PowerShell session is not running
as Administrator. Start Windows PowerShell by using the Run as Administrator option, and then
try running the script again.
PS C:\MyModule> Get-Module
ModuleType Version Name
---------- ------- ----
Manifest 3.1.0.0 Microsoft.PowerShell.Management
Manifest 3.1.0.0 Microsoft.PowerShell.Utility
Manifest 2.0.0.0 NetConnection <----- How to prevent this from loading?
Script 2.3.5 PSReadline
RequiredModules
from loading (or programmatically unload said modules) if/when Import-Module
fails?RunFirst.ps1
the most appropriate place for #Requires -RunAsAdministrator
in a module?#Requires -RunAsAdministrator
in order to showcase an Import-Module
failure. This is just one of several circumstances that can cause Import-Module
to fail, and the variety of different circumstances could very well impact which approaches are deemed better than others depending on the nature of the failure.While what you're trying to achieve is understandable, in my estimation it is impossible to implement:
Of necessity, when a module is imported, all prerequisites must be met first, which requires processing the relevant module-manifest entries, RequiredModules
, NestedModules
, RequiredAssemblies
and (debatably) ScriptsToProcess
.
While it is hypothetically possible to undo loading of dependent script modules (those that are implemented exclusively via PowerShell code), by removing them in case of importation failure (using Remove-Module
),[1] it is fundamentally impossible to reliably undo the effects of the RequiredAssemblies
and ScriptsToProcess
entries: in the former case, the problem is that .NET doesn't allow unloading of assemblies once loaded, and, in the latter case, the effects of what the script does are unknowable.
Since the
#Requires
statement applies to scripts, isRunFirst.ps1
the most appropriate place for#Requires -RunAsAdministrator
in a module?
#requires
statements equally work in *.psm1
files (script modules), so there's no need for a separate *.ps1
script file referenced in a ScriptsToProcess
module-manifest entry.
[1] Even then, it is possible - if ill-advised - for such modules to have modified the caller's state, which cannot be anticipated and therefore cannot be reliably undone.
For modules that involve loading .NET assemblies, the fundamental constraint of not being able to unload assemblies once loaded applies.