如何从二进制(C#)模块调用PowerShell Cmdlet?
我正在编写一个自定义二进制(C#)Cmdlet,我想在此Cmdlet中调用另一个PowerShell二进制Cmdlet(例如Get ADUser),并将结果返回到我的Cmdlet中。实现这一目标的最佳方式是什么? 注意:在自定义Cmdlet中创建另一个PowerShell实例(如上所述)似乎不是实现这一点的最有效方法如何从二进制(C#)模块调用PowerShell Cmdlet?,c#,powershell,C#,Powershell,我正在编写一个自定义二进制(C#)Cmdlet,我想在此Cmdlet中调用另一个PowerShell二进制Cmdlet(例如Get ADUser),并将结果返回到我的Cmdlet中。实现这一目标的最佳方式是什么? 注意:在自定义Cmdlet中创建另一个PowerShell实例(如上所述)似乎不是实现这一点的最有效方法 我看了看问题。但是,它没有回答我的问题。如果可以引用实现cmdlet的类,则可以通过创建该类的实例来“调用”cmdlet,设置表示参数的所有属性,并调用cmdlet.Invoke(
我看了看问题。但是,它没有回答我的问题。如果可以引用实现cmdlet的类,则可以通过创建该类的实例来“调用”cmdlet,设置表示参数的所有属性,并调用
cmdlet.Invoke()
方法。下面是一个例子:
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}'");
}
}
}
使用System.Linq;
使用系统、管理、自动化;
名称空间MyModule.Commands
{
[Cmdlet(VerbsLifecycle.Invoke,“另一个Cmdlet”)]
公共类InvokeAnotherCmdlet:Cmdlet
{
[参数(强制=真)]
公共字符串用户名{get;set;}
受保护的覆盖无效ProcessRecord()
{
GetADUserCommand anotherCmdlet=新的GetADUserCommand(){
//将调用cmdlet的CommandRuntime传递给被调用的cmdlet(注意1)
CommandRuntime=this.CommandRuntime,
//设置参数
Username=this.Username
};
//在枚举生成的IEnumerable之前,不会运行Cmdlet代码(注意2)
另一个cmdlet.Invoke().ToArray();
}
}
[Cmdlet(VerbsCommon.Get,“ADUser”)]
公共类GetADUserCommand:Cmdlet
{
[参数(强制=真)]
公共字符串用户名{get;set;}
受保护的覆盖无效ProcessRecord()
{
WriteVerbose($“获取广告用户{Username}'”);
}
}
}
有几件事需要注意:
Cmdlet.CommandRuntime
属性的值传递给被调用的Cmdlet对象。这将确保,如果被调用的cmdlet写入对象流(例如,通过调用WriteObject
),这些对象将到达主机。另一种方法是调用cmdlet枚举调用cmdlet的Invoke()
方法的结果Invoke()
方法不会像方法名称所示立即调用cmdlet。而是返回一个IEnumberable
对象。枚举对象将调用该命令仅当要调用的Cmdlet从Cmdlet对象继承时,建议的方法才有效。换句话说,不能新建从PsCmdlet继承的Cmdlet。由于PsCmdlet公开了更多功能(例如访问Ps会话的能力),Windows附带的大多数Cmdlet都继承自PsCmdlet。因此,建议的方法具有有限的适用性。我对一个解决方案感兴趣,该解决方案将使用从PsCmdlet继承的Cmdlet。
PsCmdlet
继承Cmdlet
,因此它应该适用于所有Cmdlet类。