powershellnugetnuget-speconegetpowershellget

Update-Module duplicates module instead of updating


I'm using PowerShellGet to install my own PowerShell module from my local Nuget feed (packed and published as here).

I'm installing it once like this:

Install-Module MyModule -Scope CurrentUser

And then I'm updating it like this:

Update-Module MyModule

It works as expected, but after every version update I'm getting duplicate of module instead of override:

Get-Module MyModule -ListAvailable

# Output
    Directory: C:\Users\user\Documents\WindowsPowerShell\Modules

ModuleType Version    Name       ExportedCommands
---------- -------    ----       ----------------
Manifest   1.0.0.40   MyModule   {...}
Manifest   1.0.0.39   MyModule   {...}
Manifest   1.0.0.38   MyModule   {...}

Functions which were removed in latest version remain available and PowerShell ISE auto complete shows duplicates for every function:

example in powershell_ise


Update

@CmdrTchort proposed additional checks for investigation, here are results.

Check where modules are installed

Get-Module -Name MyModule -ListAvailable | %{ $_.ModuleBase }

As expected, PowerShellGet installed them to %USERPROFILE%\Documents\WindowsPowerShell\Modules:

C:\Users\user\Documents\WindowsPowerShell\Modules\MyModule\1.0.1.1
C:\Users\user\Documents\WindowsPowerShell\Modules\MyModule\1.0.0.40
C:\Users\user\Documents\WindowsPowerShell\Modules\MyModule\1.0.0.39
C:\Users\user\Documents\WindowsPowerShell\Modules\MyModule\1.0.0.38

I see that $PSScriptRoot contains that path.

Check what Update-Module will do

Update-Module -Name MyModule -WhatIf
# Result
# What if: Performing the operation "Update-Module" on target "Version '1.0.1.1' of module 'MyModule', updating to version '1.0.1.2'".

Check, which version is actually imported:

  1. Start new powershell console
  2. Run Get-Module to ensure that MyModule not imported at all
  3. Run any cmdlet from MyModule
  4. Check, that only one, latest version of MyModule was imported by executing Get-Module again

For me it is:

ModuleType Version    Name       ExportedCommands
---------- -------    ----       ----------------
Manifest   1.0.1.2    MyModule   {...

Conclusion

It seems, that there is no issue here, as @CmdrTchort wrote it is expected that Get-Module -ListAvailable shows all versions installed.

I think that behavior of PowerShell auto-complete in powershell and powershell_ise is a bit confusing though since it shows duplicates of same function if few versions available and functions removed from latest version, probably will be changed soon or somehow configurable.


Solution

  • How are you bundling your module when you're packaging your new versions?

    Powershell supports multiple versions of the same module to be loaded (ListAvailable gives you the various versions).

    Can you do a Get-module MyModule -ListAvailable and print the full-module path to check how they're installed?

    Are you updating your Module-manifest for each version and bundling this in the new folder?

    You can load both versions of the same module into your Powershell Session; if so the last imported cmdlets are the one that are effective.

    Import-Module also supports -MimimumVersion og RequiredVersion.

    As you're experiencing trouble with the regular Import-Module I'm suspecting something messy with how it's structured and the PSModulePath.

    Maybe the $PSModulePath is concated with the "version" path for each new upgrade instead of updating it as it usually does? In which case; the "first" version might be the one loaded, getting the presedence rule over the other. I would do a quick check too see what's in $PSModulePath.

    When you do a Update-Module check to see what it updates with the -WhatIf switch.

    Some links for installing modules/working with modules:

    https://msdn.microsoft.com/en-us/library/dd878350(VS.85).aspx

    https://technet.microsoft.com/en-us/library/dn807166.aspx

    Hope this helps :)