PowerShell 5.1 - 如何卸载当前正在使用的模块

48
我们在一个部署 PowerShell 脚本中使用一些 PowerShell 模块。使用以下命令,我们将模块(即 XXXX)安装到 "C:\Program Files\WindowsPowerShell\Modules" 中。
Install-Module -Name "XXXX" -AllowClobber -RequiredVersion "XXXX" -Repository "XXXX" -Scope AllUsers
现在,一旦我们使用了该模块的功能,我们将使用以下命令在部署脚本结束时卸载它。
Remove-Module -Name "XXXX" -force
Uninstall-Module -Name "XXXX"  -AllVersions -force

但是这个卸载模块命令会给出以下错误。

WARNING: The version '###' of module 'XXXX' is currently in use. Retry the operation after closing the
applications.
PackageManagement\Uninstall-Package : Module 'XXXX' is in currently in use.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1:2046 char:21
+ ...        $null = PackageManagement\Uninstall-Package @PSBoundParameters
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Microsoft.Power...ninstallPackage:UninstallPackage) [Uninstall-Packag
   e], Exception
    + FullyQualifiedErrorId : ModuleIsInUse,Uninstall-Package,Microsoft.PowerShell.PackageManagement.Cmdlets.Uninstall
   Package

有人有解决这个问题的想法吗?


1
找到解决方案了吗? - kudlatiger
4个回答

30

问题可能是你现有的PowerShell会话正在“锁定”该模块,因为它正在加载可能的元素(如全局变量或常量),即使你正在尝试卸载它 (Remove-Module)。

最清洁的方法是退出PowerShell会话以确保没有被锁定。如果你需要保留会话来做其他事情,可以在使用模块之前启动一个新的PowerShell会话(嵌套会话),然后在结束时退出它。


2
我的后背感觉像是被王室的痛苦所折磨,但这似乎是问题和解决方案的原因。 - Pecos Bill
14
如果PowerShell正在使用该软件包,并且您需要退出PowerShell以删除它,则如何在不重新启动PowerShell和重新锁定软件包的情况下运行“Remove-Module”命令? - Keith
当 PowerShell 锁定某个模块时,使用另一个控制台,如 Windows 命令提示符(例如)通常是有效的。 - MrClan
6
在我的情况下,一个编辑器扩展(PowerShell for VSCode)是罪魁祸首,保留了一个模块引用。不要忘记这些。 - msanford
我在三个不同的地方安装了AWS模块以满足三种不同的需求(用户、管理员、vscode),现在必须将它们全部卸载。 - danno

27

E Bekker的原始回答中所述,模块可能会在会话中卡住。 关闭PowerShell会话,并在新会话中运行卸载命令应该会有所帮助。

处理自动加载

Keith所提到的,如果模块是通过自动加载被锁定的,那么在卸载脚本中添加-NoProfile参数应该可以解决问题:

powershell -NoProfile -Command "Uninstall-Module X"

有些模块,比如 PSReadLine,在这种会话中会被加载,可能需要额外的 -NonInteractive 参数:

powershell -NoProfile -NonInteractive -Command "Uninstall-Module X"

我还没有找到这样的情况,但如果这仍然没有帮助,一个人可以使用 (Get-InstalledModule -Name X).InstalledLocation 来找到模块安装的位置,并通过其他方式删除它(最后的手段)。如果另一个/旧版本的模块与PowerShell捆绑在一起,则最好避免手动删除,以免破坏它。

解决方法

  • 也许在这种情况下卸载不是必要的,可能可以安装您的模块,保留它,并在需要时使用 Update-InstalledModule 进行更新?
  • 许多模块可以在不安装的情况下导入。 使用 .psd1 文件的路径和 Import-Module 可能有效。 但是,这并不能使 Remove-Module 百分之百地工作。
  • 如果安全是一个问题,一个人可以仅为服务用户安装模块,并/或限制 PowerShell 的使用与 Set-ExecutionPolicy,这也可以使用 -Scope 参数运行。

14

对于我的情况,我是这样解决的:

  1. 关闭PowerShell。
  2. 确实,关闭PowerShell。打开任务管理器,找到任何后台运行的PowerShell实例,例如powershell.exe / pwsh.exe。
  3. 从C:\Users\${USER}\Documents\PowerShell\Modules删除不需要的模块文件夹。

3
在这里,最重要的是非常熟练掌握PowerShell。 - Anton Kalcik
2
我必须从 C:\Program Files\WindowsPowerShell\Modules\<module>\<version> 中删除我的文件。我认为路径可以从 (Get-Module -ListAvailable <ThePackageName>).Path 中找到。 - Vimes
对于启用了强制云同步到OneDrive的用户,路径为:%OneDrive%/Documents/WindowsPowerShell/Modules - Salman Siddiqui

7

截至2021年末,我遇到了与pwsh7.2和PSFzf模块相关的相同问题。

  1. 通过任务管理器关闭/强制关闭PowerShell/pwsh的所有实例。
  2. 启动一个没有配置文件的新pwsh实例。Win+R > pwsh -NoProfile
  3. 运行Uninstall-Module -Name PSfzf -Force

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接