如何从二进制(C#)模块调用PowerShell Cmdlet?

Ale*_*exT 5 c# powershell

我正在编写一个自定义二进制文件(C#)Cmdlet,在这个CmdLet中我想调用另一个PowerShell二进制Cmdlet(例如Get-ADUser)并将结果带回我的Cmdlet.完成此任务的最佳方法是什么?注:似乎创建PowerShell中的另一个实例(如描述在这里)我的自定义Cmdlet的里面是没有做到这一点的最有效方法.

我看了这个问题.但是,它没有回答我的问题.

Dan*_*ens 2

如果您可以引用实现 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}'");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有几点需要注意:

  1. 您可能希望将Cmdlet.CommandRuntime调用 Cmdlet 对象的属性值传递给被调用的 Cmdlet 对象。这将确保,如果您调用的 cmdlet 写入对象流(例如通过调用WriteObject),这些对象将到达主机。另一种方法是让调用 cmdlet 枚举调用调用Invoke<T>()cmdlet 上的方法的结果。

  2. 调用Invoke<T>()调用 cmdlet 上的方法不会立即调用该 cmdlet,如方法名称所示。相反,它返回一个IEnumerable<T>对象。枚举该对象将调用该命令。