You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows PowerShell 5.1无法用using module导入本地模块,Pwsh7可正常运行

Windows PowerShell 5.1中using module导入.psm1文件失败的解决方法

问题背景

我的项目目录结构如下:

└─ScriptModuleRepositoryTemplate
  │   ScriptModuleRepositoryTemplate.psd1
  │   ScriptModuleRepositoryTemplate.psm1
  │   ScriptModuleRepositoryTemplate.Tests.ps1

在测试文件ScriptModuleRepositoryTemplate.Tests.ps1顶部,我使用以下语句导入模块:

using module './ScriptModuleRepositoryTemplate.psm1'

该语句在PowerShell 7中能正常导入模块,Pester测试运行无误,但在Windows PowerShell 5.1中抛出错误:

System.IO.FileNotFoundException: The specified module 'D:\a\PowerShell.ScriptModuleRepositoryTemplate\PowerShell.ScriptModuleRepositoryTemplate\ScriptModuleRepositoryTemplate.psm1' was not loaded because no valid module file was found in any module directory.

若改用Import-Module:

Import-Module -Name "$PSScriptRoot/ScriptModuleRepositoryTemplate.psm1"

虽然能在两个PowerShell版本中正常运行,但Import-Module无法导入模块中的类和枚举,因此必须使用using module。

注:两个PowerShell版本均使用Pester v5.5.0,本地运行Invoke-Pester .和GitHub Actions均可复现问题。

原因分析

Windows PowerShell 5.1与PowerShell 7对using module的相对路径解析逻辑存在差异:

  • PowerShell 7:相对路径基于测试脚本所在目录解析
  • Windows PowerShell 5.1:相对路径基于当前工作目录解析

如果运行测试时当前工作目录与测试脚本所在目录不一致,就会出现文件找不到的错误。

解决方法

方法1:通过模块清单(.psd1)导入模块

将测试文件中的using module语句改为指向模块清单文件:

using module './ScriptModuleRepositoryTemplate.psd1'

确保.psd1文件中的RootModule字段正确指向你的.psm1文件:

RootModule = 'ScriptModuleRepositoryTemplate.psm1'

这种方法能在两个PowerShell版本中正常工作,同时支持导入类和枚举,是最优解。

方法2:确保运行测试时的工作目录是脚本所在目录

调用Invoke-Pester时指定工作目录为测试脚本所在目录:

Invoke-Pester -Path .\ScriptModuleRepositoryTemplate.Tests.ps1 -WorkingDirectory $PSScriptRoot

如果是在GitHub Actions中,先切换到模块目录再执行测试:

steps:
  - name: 运行Pester测试
    shell: pwsh
    run: |
      cd ./ScriptModuleRepositoryTemplate
      Invoke-Pester .

方法3:使用绝对路径导入(不推荐)

由于using module必须放在脚本最顶部,无法直接使用$PSScriptRoot变量,可通过生成临时脚本间接使用绝对路径,但该方法繁琐且维护性差,仅作为备选:

# 测试脚本最顶部
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath 'ScriptModuleRepositoryTemplate.psm1'
$tempScriptPath = Join-Path -Path $env:TEMP -ChildPath 'TempModuleImport.ps1'
"using module '$modulePath'" | Out-File -Path $tempScriptPath -Encoding utf8
. $tempScriptPath
Remove-Item -Path $tempScriptPath -Force

内容的提问来源于stack exchange,提问作者deadlydog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:47:05