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

Есть ли у кого-нибудь идеи решить это?


person mit    schedule 06.03.2017    source источник
comment
нашли решение?   -  person kudlatiger    schedule 07.10.2020


Ответы (3)


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

Самый простой способ убедиться, что он не заблокирован, - выйти из сеанса PowerShell. Если вам нужно сохранить сеанс, чтобы потом «делать что-то», пытаясь запустить новый сеанс PowerShell (вложенный сеанс) непосредственно перед тем, как вы воспользуетесь модулем, то выйдите из него в конце.

person E Bekker    schedule 20.09.2017
comment
Королевская боль в спине, но, похоже, это причина и решение. - person Pecos Bill; 05.02.2018
comment
Если PowerShell использует пакет, и вам нужно выйти из PowerShell, чтобы удалить его, как тогда запустить Remove-Module без перезапуска PowerShell и повторной блокировки пакета? - person Keith; 20.09.2019
comment
Использование другой консоли, такой как Windows cmd-prompt (например), обычно работает, когда PowerShell блокирует какой-либо модуль. - person MrClan; 03.03.2020

Как упоминалось в исходном ответе Э. Беккера, модули могут зависать в сеансе. Закрытие сеанса 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.
person Marcin Śmiałek    schedule 11.02.2020

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

  1. Закройте PowerShell.
  2. Действительно, закройте PowerShell. Откройте диспетчер задач и найдите все фоновые экземпляры PowerShell, например, powershell.exe / pwsh.exe.
  3. Удалите ненужные папки модулей из C: \ Users \ $ {USER} \ Documents \ PowerShell \ Modules
person Jon Davis    schedule 06.08.2020
comment
Действительно закрыть PowerShell здесь самое главное - person Anton Kalcik; 11.03.2021
comment
Пришлось удалить свой из C:\Program Files\WindowsPowerShell\Modules\<module>\<version>. Думаю, путь можно вычислить по (Get-Module -ListAvailable <ThePackageName>).Path - person Vimes; 27.07.2021