Командлет передает список параметров сразу через конвейер, а не отдельные элементы списка

Я создаю Powershell System.Management.AutomationCmdlet.Cmdlet для передачи списка строк через конвейер в командлет следующим образом:

  [Cmdlet(VerbsCommon.Add, "Signature")]
  public class AddSignature : Cmdlet
...
    [Parameter(Position = 0, ValueFromPipeline = true)]
    public List<string> Items { get; set; }
...

Теперь в перегруженном методе "ProcessRecord" я получаю только один элемент за раз Items.Count == 1 3 раза (вместо получения полного списка, сразу прошедшего через конвейер).

'item1','item2','item3' | Add-Signature

Есть ли возможность передать сразу весь список элементов (возвращаемых Get-ChildItem)? Я получаю только один предмет за раз.

В основном я хочу иметь такое же поведение при использовании конвейера, как если бы я использовал такую ​​команду (Items.Count == 3)

Add-Signature -Items "item1","item2","item3"

Любая идея?


person Pinte Dani    schedule 04.02.2015    source источник


Ответы (1)


На самом деле мне было интересно то же самое, хотя я сосредоточился на том, чтобы использовать это непосредственно из Powershell, а не на C #. Я подумал, что будет какой-то атрибут или официальный способ сделать это.

Я видел, что используются такие термины, как остановка, например «остановка конвейера», а иногда и буфер. Я могу придумать два официальных командлета, которые делают это: Sort-Object останавливается, потому что ему нужны все объекты, прежде чем он сможет их отсортировать. Format-Table -Autosize останавливается, потому что ему нужны все объекты, прежде чем он сможет выяснить, как определить размер столбцов.

Я придумал обходной путь в Powershell:

function Stall-Pipeline {
[CmdletBinding()]
param(
    [Parameter(
        ValueFromPipeline
    )]
    [String]
    $Msg
)

    Begin {
        Write-Verbose "Begin"
        $all = @()
    }

    Process {
        Write-Verbose "Process"
        $all += $Msg
    }

    End {
        Write-Verbose "End"
        foreach($item in $all) {
            # processing 
            $item # processed item
        }
    }
}

По сути, я использую блок begin для инициализации переменной, в которой будут храниться все результаты. Блок process добавляет к этой переменной, затем блок end выполняет всю фактическую обработку и отправляет элементы в конвейер.

Вы можете вызвать это с помощью -Verbose, чтобы увидеть, когда вызывается каждый блок.

Если есть способ лучше, более официальный или поддерживаемый, мне очень интересно узнать, что это такое.

person briantist    schedule 04.02.2015
comment
Я также научился выполнять фактическую работу в методе End, хотя это не совсем укладывается в смысл этого метода. Возможно, так и будет, если я не найду лучшего решения. - person Pinte Dani; 05.02.2015