Description
PreRelease modules that have binary assemblies cannot be upgraded if they are imported in any PowerShell session on the machine, because the binary will be locked.
It's practically impossible to update a PreRelease version of a module with binaries if you import it in your profile.
Expected Behavior
Update-Module should work, and should never break a working module.
Current Behavior:
PackageManagement\Install-Package : Administrator rights are required to install or update. Log on to the computer with an account that has Administrator
rights, and then try again, or install by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with elevated
rights (Run as Administrator).
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.6.7\PSModule.psm1:12955 char:20
+ ... $sid = PackageManagement\Install-Package @PSBoundParameters
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (System.Collections.ArrayList:String) [Install-Package], Exception
+ FullyQualifiedErrorId : AdministratorRightsNeededOrSpecifyCurrentUserScope,Copy-Module,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage
Unfortunately, this error message is utterly incorrect, in every way
First: administrator rights won't help. What we need to do is to close every instance of PowerShell (including in terminals, in editors, etc), and then open a new instance with -noprofile (NOTE: if we're trying to upgrade PSReadLine -- try using ISE, because that's the only way to avoid using PSReadLine).
Second: "adding -Scope CurrentUser
to your command" won't help. That's not a valid parameter for this command! 🙈💥💀🔥 And in any case, we're actually trying to upgrade to CurrentUser scope! The reason we can't is because the file is locked, not because we are trying to install somewhere we're not allowed to.
Third: Why are we repeating the advice to run "the Windows PowerShell session with elevated
rights (Run as Administrator)." For goodness sakes!
Additionally, the failed upgrade results in obliterating the existing install of the module.
Because the previous install was in the same folder, it's now gone (except for that binary file) -- AND WE CANNOT REINSTALL IT for the same reason the upgrade failed.
Possible Solution
Two possible solutions. My favorite would be:
- Always install modules into folders with full semver names
- If there's a +metadata or -postfix create a junction point with the System.Version name. I.e.
4.0.0
->4.0.0-beta02
... - When updating a pre-release, just adjust the junction after the install is successful.
Alternatively, if junctions are not supported in the file system:
- When PowerShellGet realizes that it's going to be installing to the same folder as an existing module, it should move all of the files to a SemVer-named folder before attempting to install the new version.
- If the install fails for any reason (e.g. network interruption), it should clean up by moving the old version back!
- The old pre-release version could even be left behind (and restored if the user removes the new pre-release), and could be cleaned up explicitly by the user at a later date -- just like regular versions.
Steps To Reproduce:
Install-Module PANSIES -RequiredVersion 1.4.0-beta02 -Scope CurrentUser
Import-Module PANSIES
Get-InstalledModule Pansies
and see you have beta02- Attempt to
Update-Module PANSIES -AllowPrerelease
(should update to-beta03
but will instead die in a mysterious fire) Get-InstalledModule Pansies
and see you don't have beta03, nor do you have beta02 anymore!
Context
My module PANSIES, and the built-in PSReadLine are just two examples of this which I have imported in my profile (or which PowerShell imports by default) which simply break when you try to update them.
Your Environment
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.17134.228
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17134.228
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
> Get-Module PowerShellGet
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.6.7 PowerShellGet {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
> Get-Module -ListAvailable PowerShellGet,PackageManagement
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.1.7.2 PackageManagement {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script 1.1.7.0 PackageManagement {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script 1.1.1.0 PackageManagement {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Binary 1.0.0.1 PackageManagement {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script 1.6.7 PowerShellGet {Find-Command, Find-DSCResource, Find-Module, Find-RoleCapability...}
Script 1.6.0 PowerShellGet {Install-Module, Find-Module, Save-Module, Update-Module...}
Script 1.1.3.1 PowerShellGet {Install-Module, Find-Module, Save-Module, Update-Module...}
Script 1.0.0.1 PowerShellGet {Install-Module, Find-Module, Save-Module, Update-Module...}