Допустим, у вас есть два командлета: первый возвращает выходные данные, а второй использует этот вывод в качестве входного параметра.
public class Cmdlet1 : PSCmdlet
{
protected override void ProcessRecord()
{
List<string> result = ...
WriteObject(result, true);
}
}
public class Cmdlet2 : PSCmdlet
{
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true)]
public string Input { get; set; }
protected override void ProcessRecord()
{
// Do a long operation on Input.
}
}
Cmdlet2 будет вызываться несколько раз таким образом (один раз для каждого элемента в IEnumerable, который возвращает Cmdlet1), и вы можете красиво соединить их вместе: Cmdlet1 | Select-Object -First 10 | Cmdlet2 Только первые 10 элементов вывода Cmdlet1 отправляются на Cmdlet2.
Поскольку Cmdlet2 занимает некоторое время, было бы неплохо отобразить прогресс. В настоящее время мы не можем этого сделать, потому что мы получаем строки ввода только одну за другой. Давайте изменим вход Cmdlet2 на List
public class Cmdlet1 : PSCmdlet
{
protected override void ProcessRecord()
{
List<string> result = ...
WriteObject(result, true);
}
}
public class Cmdlet2 : PSCmdlet
{
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true)]
public List<string> Input { get; set; }
protected override void ProcessRecord()
{
// Do a long operation on Input.
}
}
Мы по-прежнему получаем входные строки одну за другой, потому что вызов WriteObject в Cmdlet1 имеет true в качестве второго параметра, что позволяет PowerShell перечислять результат отдельным объектам , Если мы изменим это на false, PowerShell не будет перечислять результат, и Cmdlet2 получит весь список строк в качестве входных данных, и мы сможем работать со всеми строками и отображать хороший индикатор выполнения.
public class Cmdlet1 : PSCmdlet
{
protected override void ProcessRecord()
{
List<string> result = ...
WriteObject(result, false);
}
}
public class Cmdlet2 : PSCmdlet
{
[Parameter(Position = 1, Mandatory = true, ValueFromPipeline = true)]
public List<string> Input { get; set; }
protected override void ProcessRecord()
{
// Do a long operation on Input, displaying a progress bar.
}
}
НО: сейчас мы не можем легко их больше трубить. Cmdlet1 | Select-Object -First 10 | Cmdlet2 теперь отправляет весь ввод в Cmdlet2! Select-Object не берет первые 10, потому что есть только 1 элемент, который является IEnumerable, и этот элемент полностью отправляется в Cmdlet2!
Как правильно обращаться с подобной ситуацией?