I have a simple .NET 7 class library referencing this NuGet package (NO other ORACLE packages are included):
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.100" />
Then I have a PowerShell module written in C# (also targeting .NET 7). It references the above mentioned project.
<ProjectReference Include="..\Core\Core.csproj" />
The PowerShell module has only one cmdlet, Test-Oracle. It invokes a method from the Core.dll. The method attempts to connect to ORACLE and execute SELECT * FROM dual.
Works perfectly on my machines - it connects to ORACLE and outputs data. My client, running the same code, gets this exception:
System.TypeLoadException: Could not load type 'System.Security.Principal.WindowsImpersonationContext' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral......
Any ideas how to troubleshoot that?
EDIT:
The "core" project, that does the actual querying to ORACLE, references these NuGet packages:
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.100" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="serilog.sinks.console" Version="4.1.0" />
<PackageReference Include="serilog.sinks.file" Version="5.0.0" />
The PowerShell module project includes this:
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0-preview-06">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
</ItemGroup>
Preface:
The answer below does not solve the problem, but may be of interest for authoring PowerShell modules that should enforce use in PowerShell (Core) 7+ only, i.e. should refuse to load in Windows PowerShell.
To further narrow down your problem, I suggest implementing an assembly-resolve event handler and logging the results:
ResolveEventArgs.RequestingAssemblyproperty of the event-arguments object contains the assembly that requested the load.I may not have the complete picture, but my understanding is this:
You're using the
PowerShellStandard.LibraryNuGet package, which implies that your PowerShell module (cmdlet) can also run in Windows PowerShell, not just in PowerShell (Core) 7+.System.Security.Principal.WindowsImpersonationContexttype - see this GitHub issue for background.However, in order to create a PowerShell module that can be used in a regular PowerShell session (as opposed to creating an application that itself hosts PowerShell), you must use the
PowerShellStandard.Librarypackage - but there is no built-in way that I know of to then constrain the module to only run in one edition or the other (providing better targeting in the future is the subject of GitHub issue #5541).Thus, if you want to enforce that your module can be used in PowerShell (Core) only, you'll have to implement that yourself:[1]
Binary PowerShell modules support an initialization hook that is called when the module is loaded (imported).
In that hook, you can test whether you're running inside .NET Framework (which implies Windows PowerShell) or .NET (Core) (which implies PowerShell (Core)). If the former, you can throw an exception.
Here's a proof-of-concept, using ad hoc-compiled C# code for simplicitly:
If you execute the above in a PowerShell (Core) session, the import should succeed, and you should be able to call
Get-Foothereafter.If you execute in a Windows PowerShell session, a
PlatformNotSupportedExceptionexception should be thrown.[1] Note: Even though PowerShell module manifests have a
CompatiblePSEditionsentry in order to declare edition compatibility, it seems to have purely informational character and isn't enforced, up to at least PowerShell (Core) 7.3.7 (the current version as of this writing). Currently, the entry is respected solely when attempting to import Windows PowerShell's system modules, i.e. those stored in$env:windir\System32\WindowsPowerShell\v1.0\Modules, in PowerShell (Core).