PowerShell / SecretManagement

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

Uninstalling a registered extension vault doesn't throw an error #185

Closed user8446 closed 2 years ago

user8446 commented 2 years ago

Hi, I have noticed that if there is a registered extension vault you cannot upgrade the SecretManagement module or the extension vault module without first unregistering - a necessary safeguard. However, you can uninstall a registered extension vault without error and without first unregistering. I believe it would be a good idea to have to unregister before uninstalling as well, the same as you have to do if there is a dependency. Thoughts?

PaulHigin commented 2 years ago

Actually, you can upgrade an extension vault without first unregistering it. Both SecretManagement and extension vaults are PowerShell modules, and what prevents a PowerShell module from successfully being upgraded is if the PowerShell module is dependent on .NET binaries. .NET binaries cannot be unloaded or new versions re-loaded in a session. Consequently, PowerShell modules that are based on .NET binaries cannot be updated in a session that has already imported the (.NET based) module. Note that this doesn't apply to script-only based modules which have no .NET dependencies, but most extension vaults are .NET based.

.NET has introduced assembly load context (ALC) to try and mitigate this problem but PowerShell still loads all modules into the default ALC for backward compatibility, and is currently unable to take advantage of it (plus there are other issues with it you can read about in PowerShell github if you are interested).

Best practice is to always close the current PowerShell session and upgrade a (.NET based) module in a new session that does not have the module currently imported.

Of course, there is always the possibility of a new SecretManagement with breaking changes, in which case unregistering extension vaults should be done first. But we try very hard to never do this, and ensure backward compatibility.

Upgrading PowerShell modules is done through PowerShellGet (V3 is upcoming), but there is currently no mechanism to first ask an existing module installation to perform some sort of preliminary work (such as unregistering extension vaults). But you can make a request for it (https://github.com/PowerShell/PowerShellGet/issues).

user8446 commented 2 years ago

Hi @PaulHigin , Thank you for the .NET info, I learned something today!

I misspoke on the original issue - sorry it was late.

If I try to uninstall SecretManagement w/ a vault extension registered, I'll receive a dependency error. If I try to uninstall a registered SecretManagement.KeePass, it proceeds without error when I should receive the same error.

Furthermore, after updating either module it stays registered to the old version. You have to unregister, delete the old, and re-register. Is that the expected behavior?

Sorry for the confusion!

PS C:\Windows\System32> uninstall-module Microsoft.PowerShell.SecretManagement
Uninstall-Package: The module 'Microsoft.PowerShell.SecretManagement' of version '1.1.1' in module base folder
'C:\Users\##\Documents\PowerShell\Modules\Microsoft.PowerShell.SecretManagement\1.1.1' cannot be uninstalled,
because one or more other modules 'SecretManagement.KeePass' are dependent on this module. Uninstall the modules that
depend on this module before uninstalling module 'Microsoft.PowerShell.SecretManagement'.

PS C:\Windows\System32> uninstall-module SecretManagement.KeePass
PS C:\Windows\System32> install-module SecretManagement.KeePass
PS C:\Windows\System32> get-secretvault

Name         ModuleName               IsDefaultVault
----         ----------               --------------
KeePassVault SecretManagement.Keepass True

PS C:\Windows\System32>
PaulHigin commented 2 years ago

Oh I see. PowerShellGet won't uninstall a PowerShell module if other installed modules are dependent on it. You can force the uninstall by using the -Force parameter.

Uninstall-Module Microsoft.PowerShell.SecretManagement -Force

The upcoming PowerShellGet v3 will have a new parameter (-SkipDependencyCheck) that specifically disables the dependency check when uninstalling, which I feel is more clear.

Uninstall-PSResource -Name Microsoft.PowerShell.SecretManagement -SkipDependencyCheck
user8446 commented 2 years ago

So this is more of a PowerShellGet package provider issue then, I'm closing out. Thank you for the reply and info!