Skip to content

Import-Module on path ignores version constraints #7496

@rjmholt

Description

@rjmholt

Steps to reproduce

Note: The repro uses a relative path, but an absolute path works too; just insert $PWD instead of the . below.

> mkdir ./AModule
> New-ModuleManifest -Path ./AModule/AModule.psd1 -ModuleVersion '2.0'
> Import-Module -Path ./AModule/
> Import-Module -PassThru -FullQualifiedName @{ ModuleName = "./AModule/AModule.psd1"; ModuleVersion = '3.0' } # Also try the absolute path - same outcome

Expected behavior

Import-Module : The specified module './AModule/AModule.psd1' with version '3.0' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ Import-Module -PassThru -FullyQualifiedName @{ ModuleName = './AModul ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (./AModule:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleWithVersionNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand

Actual behavior


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   2.0        AModule                             

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0-preview.4
PSEdition                      Core
GitCommitId                    6.1.0-preview.4-61-g1243891ea8c04609ce21d0b31d40945fd46a3576
OS                             Linux 4.15.0-30-generic #32-Ubuntu SMP Thu Jul 26 17:42:43 UTC 2018
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

More information

EDIT: Just realised this is for re-imports only (which is good!)

The important note is that importing the same module off the module path will fail:

> $env:PSModulePath += [System.IO.Path]::PathSeparator + $PWD
> Import-Module -PassThru -FullyQualifiedName @{ ModuleName = 'AModule'; ModuleVersion = '3.0' }
Import-Module : The specified module 'AModule' with version '3.0' was not loaded because no valid module file was found in any module directory.
At line:1 char:1
+ Import-Module -PassThru -FullyQualifiedName @{ ModuleName = 'AModule' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ResourceUnavailable: (AModule:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleWithVersionNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
 

This behaviour is caused by this logic:

if (RequiredVersion == null
|| module.Version.Equals(RequiredVersion)
|| (BaseMinimumVersion == null && BaseMaximumVersion == null)
|| module.ModuleType != ModuleType.Manifest
|| (BaseMinimumVersion == null && BaseMaximumVersion != null && module.Version <= BaseMaximumVersion)
|| (BaseMinimumVersion != null && BaseMaximumVersion == null && module.Version >= BaseMinimumVersion)
|| (BaseMinimumVersion != null && BaseMaximumVersion != null && module.Version >= BaseMinimumVersion && module.Version <= BaseMaximumVersion))

Note that it's impossible to instantiate a ModuleSpecification with all checked fields not null, so this check always succeeds.

This is addressed by #7125, but this discovery means it's a breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Committee-ReviewedPS-Committee has reviewed this and made a decisionResolution-FixedThe issue is fixed.WG-Cmdlets-Corecmdlets in the Microsoft.PowerShell.Core module

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions