3

I have found an interesting case which I can't fully understand.

My runtime - PowerShell 7.2.4

I have two PowerShell Core modules: Net6PowerShellModule and NetstandardPowerShellModule.


Net6PowerShellModule.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Net6PowerShellModule.psd1" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Net6PowerShellModule.psd1">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
    <PackageReference Include="System.Management.Automation" Version="7.2.4" />
  </ItemGroup>
</Project>

Test-Net6Cmdlet.cs

using System.Management.Automation;

namespace Net6PowerShellModule
{
    [Cmdlet("Test", "Net6Cmdlet")]
    public class TestNet6Cmdlet : PSCmdlet
    {
        protected override void ProcessRecord()
        {
            var type = typeof(Microsoft.Extensions.DependencyInjection.IServiceCollection);

            WriteObject("Net6 Cmdlet Run.");
        }
    }
}

Net6PowerShellModule.psd1

@{
    RootModule = 'Net6PowerShellModule.dll'
    ModuleVersion = '0.0.1'
    GUID = '8c1bd929-32bd-44c3-af6b-d9dd261e34f3'
    CmdletsToExport = 'Test-Net6Cmdlet'
}

NetstandardPowerShellModule.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="NetstandardPowerShellModule.psd1" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="NetstandardPowerShellModule.psd1">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.2.0" />
    <PackageReference Include="System.Management.Automation" Version="6.1.2" />
  </ItemGroup>
</Project>

Test-NetstandardCmdlet.cs

using System.Management.Automation;

namespace NetstandardPowerShellModule
{
    [Cmdlet("Test", "NetstandardCmdlet")]
    public class TestNetstandardCmdlet : PSCmdlet
    {
        protected override void ProcessRecord()
        {
            var type = typeof(Microsoft.Extensions.DependencyInjection.IServiceCollection);

            WriteObject("Netstandard 2.0 Cmdlet Run.");
        }
    }
}

NetstandardPowerShellModule.psd1

@{
    RootModule = 'NetstandardPowerShellModule.dll'
    ModuleVersion = '0.0.1'
    GUID = 'eef615d0-aecf-4e89-8f4c-53174f8c99d6'
    CmdletsToExport = 'Test-NetstandardCmdlet'
}


Next, I have two possible use cases for those modules:

  1. Import Net6PowerShellModule
  2. Import NetstandardPowerShellModule
  3. Run Test-Net6Cmdlet
  4. Run Test-NetstandardCmdlet

Result - everything runs correctly. The only loaded assembly is Microsoft.Extensions.DependencyInjection.Abstractions version 6.0.0.


  1. Import Net6PowerShellModule
  2. Import NetstandardPowerShellModule
  3. Run Test-NetstandardCmdlet
  4. Run Test-Net6Cmdlet.

Result - error: Test-Net6Cmdlet: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (0x80131621)


Based on this question, this is not an expected behavior:

Subsequent attempts to load a different version of the assembly: cause a statement-terminating error in Powershell (Core) 7+ Assembly with same name is already loaded.

Why does the first scenario work then?


If I add the RequiredAssemblies = @('Microsoft.Extensions.DependencyInjection.Abstractions.dll') line in both module manifests, I got an expected behavior: regardless of which module is loaded first, I still got an error: Assembly with same name is already loaded.


Update 1

Articles that I've already looked at:

semptra
  • 533
  • 1
  • 5
  • 6

0 Answers0