Powershell - как создать сценарий обновления сеанса в PowerShell?

У меня есть один скрипт ps1, который управляет операциями, которые я хочу выполнить. Я использую модули с определениями классов в модулях, использующих шаблон Command.

Все хорошо и хорошо, когда я впервые открываю консоль сеанса PowerShell и запускаю сценарий.

Если я каким-либо образом изменю класс и перезапущу его на той же консоли, похоже, что консоль не принимает измененный скрипт. Мне нужно закрыть консоль PowerShell и запустить скрипт заново, чтобы изменения сработали. В противном случае я просто заставлю сценарий вести себя так же, как и до того, как я внес изменения. Очевидно, что происходит некоторое кеширование.

Мне интересно, решила ли MS эту проблему. Я прочитал много старых постов с жалобами на это.

Я пробовал следующее, но, похоже, ни один из них не работает:

Remove-Variable * -ErrorAction SilentlyContinue;Remove-Module *;$error.Clear();Clear-Host

Я даже пробовал их все вместе. Все еще не помогает.

Можно ли еще что-нибудь сделать, чтобы обеспечить загрузку новейшего кода в любых поддерживающих модулях? Необходимость закрыть всю консоль и перезагрузить ее - серьезная проблема с производительностью.

Пример того, что я делаю: 6

      using module .\Logger.psm1
using module .\AzurePlatformParmsDefault.psm1   
using module .\AzurePlatform.psm1

[Logger] $Logger = [Logger]::Create()
[AzurePlatformParms] $AzurePlatformParms = [AzurePlatformParmsDefault]::Create( $Logger )
[AzurePlatform] $AzurePlatform = [AzurePlatform]::Create( $Logger, $AzurePlatformParms )

[bool] $Result = $AzurePlatform.Execute()

1 ответ

Принято считать, что изначально это невозможно сделать, и решением является создание нового пространства выполнения или процесса.

Вы можете сбросить переменные до значений по умолчанию и импортировать переменные среды из области пользователя / компьютера (в Windows); перед очисткой любых заданий, событий, подписчиков событий и т. д. Это не настоящее обновление сеанса, и классы / пользовательские типы сохранятся.

Чтобы ускорить рабочий процесс, вы можете использовать функцию в своем которые могут автоматизировать создание нового сеанса и загрузку того, что необходимо. Такой подход может сэкономить достаточно времени, так что повторное использование интерактивного сеанса становится тривиальным. Я включу тот, который использую в своем профиле, в качестве примера. Он довольно всеобъемлющий, но я предлагаю адаптировать тот, который подходит для ваших конкретных нужд.

Пример

      function Start-NewSession {
    [CmdletBinding(DefaultParameterSetName = 'NoChange')]
    [Alias('sans')]
    param(
        [Alias('N')]
        [switch]
        $NoClose,

        [Parameter(ParameterSetName = 'Elevate')]
        [Parameter(ParameterSetName = 'NoChange')]
        [Alias('nop')]
        [switch]
        $NoProfile,

        [Parameter(ParameterSetName = 'Elevate')]
        [Parameter(ParameterSetName = 'NoChange')]
        [Alias('A')]
        [switch]
        $AddCommands,

        [Parameter(ParameterSetName = 'Elevate')]
        [Alias('E')]
        [switch]
        $Elevate,

        [Parameter(ParameterSetName = 'DeElevate')]
        [Alias('D')]
        [switch]
        $DeElevate
    )
    $PSAppPath = (Get-Process -Id $PID).Path
    $SPParams = @{
        Filepath         = $PSAppPath
        WorkingDirectory = $PWD
        ArgumentList     = ''
    }
    if ($Elevate.IsPresent) {
        $SPParams['Verb'] = 'RunAs'
    }
    elseif ($DeElevate.IsPresent) {
        $SPParams['FilePath'] = Join-Path $env:windir 'explorer.exe'
        $SPParams['ArgumentList'] = $PSAppPath
    }
    if ($NoProfile.IsPresent) {
        $SPParams['ArgumentList'] += ' -NoProfile'
    }
    if ($AddCommands.IsPresent) {
        $ExtraCmds = Read-Host -Prompt 'Post-startup commands'
        if (-not [string]::IsNullOrWhiteSpace($ExtraCmds)) {
            $SPParams['ArgumentList'] +=
            ' -NoExit -Command "' + $ExtraCmds.Replace('"', '\"') + '"'
        }
    }
    if ([string]::IsNullOrWhiteSpace($SPParams['ArgumentList'])) {
        $SPParams.Remove('ArgumentList')
    }
    Start-Process @SPParams
    if (-not $NoClose.IsPresent) { exit }
}

Это позволяет набирать для создания нового сеанса и закрытия старого.

Другие вопросы по тегам