PowerShell / SecretManagement

PowerShell module to consistent usage of secrets through different extension vaults
MIT License
317 stars 46 forks source link

While developing an extension: Prevent session restart for reloading the module #206

Open Callidus2000 opened 1 year ago

Callidus2000 commented 1 year ago

Summary of the new feature / enhancement

I'm developing a (script based) extension for SecretManagement. Currently any code change needs a restart of the terminal. In earlier versions Register-SecretVault did a Import-Module -Force but I'm afraid that's gone with the new runspace design.

Expected Behavior

Register-SecretVault -Name MySafe -ModuleName $modulePath -AllowClobber
# Do some Changes in the code
Register-SecretVault -Name MySafe -ModuleName $modulePath -AllowClobber
# Changed code is executed

Actual behavior

Register-SecretVault -Name MySafe -ModuleName $modulePath -AllowClobber
# Do some Changes in the code
Register-SecretVault -Name MySafe -ModuleName $modulePath -AllowClobber
# Old code is executed

Proposed technical implementation details (optional)

No response

llewellyn-marriott commented 1 year ago

I ran into this issue also; it was making extension development very tedious. I used this quick hack at the start of my test script:

# Get the runspace field
$RunspaceField = (([Microsoft.PowerShell.SecretManagement.SecretVaultInfo].Assembly.GetTypes() | Where-Object Name -eq 'PowerShellInvoker').DeclaredFields | Where-Object Name -eq '_runspace')
# Get current runspace value and dispose of it
$RunspaceValue = $RunspaceField.GetValue($null)
if($NULL -ne $RunspaceValue) {
    $RunspaceValue.Dispose()
}
# Set the runspace field to null
$RunspaceField.SetValue($null, $null)

This code will dispose the Runspace if it is set, and then set it to null. The Runspace will be recreated next time it is used.

I suppose the fix would be to remove the module from the Runspace when Unregister-SecretVault is called. As long as there are no other vaults registered with the same module.

Callidus2000 commented 1 year ago

Nice. I've started to use the module RestartableSession. It automatically restarts a new clean session with a lot of initialization options. The workaround is documented in my template module and in the corresponding ReadMe.

I'll include your fix into my documentation. It's a lot faster than mine, but the RestartableSession approach has the benefit that it keeps other vaults alive.