PowerShell - как импортировать модуль в пространстве выполнения
Я пытаюсь создать командлет в С#. Код выглядит примерно так:
[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" в Runspace?
Спасибо!
Ответы
Ответ 1
Существует два способа импорта модулей программно, но я сначала рассмотрю ваш метод. Ваша строка 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
Type и его свободный 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
Надеюсь, что это поможет.