PowerShell - 如何在Runspace中导入模块

时间:2011-06-07 13:41:38

标签: c# powershell powershell-v2.0


我正在尝试在C#中创建一个cmdlet。代码看起来像这样:

[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();

        Collection<PSObject> psObjects = pipeline.Invoke();
        foreach (var psObject in psObjects)
        {
            WriteObject(psObject);
        }
    }
}

但是尝试在PowerShell中执行此CmdLet会给我带来这样的错误:术语“导入 - 模块”不会被识别为cmdlet的名称。 PowerShell中的相同命令不会给我这个错误。如果我执行'Get-Command',我可以看到'Invoke-Module'被列为CmdLet。

有没有办法在Runspace中执行'Import-Module'?

谢谢!

2 个答案:

答案 0 :(得分:20)

有两种方法可以以编程方式导入模块,但我会首先解决您的方法。您的行pipeline.Commands.Add("...")应该只添加命令,而不是命令AND参数。该参数单独添加:

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

上面的管道API使用起来有点笨拙,并且在许多用途中被非正式地弃用,尽管它是许多高级API的基础。在PowerShell v2或更高版本中执行此操作的最佳方法是使用System.Management.Automation.PowerShell类型及其流畅的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()

使用后一种方法的另一种方法是使用InitialSessionState预加载模块,这样就不需要使用Import-Module明确地为运行空间设定种子。请参阅我的博客,了解如何执行此操作:

<击> http://nivot.org/nivot2/post/2010/05/03/PowerShell20DeveloperEssentials1InitializingARunspaceWithAModule.aspx

http://nivot.org/blog/post/2010/05/03/PowerShell20DeveloperEssentials1InitializingARunspaceWithAModule

希望这有帮助。

答案 1 :(得分:0)

最简单的方法是使用AddScript()方法。 您可以这样做:

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

如果要在同一行中添加另一个导入

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

在将脚本添加到管道中之后,.Invoke()并不是强制性的,您可以添加更多脚本并稍后调用。

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

有关更多信息,请访问Microsoft Official website