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

PowerShell 5.1 - How to uninstall module which is currently use

我们在一个部署 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.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

有没有人知道如何解决这个问题?

问题可能是您现有的 PowerShell 会话是 "locking" 通过从中加载可能的元素(例如全局变量或常量)的模块,即使您正在尝试卸载它 (Remove-Module ).

确保它未被锁定的最简单方法是退出 PowerShell 会话。如果您需要保留会话以在之后执行 "stuff",请在使用该模块之前尝试启动一个新的 PowerShell 会话(嵌套会话),然后在最后退出它。

中所述,模块可能会卡在会话中。 关闭 PowerShell 会话,运行在新会话中卸载应该会有帮助。

处理自动加载

作为,模块如果自动加载可能会被锁定。如果它是通过配置文件发生的,将 -NoProfile 添加到卸载脚本应该会有所帮助:

powershell -NoProfile -Command "Uninstall-Module X"

一些模块,如 PSReadLine,即使在这样的会话中也会加载,并且可能需要额外的 -NonInteractive 参数:

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

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

解决方法

  • 也许在这种情况下不需要卸载,并且可以安装您的模块,保留它,并在需要时用 Update-InstalledModule 更新它?
  • 许多模块无需安装即可导入。 Import-Module 使用 .psd1 文件的路径可能会起作用。尽管如此,它并没有使 Remove-Module 100% 发挥作用。
  • 如果担心安全问题,可以只为服务用户安装模块 Install-Module -Scope CurrentUser,and/or 限制 PowerShell 使用 Set-ExecutionPolicy,可以是 运行 也有 -Scope 个参数。

就我而言,我是这样解决的:

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

截至 2021 年底,我在使用 pwsh7.2 和 PSFzf 模块时遇到了同样的问题。 什么对我有用:

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