Skip to content

Commit efbdea5

Browse files
SteveL-MSFTdaxian-dbw
authored andcommitted
Fix importing remote module using version filters and added tests (PowerShell#4900)
- Add tests for remote import-module - Fix issue with remotely importing module where it was checking the version filter incorrectly against the proxy module - The filters are applied when importing the module remotely - After proxy module is generated it always has a module version of 1.0, so the filters will always fail when importing the proxy locally
1 parent 901a61b commit efbdea5

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,14 +986,28 @@ private PSModuleInfo ImportModule_RemotelyViaPsrpSession_SinglePreimportedModule
986986
// import the proxy module just as any other local module
987987
//
988988
object[] oldArgumentList = this.ArgumentList;
989+
Version originalBaseMinimumVersion = BaseMinimumVersion;
990+
Version originalBaseMaximumVersion = BaseMaximumVersion;
991+
Version originalBaseRequiredVersion = BaseRequiredVersion;
989992
try
990993
{
991994
this.ArgumentList = new object[] { psSession };
995+
996+
// The correct module version has already been imported from the remote session and created locally.
997+
// The locally created module always has a version of 1.0 regardless of the actual module version
998+
// imported from the remote session, and version checking is no longer needed and will not work while
999+
// importing this created local module.
1000+
BaseMinimumVersion = null;
1001+
BaseMaximumVersion = null;
1002+
BaseRequiredVersion = null;
9921003
ImportModule_LocallyViaName(importModuleOptions, wildcardEscapedPsd1Path);
9931004
}
9941005
finally
9951006
{
9961007
this.ArgumentList = oldArgumentList;
1008+
BaseMinimumVersion = originalBaseMinimumVersion;
1009+
BaseMaximumVersion = originalBaseMaximumVersion;
1010+
BaseRequiredVersion = originalBaseRequiredVersion;
9971011
}
9981012

9991013
//

test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@
2121
{ Import-Module -ModuleInfo $a } | Should Not Throw
2222
(Get-Module -Name $moduleName).Name | Should Be $moduleName
2323
}
24+
25+
It "should be able to load an already loaded module" {
26+
Import-Module $moduleName
27+
{ $script:module = Import-Module $moduleName -PassThru } | Should Not Throw
28+
Get-Module -Name $moduleName | Should Be $script:module
29+
}
2430
}
2531

