PowerShell
Работа с конвейером PowerShell
Поиск…
Вступление
PowerShell представляет модель конвейеризации объекта, которая позволяет отправлять целые объекты вниз по конвейеру до потребления команд или (по крайней мере) вывода. В отличие от классической конвейерной обработки на основе строк, информация в конвейерных объектах не обязательно должна находиться на определенных позициях. Командлеты могут объявлять для взаимодействия с объектами из конвейера в качестве входных данных, а возвращаемые значения автоматически отправляются в конвейер.
Синтаксис
- BEGIN Первый блок. Выполняется один раз в начале. Ввод конвейера здесь равен $ null, поскольку он не был установлен.
- ПРОЦЕСС Второй блок. Выполняется для каждого элемента конвейера. Параметр конвейера равен текущему обрабатываемому элементу.
- END Последний блок. Выполняется один раз в конце. Параметр конвейера равен последнему элементу ввода, поскольку он не был изменен с момента его установки.
замечания
В большинстве случаев ввод конвейера будет представлять собой массив объектов. Хотя поведение блока PROCESS{}
может показаться похожим на блок foreach{}
, пропуская элемент в массиве, требуется другой процесс.
Если, как и в foreach{}
, вы использовали continue
внутри блока PROCESS{}
, он сломал бы конвейер, пропустив все следующие утверждения, включая блок END{}
. Вместо этого используйте return
- он только завершит блок PROCESS{}
для текущего элемента и переместится к следующему.
В некоторых случаях возникает необходимость выводить результат функций с различным кодированием. Кодирование вывода CmdLets управляется переменной $OutputEncoding
. Когда вывод предназначен для ввода в конвейер для родных приложений, может быть хорошей идеей исправить кодировку в соответствии с целевым значением $OutputEncoding = [Console]::OutputEncoding
Дополнительные ссылки:
Статья в блоге с более $OutputEncoding
описанием $OutputEncoding
https://blogs.msdn.microsoft.com/powershell/2006/12/11/outputencoding-to-the-rescue/
Запись функций с расширенным жизненным циклом
В этом примере показано, как функция может принимать конвейерные входные данные и эффективно выполнять итерацию.
Обратите внимание, что begin
и end
структуры функции являются необязательными при конвейерной обработке, но этот process
требуется при использовании ValueFromPipeline
или ValueFromPipelineByPropertyName
.
function Write-FromPipeline{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
$myInput
)
begin {
Write-Verbose -Message "Beginning Write-FromPipeline"
}
process {
Write-Output -InputObject $myInput
}
end {
Write-Verbose -Message "Ending Write-FromPipeline"
}
}
$foo = 'hello','world',1,2,3
$foo | Write-FromPipeline -Verbose
Выход:
VERBOSE: Beginning Write-FromPipeline
hello
world
1
2
3
VERBOSE: Ending Write-FromPipeline
Базовая поддержка трубопроводов в функциях
Это пример функции с простейшей возможной поддержкой конвейерной обработки.
Любая функция с поддержкой конвейера должна иметь по крайней мере один параметр с параметром ParameterAttribute ValueFromPipeline
или ValueFromPipelineByPropertyName
, как показано ниже.
function Write-FromPipeline {
param(
[Parameter(ValueFromPipeline)] # This sets the ParameterAttribute
[String]$Input
)
Write-Host $Input
}
$foo = 'Hello World!'
$foo | Write-FromPipeline
Выход:
Hello World!
Примечание. В PowerShell 3.0 и выше поддерживаются значения по умолчанию для ParameterAttributes. В более ранних версиях вы должны указать ValueFromPipeline=$true
.
Рабочая концепция трубопровода
В серии конвейеров каждая функция выполняется параллельно другим, подобно параллельным потокам. Первый обработанный объект передается на следующий конвейер, и следующая обработка немедленно выполняется в другом потоке. Это объясняет высокую скорость усиления по сравнению со стандартным ForEach
@( bigFile_1, bigFile_2, ..., bigFile_n) | Copy-File | Encrypt-File | Get-Md5
- step - скопировать первый файл (в Thread
Copy-file
) - step - копировать второй файл (в Thread
Copy-file
) и одновременно шифровать первый (вEncrypt-File
) - step - копировать третий файл (в
Copy-file
Thread) и одновременно шифровать второй файл (вEncrypt-File
) и одновременноget-Md5
первого (вGet-Md5
)