PowerShell - Как импортировать модуль в пространстве выполнения - PullRequest
13 голосов
/ 07 июня 2011


Я пытаюсь создать командлет в C #. Код выглядит примерно так:

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

Но попытка выполнить этот CmdLet в PowerShell дает мне такую ​​ошибку: Термин Import-Module не распознается как имя командлета . Та же команда в PowerShell не дает мне этой ошибки. Если вместо этого выполнить «Get-Command», я вижу, что «Invoke-Module» указан как CmdLet.

Есть ли способ сделать 'Import-Module' в пространстве выполнения?

Спасибо!

1 Ответ

21 голосов
/ 07 июня 2011

Существует два способа программного импорта модулей, но сначала я расскажу о вашем методе. Ваша строка pipeline.Commands.Add("...") должна только добавлять команду, а не команду И параметр. Параметр добавляется отдельно:

# 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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...