If you can reference the class that implements your cmdlet you can 'call' the cmdlet by creating an instance of the class, set any properties that represent parameters and call the Cmdlet.Invoke<T>()
method. Here's an example:
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}'");
}
}
}
A couple of things to note:
You may wish to pass the value of the Cmdlet.CommandRuntime
property of the calling Cmdlet object to the called Cmdlet object. This will ensure that, if your called cmdlet writes to object streams (e.g. by calling WriteObject
) those objects will make their way to the host. The alternative is for the calling cmdlet to enumerate the result of calling the Invoke<T>()
method on the calling cmdlet.
Calling the Invoke<T>()
method on the calling cmdlet doesn't immediately invoke the cmdlet as the method name might suggest. It instead returns a IEnumerable<T>
object. Enumerating the object will invoke the command.