导入模块详细输出意味着模块加载了两次

时间:2016-01-21 12:25:44

标签: powershell module relative-path verbose

我在非标准路径下有一个模块( MyModule ),即不在$env:PSModulePath -split ";"中列出的常用位置下。但是,我已经添加了"生产" MyModule 到该环境变量的路径,同时我继续开发"开发"副本。

在尝试调试某些内容时,我使用以下命令加载了模块(使用$VerbosePreference = "Continue"),并立即看到两行看似矛盾的详细输出:

[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'.

我想了解为什么Import-Module似乎要加载模块两次,特别是当第二条路径不正确时。

更多细节:

模块的文件夹结构是:

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

注意(1)我保留了较旧的版本1"将此模块放在MyModule1子文件夹中,并将我更新的"版本2"在MyModule2子文件夹中的文件和(2)自定义模块测试脚本使用.xml文件列出测试用例。我很确定后者可以被忽略。

我的模块清单(.psd1)文件包含以下内容,其他所有行都是空格或注释:

@{
  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'
  )
}

显然,我已经使用了文件的相对路径,尤其是。 RootModule 键;这是必要的,因为当我分享模块时,我无法确定模块的复制位置。

回到详细输出,我可以看到两行显示(1)PSD1文件的正确路径和(2)PSM1文件的无效路径。我注意到第二个路径的用户名是小写的,这是我在测试前{I} Set-Location时输入的方式。因此,看起来第一条路径是通过将MyModule.psd1附加到Import-Module cmdlet的路径,第二条路径是(Get-Location)和RootModule路径的串联。

这似乎只发生在这个模块上。我有其他人在同一根' root'没有表现出这种行为的文件夹。

1 个答案:

答案 0 :(得分:0)

庵。好。我可能已经解决了,至少部分......

我不小心在我运行Import-Module cmdlet的位置下创建了 MyModule2 子文件夹的副本。删除该文件夹后,详细输出开始变得更有意义:

[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>'.
....

我想这意味着当PowerShell解析清单文件中的 RootModule 时,它首先在当前路径下查找,然后在主模块文件夹中找不到任何内容。我觉得这是违反直觉的,因为我预计清单中的任何相对路径总是相对于PSD1文件,而不是当前位置。

如果我然后再尝试再次导入模块我得到了这个:

[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>'.
....

也就是说,只有一个&#34;加载模块&#34;线,而不是两行详细输出。然后我尝试了-Force开关,得到了以下内容:

[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>'.
....

因此,似乎在首次导入模块或强行重新导入模块时会出现两行详细输出,但如果它已经是会话的一部分,那么您只能看到第一行。

此外,我终于发现详细输出区别于导出功能和导入它们之间。这些函数按照它们在PSM1文件中定义的顺序导出,但按字母顺序导入。这表明使用一阶段或两阶段过程取决于是否正在从PSM1文件中重新读取函数定义,并考虑我们是否看到一行或两行详细输出。

或者,为了更直接地回答这个问题,似乎有两行说&#34;加载模块......&#34;什么时候需要读取.psm1文件,当PowerShell已经知道模块及其内容时只需要一行。