PowerShell 5.1 - Как удалить модуль, который используется в настоящее время

Мы используем несколько модулей 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

У кого-нибудь есть идеи, чтобы решить эту проблему?

4 ответа

Проблема может заключаться в том, что ваш существующий сеанс PowerShell "блокирует" модуль путем загрузки из него возможных элементов (таких как глобальные переменные или константы), даже если вы пытаетесь его выгрузить (Remove-Module).

Самый простой способ убедиться, что он не заблокирован, - выйти из сеанса PowerShell. Если вам нужно сохранить сессию, чтобы потом выполнять "вещи", попробуйте запустить новый сеанс 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и / или ограничить использование PowerShell с помощью Set-ExecutionPolicy, который можно запустить с -Scope аргумент тоже.

В моем случае я решил это так:

  1. Закройте PowerShell.
  2. Действительно, закройте PowerShell. Откройте диспетчер задач и найдите все фоновые экземпляры PowerShell, например, powershell.exe / pwsh.exe.
  3. Удалите ненужные папки модулей из C:\Users\${USER}\Documents\PowerShell\Modules

В конце 2021 года я столкнулся с той же проблемой с pwsh7.2 и модулем PSFzf. Что сработало для меня:

  1. Закрыть/Принудительно закрыть все экземпляры PowerShell/pwsh через диспетчер задач.
  2. Запустите новый экземпляр pwsh без профиля. Win+R > pwsh -NoProfile
  3. Бежать Uninstall-Module -Name PSfzf -Force