如何从二进制(c#)模块调用PowerShell Cmdlet
本文关键字:模块 调用 PowerShell Cmdlet 二进制 | 更新日期: 2023-09-27 18:11:41
我正在编写一个自定义二进制(c#) Cmdlet,并且从这个Cmdlet中,我想调用另一个PowerShell二进制Cmdlet(例如Get-ADUser)并将结果带回我的Cmdlet。实现这一目标的最佳方式是什么?注意:在我的自定义Cmdlet中创建另一个PowerShell实例(如这里所述)似乎不是完成此任务的最有效方法。
我看着这个问题。然而,它并没有回答我的问题。如果您可以引用实现cmdlet的类,您可以通过创建类的实例来'调用' cmdlet,设置表示参数的任何属性并调用Cmdlet.Invoke<T>()
方法。下面是一个例子:
using System.Linq;
using System.Management.Automation;
namespace MyModule.Commands
{
[Cmdlet(VerbsLifecycle.Invoke, "AnotherCmdlet")]
public class InvokeAnotherCmdlet : Cmdlet
{
[Parameter(Mandatory = true)]
public string Username { get; set; }
protected override void ProcessRecord()
{
GetADUserCommand anotherCmdlet = new GetADUserCommand() {
// Pass CommandRuntime of calling cmdlet to the called cmdlet (note 1)
CommandRuntime = this.CommandRuntime,
// Set parameters
Username = this.Username
};
// Cmdlet code isn't ran until the resulting IEnumerable is enumerated (note 2)
anotherCmdlet.Invoke<object>().ToArray();
}
}
[Cmdlet(VerbsCommon.Get, "ADUser")]
public class GetADUserCommand : Cmdlet
{
[Parameter(Mandatory = true)]
public string Username { get; set; }
protected override void ProcessRecord()
{
WriteVerbose($"Getting AD User '{Username}'");
}
}
}
有几点需要注意:
您可能希望将调用Cmdlet对象的
Cmdlet.CommandRuntime
属性的值传递给被调用的Cmdlet对象。这将确保,如果你调用的cmdlet写入对象流(例如,通过调用WriteObject
),这些对象将使他们的方式到主机。另一种方法是让调用cmdlet枚举调用cmdlet上的Invoke<T>()
方法的结果。在调用cmdlet上调用
Invoke<T>()
方法不会像方法名称所暗示的那样立即调用cmdlet。相反,它返回一个IEnumerable<T>
对象。枚举对象将调用该命令。
您是正确的,正确的方法是创建PowerShell
的实例。强类型的方法是
PowerShell ps = PowerShell.Create();
ps.AddCommand(new CmdletInfo("Get-Cmdlet", typeof(GetCmdletCommand)));
虽然从c#调用PowerShell有其优点,但如果你想这样做,你应该重新考虑你的方法,因为你可能会遵循反模式。更明智的做法是让你的袖口"贴合"。通过将一个的输出与另一个的输入进行匹配,并在管道中调用它们。另一个问题给出了更好的答案,它描述了cmlet"单元"的设计选择。它们粘在一起