Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Powershell from .Net Core - Could not load file or assembly Microsoft.Management.Infrastructure

I have been trying to run a powershell script from a .Net Core Web app (not discussing best practices here ;) ) with the following code:

    string command = @"& """c:\\my Folder\\myScript.ps1""";

    using (var ps = PowerShell.Create())
    {
        var results = ps.AddScript(command).Invoke();
    }

It works well on my dev machine, but in production it fails when trying to execute this function:

ps.AddScript(command).Invoke()

I get the following exception:

System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified. File name: 'Microsoft.Management.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes) at System.Reflection.RuntimeAssembly.GetExportedTypes() at System.Management.Automation.Runspaces.PSSnapInHelpers.GetAssemblyTypes(Assembly assembly, String name) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzeModuleAssemblyWithReflection(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, Boolean isModuleLoad, Dictionary2& cmdlets, Dictionary2& aliases, Dictionary2& providers, String helpFile, Type& randomCmdletToCheckLinkDemand, Type& randomProviderToCheckLinkDemand) at System.Management.Automation.Runspaces.PSSnapInHelpers.AnalyzePSSnapInAssembly(Assembly assembly, String name, PSSnapInInfo psSnapInInfo, PSModuleInfo moduleInfo, Boolean isModuleLoad, Dictionary2& cmdlets, Dictionary2& aliases, Dictionary2& providers, String& helpFile) at System.Management.Automation.Runspaces.InitialSessionState.ImportPSSnapIn(PSSnapInInfo psSnapInInfo, PSSnapInException& warning) at System.Management.Automation.Runspaces.InitialSessionState.CreateDefault() at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(PSHost host) at System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace() at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync) at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection1 input, PSDataCollection1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.CoreInvoke[TOutput](IEnumerable input, PSDataCollection`1 output, PSInvocationSettings settings) at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)

I don't know which framework/package I am suppose to install to make it run. Target Framework is .Net Core 2.1 which is installed, hence the application running fine except line mentionned above.

The deps.json file contains this:

    "Microsoft.Management.Infrastructure/1.0.0": {
        "dependencies": {
          "NETStandard.Library": "2.0.3",
          "System.Runtime.CompilerServices.VisualC": "4.3.0",
          "System.Runtime.Serialization.Xml": "4.3.0",
          "System.Security.SecureString": "4.3.0",
          "System.Threading.ThreadPool": "4.3.0"
        },
        "compile": {
          "ref/netstandard1.6/Microsoft.Management.Infrastructure.Native.dll": {},
          "ref/netstandard1.6/Microsoft.Management.Infrastructure.dll": {}
        }
      }

Nuget Packages installed:

Microsoft.AspNetCore.App (2.1.1)
Microsoft.PowerShell.Commands.Diagnostics (6.0.5)
Microsoft.PowerShell.SDK (6.0.5)
Microsoft.PowerShell.WSMan.Management (6.0.5)

Edit I also added Microsoft.Management.Infrastructure (1.0.0) but it didn't fix the issue

Edit2 Dev is Windows 10 Pro and Prod is Windows Server 2016 Standard

Edit3 The script runs fine on prod when launched through PowerShell directly. The error shown is when the Web app tries to run PowerShell.

Edit4 App pool account has admin rights and is the same account that I used to run the script manually (not good practice but for now I'm just trying to make this run).

Edit5 I tried to put the dll in the folder of the app on the server and restart the site + recycle the application pool. I tried with every version I could find on the dev machine and nothing worked :/

Edit6 Updated nuget packages from 6.0.5 to latest 6.2.1 , same issue

like image 209
Sylvain Gantois Avatar asked May 29 '19 03:05

Sylvain Gantois


4 Answers

I had same issue, Microsoft.Management.Infrastructure.dll (and associated files) did not get published. Solved by specifying a non-portable RID in publish profile (*.pubxml, not the *.csproj):

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

Problem is probably caused by the fact, that under C:\Users\UserName\.nuget\packages\microsoft.management.infrastructure\1.0.0\runtimes there are only folders with non-portable RIDs; there is no win-x86 and win-x64.

like image 95
George Chakhidze Avatar answered Oct 16 '22 10:10

George Chakhidze


Check application identity pool for Web app in pool. It may be rights issue Use identity impersonation or run on admin account. when you run from console you run with your identity when you run with app its app identity pool

like image 44
Jin Thakur Avatar answered Oct 16 '22 11:10

Jin Thakur


You can load any DLL from Powershell, so one solution that should definitely work is loading the Microsoft.Management.Infrastructure DLL as part of the script. But before doing that, let's verify the difference between what's loaded in dev and prod powershell sessions.

You can get the list of currently loaded assemblies in PowerShell by running [Threading.Thread]::GetDomain().GetAssemblies(). Add this line at the start and end of your script (at the end because PowerShell will auto-load referenced assemblies if it can, when they are first used in the script). Now run the script on dev and prod and compare the results. Chances are, Microsoft.Management.Infrastructure will be missing on prod.

The assemblies list output shows the location of the assemblies. From the dev list, grab the Microsoft.Management.Infrastructure DLL file. You now have two options:

  1. Put the file in the prod machine's GAC. PowerShell should now load the DLL automatically as required.
  2. Make loading this DLL file part of your PowerShell script. Add [Reflection.Assembly]::LoadFile($fullPathToDLL) at the start of your script (or anywhere before you use Microsoft.Management.Infrastructure).
like image 1
Dhruv Murarka Avatar answered Oct 16 '22 11:10

Dhruv Murarka


Add this in your csproj.

<PackageReference Include="NETStandard.Library" Version="1.6.1" />
like image 1
Hugues Gauthier Avatar answered Oct 16 '22 10:10

Hugues Gauthier