#powershell #module #powershell-module
#powershell #модуль #powershell-модуль
Вопрос:
У меня есть модуль, позвольте мне назвать его xyz.ps.core
. Он экспортирует функцию — Get-PullRequestsFromCommitIds
Я исправил ошибку в функции, переиздал модуль, переустановил и повторно импортировал его, и все же функция по-прежнему ссылается на старую версию модуля.
Пожалуйста, соблюдайте:
C:xyztip [master ≡]> Get-Command Get-PullRequestsFromCommitIds | ft -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Function Get-PullRequestsFromCommitIds 1.0.19107.4 xyz.ps.core
Как вы можете видеть, функция взята из версии 1.0.19107.4
C:xyztip [master ≡]> get-module xyz.ps.core | ft -AutoSize
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.19107.7 xyz.ps.core {Assert-ExtractionDestFolder, Assert-PullRequestMatchesFolder, Backup-Database, Connect-OctopusToTfs...}
C:xyztip [master ≡]> get-module xyz.ps.core -ListAvailable | ft -AutoSize
Directory: C:UsersmkharitonovDocumentsWindowsPowerShellModules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.19107.7 xyz.PS.Core {Assert-ExtractionDestFolder, Assert-PullRequestMatchesFolder, Backup-Database, Connect-OctopusToTfs...}
Но версия модуля уже включена 1.0.19107.7
. Но хорошо, у меня есть функция, которая обновляет модуль, даже если он уже установлен на ту же версию:
C:xyztip [master ≡]> (get-command Use-Module).ScriptBlock
param([Parameter(Mandatory)]$Name)
if ($VerbosePreference -ne 'Continue')
{
Write-Host -ForegroundColor Cyan -NoNewline "Using the latest version of $Name ... "
}
Write-Verbose "Uninstalling all the versions of $Name ..."
Uninstall-Module $Name -AllVersions -Force -ErrorAction SilentlyContinue
Remove-Module $Name -Force -ErrorAction SilentlyContinue
Write-Verbose "Installing the latest version of $Name ..."
Install-Module $Name -Scope CurrentUser -Force
Write-Verbose "Importing $Name into the current session ..."
Import-Module $Name -Force
if ($VerbosePreference -ne 'Continue')
{
Write-Host -ForegroundColor Cyan (Get-Module $Name).Version
}
Давайте воспользуемся им сейчас:
C:xyztip [master ≡]> use-module xyz.ps.core
Using the latest version of xyz.ps.core ... 1.0.19107.7
Давайте проверим источник функции:
C:xyztip [master ≡]> Get-Command Get-PullRequestsFromCommitIds | ft -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Function Get-PullRequestsFromCommitIds 1.0.19107.4 xyz.ps.core
Все тот же старый. Обратите внимание, что в новом окне Powershell функция берется из текущей версии модуля.
Можно ли обновить функцию, не закрывая powershell?
Комментарии:
1. Вы имеете в виду
Import-Module modulename -Force
?2. Я уже делаю это — обратите
Import-Module $Name -Force
внимание в теле функцииUse-Module
, которую я использую для обновления модуля.
Ответ №1:
Все дело в поведении, связанном с областями действия. ДВУ:
Сеансы, модули и вложенные приглашения являются автономными средами, но они не являются дочерними областями глобальной области в сеансе.
По сути, поскольку модули являются автономными средами, а не дочерней областью, они не могут импортировать модули в «родительскую» область сценария. Даже если вы используете -Force
.
Давайте протестируем области внутри модуля:
Модуль выборки.psm1
Function Test-Import {
param([Parameter(Mandatory)]$Name)
Write-Host "List Loaded modules before"
Get-Module
Write-Host "Importing $Name into the current session ..."
Import-Module $Name -Force
Write-Host "Module Version $((Get-Module $Name).Version)"
Write-Host "Loaded Modules After"
#List Loaded modules after
Get-Module
}
#Only present desired functions
Export-ModuleMember -Function Test-Import
Если мы начнем с простого теста с чистого листа (я удалил посторонние модули для краткости):
PS C:> #Clean state - Nothing Loaded for demonstration
PS C:> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
PS C:> Import-Module .sampleModule.psm1
PS C:> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 Test-Module {Test-Import}
PS C:> Test-Import ActiveDirectory
List Loaded modules before
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 Test-Module {Test-Import}
Importing ActiveDirectory into the current session ...
Module Version 1.0.1.0
Loaded Modules After
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.1.0 ActiveDirectory {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
Script 0.0 Test-Module {Test-Import}
Здесь мы замечаем, что модуль ActiveDirectory не присутствовал в начале функции, но действительно был загружен в конце функции и сообщил правильную версию. Теперь давайте посмотрим, загрузился ли он:
PS C:> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 Test-Module {Test-Import}
Как мы можем видеть, поскольку модули выполняются в своей собственной автономной среде, мы успешно импортировали модуль (ActiveDirectory в этом примере) в область модуля, но не в локальную область, как вы ожидали.
Единственный способ обойти эту проблему с областью — импортировать модуль в глобальную область, добавив -Global
like:
Import-Module $Name -Force -Global
Изменение этой одной строки в примере сценария и повторный импорт:
PS C:> Import-Module .sampleModule.psm1 -Force
PS C:> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 Test-Module {Test-Import}
PS C:> Test-Import ActiveDirectory
List Loaded modules before
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 0.0 Test-Module {Test-Import}
Importing ActiveDirectory into the current session ...
Module Version 1.0.1.0
Loaded Modules After
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.1.0 ActiveDirectory {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
Script 0.0 Test-Module {Test-Import}
То же, что и раньше… Теперь давайте проверим, правильно ли он загрузился:
PS C:> Get-Module
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 1.0.1.0 ActiveDirectory {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
Script 0.0 Test-Module {Test-Import}
Успех!