@@ -591,6 +591,27 @@ private void ImportModule_ViaAssembly(ImportModuleOptions importModuleOptions, A
591
591
}
592
592
}
593
593
594
+ private PSModuleInfo ImportModule_LocallyViaName_WithTelemetry ( ImportModuleOptions importModuleOptions , string name )
595
+ {
596
+ PSModuleInfo foundModule = ImportModule_LocallyViaName ( importModuleOptions , name ) ;
597
+ if ( foundModule != null )
598
+ {
599
+ SetModuleBaseForEngineModules ( foundModule . Name , this . Context ) ;
600
+
601
+ // report loading of the module in telemetry
602
+ // avoid double reporting for WinCompat modules that go through CommandDiscovery\AutoloadSpecifiedModule
603
+ if ( ! foundModule . IsWindowsPowerShellCompatModule )
604
+ {
605
+ ApplicationInsightsTelemetry . SendTelemetryMetric ( TelemetryType . ModuleLoad , foundModule . Name ) ;
606
+ #if LEGACYTELEMETRY
607
+ TelemetryAPI . ReportModuleLoad ( foundModule ) ;
608
+ #endif
609
+ }
610
+ }
611
+
612
+ return foundModule ;
613
+ }
614
+
594
615
private PSModuleInfo ImportModule_LocallyViaName ( ImportModuleOptions importModuleOptions , string name )
595
616
{
596
617
try
@@ -820,6 +841,24 @@ private PSModuleInfo ImportModule_LocallyViaName(ImportModuleOptions importModul
820
841
return null ;
821
842
}
822
843
844
+ private PSModuleInfo ImportModule_LocallyViaFQName ( ImportModuleOptions importModuleOptions , ModuleSpecification modulespec )
845
+ {
846
+ RequiredVersion = modulespec . RequiredVersion ;
847
+ MinimumVersion = modulespec . Version ;
848
+ MaximumVersion = modulespec . MaximumVersion ;
849
+ BaseGuid = modulespec . Guid ;
850
+
851
+ PSModuleInfo foundModule = ImportModule_LocallyViaName ( importModuleOptions , modulespec . Name ) ;
852
+
853
+ if ( foundModule != null )
854
+ {
855
+ ApplicationInsightsTelemetry . SendTelemetryMetric ( TelemetryType . ModuleLoad , foundModule . Name ) ;
856
+ SetModuleBaseForEngineModules ( foundModule . Name , this . Context ) ;
857
+ }
858
+
859
+ return foundModule ;
860
+ }
861
+
823
862
#endregion Local import
824
863
825
864
#region Remote import
@@ -1024,7 +1063,10 @@ private PSModuleInfo ImportModule_RemotelyViaPsrpSession_SinglePreimportedModule
1024
1063
{
1025
1064
powerShell . AddCommand ( "Export-PSSession" ) ;
1026
1065
powerShell . AddParameter ( "OutputModule" , wildcardEscapedPath ) ;
1027
- powerShell . AddParameter ( "AllowClobber" , true ) ;
1066
+ if ( ! importModuleOptions . NoClobberExportPSSession )
1067
+ {
1068
+ powerShell . AddParameter ( "AllowClobber" , true ) ;
1069
+ }
1028
1070
powerShell . AddParameter ( "Module" , remoteModuleName ) ; // remoteModulePath is currently unsupported by Get-Command and implicit remoting
1029
1071
powerShell . AddParameter ( "Force" , true ) ;
1030
1072
powerShell . AddParameter ( "FormatTypeName" , "*" ) ;
@@ -1816,21 +1858,7 @@ protected override void ProcessRecord()
1816
1858
{
1817
1859
foreach ( string name in Name )
1818
1860
{
1819
- PSModuleInfo foundModule = ImportModule_LocallyViaName ( importModuleOptions , name ) ;
1820
- if ( foundModule != null )
1821
- {
1822
- SetModuleBaseForEngineModules ( foundModule . Name , this . Context ) ;
1823
-
1824
- // report loading of the module in telemetry
1825
- // avoid double reporting for WinCompat modules that go through CommandDiscovery\AutoloadSpecifiedModule
1826
- if ( ! foundModule . IsWindowsPowerShellCompatModule )
1827
- {
1828
- ApplicationInsightsTelemetry . SendTelemetryMetric ( TelemetryType . ModuleLoad , foundModule . Name ) ;
1829
- #if LEGACYTELEMETRY
1830
- TelemetryAPI . ReportModuleLoad ( foundModule ) ;
1831
- #endif
1832
- }
1833
- }
1861
+ ImportModule_LocallyViaName_WithTelemetry ( importModuleOptions , name ) ;
1834
1862
}
1835
1863
}
1836
1864
else if ( this . ParameterSetName . Equals ( ParameterSet_ViaPsrpSession , StringComparison . OrdinalIgnoreCase ) )
@@ -1845,17 +1873,7 @@ protected override void ProcessRecord()
1845
1873
{
1846
1874
foreach ( var modulespec in FullyQualifiedName )
1847
1875
{
1848
- RequiredVersion = modulespec . RequiredVersion ;
1849
- MinimumVersion = modulespec . Version ;
1850
- MaximumVersion = modulespec . MaximumVersion ;
1851
- BaseGuid = modulespec . Guid ;
1852
-
1853
- PSModuleInfo foundModule = ImportModule_LocallyViaName ( importModuleOptions , modulespec . Name ) ;
1854
- ApplicationInsightsTelemetry . SendTelemetryMetric ( TelemetryType . ModuleLoad , modulespec . Name ) ;
1855
- if ( foundModule != null )
1856
- {
1857
- SetModuleBaseForEngineModules ( foundModule . Name , this . Context ) ;
1858
- }
1876
+ ImportModule_LocallyViaFQName ( importModuleOptions , modulespec ) ;
1859
1877
}
1860
1878
}
1861
1879
else if ( this . ParameterSetName . Equals ( ParameterSet_FQName_ViaPsrpSession , StringComparison . OrdinalIgnoreCase ) )
@@ -1884,19 +1902,10 @@ private bool IsModuleInDenyList(string[] moduleDenyList, string moduleName, Modu
1884
1902
{
1885
1903
Debug . Assert ( string . IsNullOrEmpty ( moduleName ) ^ ( moduleSpec == null ) , "Either moduleName or moduleSpec must be specified" ) ;
1886
1904
1887
- var exactModuleName = string . Empty ;
1905
+ // moduleName can be just a module name and it also can be a full path to psd1 from which we need to extract the module name
1906
+ string exactModuleName = ModuleIntrinsics . GetModuleName ( moduleSpec == null ? moduleName : moduleSpec . Name ) ;
1888
1907
bool match = false ;
1889
1908
1890
- if ( ! string . IsNullOrEmpty ( moduleName ) )
1891
- {
1892
- // moduleName can be just a module name and it also can be a full path to psd1 from which we need to extract the module name
1893
- exactModuleName = Path . GetFileNameWithoutExtension ( moduleName ) ;
1894
- }
1895
- else if ( moduleSpec != null )
1896
- {
1897
- exactModuleName = moduleSpec . Name ;
1898
- }
1899
-
1900
1909
foreach ( var deniedModuleName in moduleDenyList )
1901
1910
{
1902
1911
// use case-insensitive module name comparison
@@ -1941,6 +1950,49 @@ private List<T> FilterModuleCollection<T>(IEnumerable<T> moduleCollection)
1941
1950
return filteredModuleCollection ;
1942
1951
}
1943
1952
1953
+ private void PrepareNoClobberWinCompatModuleImport ( string moduleName , ModuleSpecification moduleSpec , ref ImportModuleOptions importModuleOptions )
1954
+ {
1955
+ Debug . Assert ( string . IsNullOrEmpty ( moduleName ) ^ ( moduleSpec == null ) , "Either moduleName or moduleSpec must be specified" ) ;
1956
+
1957
+ // moduleName can be just a module name and it also can be a full path to psd1 from which we need to extract the module name
1958
+ string coreModuleToLoad = ModuleIntrinsics . GetModuleName ( moduleSpec == null ? moduleName : moduleSpec . Name ) ;
1959
+
1960
+ var isModuleToLoadEngineModule = InitialSessionState . IsEngineModule ( coreModuleToLoad ) ;
1961
+ string [ ] noClobberModuleList = PowerShellConfig . Instance . GetWindowsPowerShellCompatibilityNoClobberModuleList ( ) ;
1962
+ if ( isModuleToLoadEngineModule || ( ( noClobberModuleList != null ) && noClobberModuleList . Contains ( coreModuleToLoad , StringComparer . OrdinalIgnoreCase ) ) )
1963
+ {
1964
+ // if it is one of engine modules - first try to load it from $PSHOME\Modules
1965
+ // otherwise rely on $env:PSModulePath (in which WinPS module location has to go after CorePS module location)
1966
+ if ( isModuleToLoadEngineModule )
1967
+ {
1968
+ string expectedCoreModulePath = Path . Combine ( ModuleIntrinsics . GetPSHomeModulePath ( ) , coreModuleToLoad ) ;
1969
+ if ( Directory . Exists ( expectedCoreModulePath ) )
1970
+ {
1971
+ coreModuleToLoad = expectedCoreModulePath ;
1972
+ }
1973
+ }
1974
+
1975
+ if ( moduleSpec == null )
1976
+ {
1977
+ ImportModule_LocallyViaName_WithTelemetry ( importModuleOptions , coreModuleToLoad ) ;
1978
+ }
1979
+ else
1980
+ {
1981
+ ModuleSpecification tmpModuleSpec = new ModuleSpecification ( )
1982
+ {
1983
+ Guid = moduleSpec . Guid ,
1984
+ MaximumVersion = moduleSpec . MaximumVersion ,
1985
+ Version = moduleSpec . Version ,
1986
+ RequiredVersion = moduleSpec . RequiredVersion ,
1987
+ Name = coreModuleToLoad
1988
+ } ;
1989
+ ImportModule_LocallyViaFQName ( importModuleOptions , tmpModuleSpec ) ;
1990
+ }
1991
+
1992
+ importModuleOptions . NoClobberExportPSSession = true ;
1993
+ }
1994
+ }
1995
+
1944
1996
internal override IList < PSModuleInfo > ImportModulesUsingWinCompat ( IEnumerable < string > moduleNames , IEnumerable < ModuleSpecification > moduleFullyQualifiedNames , ImportModuleOptions importModuleOptions )
1945
1997
{
1946
1998
IList < PSModuleInfo > moduleProxyList = new List < PSModuleInfo > ( ) ;
@@ -1968,6 +2020,24 @@ internal override IList<PSModuleInfo> ImportModulesUsingWinCompat(IEnumerable<st
1968
2020
return new List < PSModuleInfo > ( ) ;
1969
2021
}
1970
2022
2023
+ // perform necessary preparations if module has to be imported with NoClobber mode
2024
+ if ( filteredModuleNames != null )
2025
+ {
2026
+ foreach ( string moduleName in filteredModuleNames )
2027
+ {
2028
+ PrepareNoClobberWinCompatModuleImport ( moduleName , null , ref importModuleOptions ) ;
2029
+ }
2030
+ }
2031
+
2032
+ if ( filteredModuleFullyQualifiedNames != null )
2033
+ {
2034
+ foreach ( var moduleSpec in filteredModuleFullyQualifiedNames )
2035
+ {
2036
+ PrepareNoClobberWinCompatModuleImport ( null , moduleSpec , ref importModuleOptions ) ;
2037
+ }
2038
+ }
2039
+
2040
+ // perform the module import / proxy generation
1971
2041
moduleProxyList = ImportModule_RemotelyViaPsrpSession ( importModuleOptions , filteredModuleNames , filteredModuleFullyQualifiedNames , WindowsPowerShellCompatRemotingSession , usingWinCompat : true ) ;
1972
2042
1973
2043
foreach ( PSModuleInfo moduleProxy in moduleProxyList )
0 commit comments