Import-Module Verbose output implies module is loa

2019-08-08 14:54发布

I have a module (MyModule) under a non-standard path, i.e. not under the usual locations listed in $env:PSModulePath -split ";". I have, however, added the "production" path to MyModule to that environment variable while I continue to work on a "development" copy.

Whilst trying to debug something, I loaded the module (with $VerbosePreference = "Continue") using the following command and immediately saw two seemingly contradictory lines of Verbose output:

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Loading module from path 'D:\Dev\usera\MyModule2\MyModule.psm1'.

I would like to understand why Import-Module appears to be loading the module twice, especially as the second path is incorrect.


MORE DETAIL:

The folder structure for the module is:

MyModule\MyModule.psd1
MyModule\MyModule.Test-Module.xml
MyModule\MyModule1\MyModule.psm1
MyModule\MyModule2\MyModule.psm1

Note (1) I retained an older "version 1" of this module in a MyModule1 sub-folder and put my updated "version 2" file in a MyModule2 sub-folder and (2) that the .xml file is used by a custom module-testing script to list test cases. I'm pretty sure that the latter can be ignored.

My module manifest (.psd1) file contains the following, with all other lines being blanks or comments:

@{
  RootModule = '.\MyModule2\MyModule.psm1'
  ModuleVersion = '2.0.0.0'
  GUID = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
  Author = 'Old Developer (v1.x) & New Developer (v2.x)'
  CompanyName = 'MyCompany'
  Copyright = '(c) 2013-2015 MyCompany. All rights reserved.'
  Description = 'Really useful functions'
  FileList = @(
    '.\MyModule.psd1'
    '.\MyModule.Test-Module.xml'
    '.\MyModule1\MyModule.psm1'
    '.\MyModule2\MyModule.psm1'
    '.\MyModule2\Examples\Archive-FilesWithCompression.ps1'
  )
}

Clearly I have used relative paths for the files, esp. the RootModule key; this is necessary as I cannot be sure where the module will be copied when I share it.

Going back to the Verbose output, I can see that the two lines show (1) the correct path to the PSD1 file and (2) an invalid path to the PSM1 file. I did notice that the second path has the username in lower-case, which is how I happened to type it when I Set-Location before testing. So, it looks like the first path is taken by appending MyModule.psd1 to the path given to the Import-Module cmdlet and the second is a concatenation of (Get-Location) and the RootModule path.

This only seems to happen to this module. I have others under the same 'root' folder which don't exhibit this behaviour.

1条回答
聊天终结者
2楼-- · 2019-08-08 15:49

Um. OK. I may have worked it out, at least in part...

I had accidentally made a copy of the MyModule2 sub-folder under the location from where I was running the Import-Module cmdlet. Once I removed that folder the verbose output started to make more sense:

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....

I guess this means that when PowerShell resolves the RootModule in the manifest file it looks under the current path first and then the main module folder if nothing is found. I find this counter-intuitive as I'd expect that any relative paths in the manifest would always be relative to the PSD1 file, not the current location.

If I then try to import the module again immediately I get this:

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Importing function '<function>'.
....

That is, only one "loading module" line, rather than the two lines of verbose output. I then tried the -Force switch and got the following:

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule -Force

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Removing the imported "<function>" function.
....
VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....
VERBOSE: Importing function '<function>'.
....

So, it seems that the two lines of verbose output appear when the module is first imported, or forcibly re-imported, but if it is already part of the session then you only see the first line.

Also, I finally spotted that the verbose output differentiated between exporting functions and importing them. The functions are exported in the order that they are defined in the PSM1 file, but are imported in alphabetical order. This suggests a one- or two-stage process is used depending on whether the function definitions are being re-read from the PSM1 file, tying in with whether we see one or two lines of verbose output.

Or, to answer the question more directly, it appears that there are two lines saying "Loading module..." when it needs to read the .psm1 file, and only one line when PowerShell is already aware of the module and its contents.

查看更多
登录 后发表回答