2632
Describe "Import-Module with ScriptsToProcess" -Tags "CI" {
27-
33+
2834
BeforeAll {
2935
$moduleRootPath = Join-Path $TestDrive 'TestModules'
3036
New-Item $moduleRootPath -ItemType Directory -Force | Out-Null
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
Describe "Remote import-module tests" -Tags 'Feature','RequireAdminOnWindows' {
2+
3+
BeforeAll {
4+
$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
5+
$modulePath = "$testdrive\Modules\TestImport"
6+
if (!$IsWindows) {
7+
$PSDefaultParameterValues["it:skip"] = $true
8+
} else {
9+
$pssession = New-RemoteSession
10+
Invoke-Command -Session $pssession -ScriptBlock { $env:PSModulePath += ";${using:testdrive}" }
11+
# pending https://github.com/PowerShell/PowerShell/issues/4819
12+
# $cimsession = New-RemoteSession -CimSession
13+
$null = New-Item -ItemType Directory -Path $modulePath
14+
Set-Content -Path $modulePath\testimport.psm1 -Value "function test-hello { 'world' }"
15+
New-ModuleManifest -Path $modulePath\testimport.psd1 -ModuleVersion 1.2.3 -RootModule testimport.psm1 -FunctionsToExport "test-hello" `
16+
-HelpInfoUri "https://help" -Guid (New-Guid)
17+
}
18+
}
19+
20+
AfterAll {
21+
$global:PSDefaultParameterValues = $originalDefaultParameterValues
22+
if ($IsWindows) {
23+
$pssession | Remove-PSSession -ErrorAction SilentlyContinue
24+
}
25+
}
26+
27+
BeforeEach {
28+
Remove-Module TestImport -Force -ErrorAction SilentlyContinue
29+
}
30+
31+
It "Import-Module can be called as an API with '<parameter>' = '<value>'" -TestCases @(
32+
@{parameter = "Global" ; value = $true},
33+
@{parameter = "Global" ; value = $false},
34+
@{parameter = "Prefix" ; value = "Hello"},
35+
@{parameter = "Name" ; value = "foo","bar"},
36+
@{parameter = "FullyQualifiedName" ; value = @{ModuleName='foo';RequiredVersion='0.0'},@{ModuleName='bar';RequiredVersion='1.1'}},
37+
@{parameter = "Assembly" ; script = { [System.AppDomain]::CurrentDomain.GetAssemblies() | Select-Object -First 2 }}
38+
@{parameter = "Function" ; value = "foo","bar"},
39+
@{parameter = "Cmdlet" ; value = "foo","bar"},
40+
@{parameter = "Variable" ; value = "foo","bar"},
41+
@{parameter = "Alias" ; value = "foo","bar"},
42+
@{parameter = "Force" ; value = $true},
43+
@{parameter = "Force" ; value = $false},
44+
@{parameter = "PassThru" ; value = $true},
45+
@{parameter = "PassThru" ; value = $false},
46+
@{parameter = "AsCustomObject" ; value = $true},
47+
@{parameter = "AsCustomObject" ; value = $false},
48+
@{parameter = "MinimumVersion" ; value = "1.2.3"},
49+
@{parameter = "MaximumVersion" ; value = "3.2.1"},
50+
@{parameter = "RequiredVersion" ; value = "1.1.1"},
51+
@{parameter = "ArgumentList" ; value = "hello","world"},
52+
@{parameter = "DisableNameChecking"; value = $true},
53+
@{parameter = "DisableNameChecking"; value = $false},
54+
@{parameter = "NoClobber" ; value = $true},
55+
@{parameter = "NoClobber" ; value = $false},
56+
@{parameter = "Scope" ; value = "Local"},
57+
@{parameter = "Scope" ; value = "Global"},
58+
@{parameter = "PSSession" ; value = $pssession},
59+
# @{parameter = "CimSession" ; value = $cimsession},
60+
@{parameter = "CimResourceUri" ; value = "http://foo/"},
61+
@{parameter = "CimNamespace" ; value = "foo"}
62+
) {
63+
param($parameter, $value, $script)
64+
65+
$importModuleCommand = [Microsoft.PowerShell.Commands.ImportModuleCommand]::new()
66+
if ($script -ne $null) {
67+
$value = & $script
68+
}
69+
$importModuleCommand.$parameter = $value
70+
if ($parameter -eq "FullyQualifiedName") {
71+
$importModuleCommand.FullyQualifiedName.Count | Should BeExactly 2
72+
$importModuleCommand.FullyQualifiedName | Should BeOfType "Microsoft.PowerShell.Commands.ModuleSpecification"
73+
$importModuleCommand.FullyQualifiedName[0].Name | Should Be "foo"
74+
$importModuleCommand.FullyQualifiedName[0].RequiredVersion | Should Be "0.0"
75+
$importModuleCommand.FullyQualifiedName[1].Name | Should Be "bar"
76+
$importModuleCommand.FullyQualifiedName[1].RequiredVersion | Should Be "1.1"
77+
} else {
78+
$importModuleCommand.$parameter | Should BeExactly $value
79+
}
80+
}
81+
82+
It "Import-Module can import over remote session: <test>" -TestCases @(
83+
@{ test = "pssession" ; parameters = @{Name="TestImport";PSSession=$pssession}},
84+
# @{ test = "cimsession" ; parameters = @{Name="TestImport";CimSession=$cimsession}},
85+
@{ test = "minimumversion" ; parameters = @{Name="TestImport";PSSession=$pssession;MinimumVersion="1.0";Force=$true}},
86+
@{ test = "requiredversion" ; parameters = @{Name="TestImport";PSSession=$pssession;RequiredVersion="1.2.3"}},
87+
@{ test = "maxiumversion" ; parameters = @{Name="TestImport";PSSession=$pssession;MaximumVersion="2.0"}},
88+
@{ test = "invalid miniumversion" ; parameters = @{Name="TestImport";PSSession=$pssession;MinimumVersion="2.0"};
89+
errorid = "Modules_ModuleWithVersionNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand,Microsoft.PowerShell.Commands.ImportModuleCommand"},
90+
@{ test = "invalid maximumversion" ; parameters = @{Name="TestImport";PSSession=$pssession;MaximumVersion="1.0"};
91+
errorid = "Modules_ModuleWithVersionNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand,Microsoft.PowerShell.Commands.ImportModuleCommand"},
92+
@{ test = "fullyqualifiedname" ; parameters = @{FullyQualifiedName=@{Modulename="TestImport"; RequiredVersion="1.2.3"};PSSession=$pssession}}
93+
) {
94+
param ($test, $parameters, $errorid)
95+
96+
Invoke-Command -Session $pssession -ScriptBlock { $env:PSModulePath += ";$(Split-Path $using:modulePath)"}
97+
Get-Module TestImport | Should BeNullOrEmpty
98+
if ($errorid) {
99+
{ Import-Module @parameters -ErrorAction Stop } | ShouldBeErrorId $errorid
100+
} else {
101+
Import-Module @parameters
102+
$module = Get-Module TestImport
103+
$module.Name | Should BeExactly "TestImport"
104+
105+
# generated proxy module always uses 1.0
106+
$module.Version | Should BeExactly "1.0"
107+
108+
test-hello | Should BeExactly "world"
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)