Import PowerShell module from within some subfolders

Viewed 635

Although there are already plenty of questions and blogs regarding PowerShell module imports, I did not found any that would answer my question.

I'm trying to import modules which are grouped within subfolders without adding all those subfolders to the $env:PSModulePath. Example of the folder structure:

...\WindowsPowerShell\Modules\
...\WindowsPowerShell\Modules\Avengers
...\WindowsPowerShell\Modules\Avengers\ModuleHulk\ModuleHulk.psd1
...\WindowsPowerShell\Modules\Avengers\ModuleThor\ModuleThor.psd1
...\WindowsPowerShell\Modules\X-Men
...\WindowsPowerShell\Modules\X-Men\ModuleProfX\ModuleProfX.psd1
...\WindowsPowerShell\Modules\X-Men\ModuleMagneto\ModuleMagneto.psd1
...\WindowsPowerShell\Modules\FantasticFour
...\WindowsPowerShell\Modules\FantasticFour\ModuleMisterFantastic\ModuleMisterFantastic.psd1
...\WindowsPowerShell\Modules\FantasticFour\ModuleInvisibleWoman\ModuleInvisibleWoman.psd1

According to the Microsoft Docs the module .psd1 filename has to be the same as the module folder name. This is satisfied above. The modules have to be within a location of the $env:PSModulePath, all good.

Unfortunately, PowerShell fails to import these modules:

PS> Import-Module ModuleHulk
Import-Module : The specified module 'ModuleHulk' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ Import-Module ModuleHulk
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (ModuleHulk:String) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

PS>

However, recently I found out one can also import modules using the fairly new using module statement (since PowerShell Version 5). For doing that I could add the following code at the very beginning in my scripts or execute that even in the console:

#Requires -Version 5
using module ModuleHulk
PS> using module ModuleHulk
PS>

No issue, all good, so the module itself is fine and can be imported as usual. But, this seems to be a hacky solution and it needs at least PowerShell 5. Now the question:

Is there any way to achieve that using the usual Import-Module cmdlet, without adding all the subfolders to the $env:PSModulePath?

1 Answers

I found one possible solution thanks to another SO question: Import-Module works only when piped from Get-Module.

The Import-Module cmdlet also accepts one or more [PSModuleInfo] objects, which are what Get-Module returns. So one can do the following:

Get-Module ModuleHulk -ListAvailable | Import-Module
PS> Get-Module ModuleHulk -ListAvailable

    Directory: ...\WindowsPowerShell\Modules\Avengers\

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      ModuleHulk

PS> Get-Module ModuleHulk -ListAvailable | Import-Module
PS> Get-Module ModuleHulk

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0.0      ModuleHulk                          {...}

PS>

And it worked! If anyone knows why the Get-Module cmdlet finds the modules in a different way than Import-Module, please let me know.

Related