开发者

PowerShell - How to Import-Module in a Runspace

开发者 https://www.devze.com 2023-03-11 10:20 出处:网络
I am trying to create a cmdlet in C#. The code looks something like this: [Cmdlet(VerbsCommon.Get, \"HeapSummary\")]

I am trying to create a cmdlet in C#. The code looks something like this:

[Cmdlet(VerbsCommon.Get, "HeapSummary")]
public class Get_HeapSummary : Cmdlet
{
    protected override void ProcessRecord()
    {
        RunspaceConfiguration config = RunspaceConfiguration.Create();
        Runspace myRs = RunspaceFactory.CreateRunspace(config);
        myRs.Open();

        RunspaceInvoke scriptInvoker = new RunspaceInvoke(myRs);
        scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

        Pipeline pipeline = myRs.CreatePipeline();
        pipeline.Commands.Add(@"Import-Module G:\PowerShell\PowerDbg.psm1");
        //...
        pipeline.Invoke();

        Coll开发者_JAVA技巧ection<PSObject> psObjects = pipeline.Invoke();
        foreach (var psObject in psObjects)
        {
            WriteObject(psObject);
        }
    }
}

But trying to execute this CmdLet in PowerShell gives me this error: The term Import-Module is not recognized as the name of a cmdlet. The same command in PowerShell doesn't give me this error. If I execute 'Get-Command' instead, I can see that 'Invoke-Module' is listed as a CmdLet.

Is there a way to do an 'Import-Module' in a Runspace?

Thanks!


There are two ways to import modules programmatically, but I'll address your method first. Your line pipeline.Commands.Add("...") should only be adding the command, not the command AND the parameter. The parameter is added separately:

# argument is a positional parameter
pipeline.Commands.Add("Import-Module");
var command = pipeline.Commands[0];
command.Parameters.Add("Name", @"G:\PowerShell\PowerDbg.psm1")

The above pipeline API is a bit clumsy to use and is informally deprecated for many uses although it's at the base of many of the higher level APIs. The best way to do this in powershell v2 or higher is by using the System.Management.Automation.PowerShell Type and its fluent API:

# if Create() is invoked, a runspace is created for you
var ps = PowerShell.Create(myRS);
ps.Commands.AddCommand("Import-Module").AddArgument(@"g:\...\PowerDbg.psm1")
ps.Invoke()

Another way when using the latter method is to preload modules using InitialSessionState, which avoids the need to seed the runspace explictly with Import-Module.

InitialSessionState initial = InitialSessionState.CreateDefault();
    initialSession.ImportPSModule(new[] { modulePathOrModuleName1, ... });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    RunspaceInvoke invoker = new RunspaceInvoke(runspace);
    Collection<PSObject> results = invoker.Invoke("...");

Hope this helps.


The simplest way that you can do this is by using AddScript() method. You can do:

pipeline.AddScript("Import-Module moduleName").Invoke();

If you want to add another import in the same line

pipeline.AddScript("Import-Module moduleName \n Import-Module moduleName2").Invoke();

Its not mandatory to .Invoke() right ofter you add the script to the pipeline, you can add more scripts and invoke later.

pipeline.AddScript("Import-Module moduleName");
pipeline.AddCommand("pwd");
pipeline.Invoke();

For more information visit Microsoft Official website

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号