РАЗДЕЛ
	about_pipelines

КРАТКОЕ ОПИСАНИЕ
	Объединение команд в конвейеры в Windows PowerShell 

ПОЛНОЕ ОПИСАНИЕ
	Конвейер - это последовательность команд, объединенных 
	операторами конвейера (|)(код ASCII: 124). Каждый оператор 
	конвейера передает результаты предшествующей команды последующей 
	команде.
	 
	С помощью конвейера можно передавать выходные объекты одной 
	команды на обработку другой команде как входные объекты. Выходные 
	объекты этой команды можно передать еще одной команде. Таким 
	образом получается мощная цепь (или конвейер) команд, состоящая 
	из последовательности простых команд. 

	Пример:  

		Command-1 | Command-2 | Command-3 

	В этом примере объекты, выдаваемые командой Command-1, передаются 
	команде Command-2. Команда Command-2 обрабатывает их и передает 
	команде Command-3. Команда Command-3 обрабатывает их и передает 
	их далее по конвейеру. Поскольку в конвейере нет следующей 
	команды, результаты отображаются в консоли.

	Команды в конвейере обрабатываются слева направо в том порядке, в 
	котором они указаны. Обработка выполняется как одна операция, и 
	выходные данные отображаются сразу после их создания.

	Приведем простой пример. Следующая команда получает процесс 
	Notepad, а затем останавливает его.

		 get-process notepad | stop-process

	Первая команда с помощью командлета Get-Process получает объект, 
	представляющий идентификатор процесса Notepad. Для передачи 
	объекта процесса командлету Stop-Process, останавливающему 
	процесс Notepad, используется оператор конвейера (|). Обратите 
	внимание, что в команде Stop-Process не указан параметр, задающий 
	имя или идентификатор процесса, поскольку процесс передается по 
	конвейеру.

	Приведем практический пример. Следующий конвейер команд получает 
	текстовые файлы из текущего каталога, выбирает из них только 
	файлы с размером более 10000 байт, упорядочивает их по размеру и 
	отображает имя и размер каждого файла в таблице.

		Get-ChildItem -path *.txt | Where-Object {$_.length -gt 10000} | 
		Sort-Object -property Length | Format-Table -property name, length 

	Этот конвейер состоит из четырех команд в указанном порядке. Эта 
	команда пишется слева направо, но на следующей схеме этот процесс 
	представлен вертикально.

	 Get-ChildItem -path *.txt

				|
				|  (объекты FileInfo)
				|  (  .txt		 )
				|
				V				 

	 Where-Object {$_.length -gt 10000}

				|
				|  (объекты FileInfo)
				|  (  .txt		 )
				|  ( Length > 10000 )
				|
				V

	 Sort-Object -property Length

				|
				|  (объекты FileInfo)
				|  (  .txt		)
				|  ( Length > 10000  )
				|  ( упоряд. по длине )
				|
				V

	 Format-Table -property name, length

				|  
				|  (объекты FileInfo   )
				|  (  .txt			 )
				|  ( Length > 10000   )
				|  ( упоряд. по длине  )
				|  (в формате таблицы )
				|
				V
		Name					 Length
		----					 ------
		tmp1.txt					82920
		tmp2.txt				 114000
		tmp3.txt				 114000


ИСПОЛЬЗОВАНИЕ КОНВЕЙЕРОВ

	Командлеты Windows PowerShell предназначены для использования в 
	конвейерах. Например, результаты командлета Get обычно можно 
	передать командлету действия (например, Set, Start, Stop или 
	Rename) с таким же существительным.

	Например, можно передать по конвейеру любую службу из командлета 
	Get-Service в командлет Start-Service или Stop-Service (впрочем, 
	перезапускать отключенные службы таким образом нельзя).

	Следующий конвейер команд запускает на компьютере службу WMI.

		get-service wmi | start-service

	Командлеты, получающие и задающие объекты поставщиков Windows 
	PowerShell, например командлеты Item и ItemProperty, также 
	предназначены для использования в конвейерах. 

	Например, можно передать по конвейеру результаты команды Get-Item 
	или Get-ChildItem от поставщика реестра Windows PowerShell 
	командлету New-ItemProperty. Следующая команда добавляет в реестр 
	новую запись "NoOfEmployees" с величиной 8124 (в разделе реестра 
	MyCompany).

	 get-item -path HKLM:\Software\MyCompany | new-Itemproperty 
	 -name NoOfEmployees -value 8124

	Многие служебные командлеты, такие как Get-Member, Where-Object, 
	Sort-Object, Group-Object и Measure-Object, используются 
	практически исключительно в командлетах. Этим командлетам можно 
	передавать по конвейеру любые объекты.

	Например, все выполняющиеся на компьютере процессы можно передать 
	команде Sort-Object по конвейеру и упорядочить их по количеству 
	дескрипторов в процессе.

		get-process | sort-object -property handles

	Кроме того, любые объекты можно передать по конвейеру командлетам 
	форматирования, таким как Format-List и Format-Table, командлетам 
	экспорта, таким как Export-Clixml и Export-CSV, и командлетам 
	вывода данных, таким как Out-Printer.

	Например, процесс Winlogon можно передать по конвейеру командлету 
	Format-List, чтобы отобразить все свойства процесса в виде списка.

		get-process winlogon | format-list -property *

	Комбинирование простых команд с помощью конвейера избавляет от 
	необходимости вводить лишние команды и делает скрипты более 
	эффективными, и чтобы овладеть этим навыком, достаточно лишь 
	немного практики.


ПРИНЦИП ДЕЙСТВИЯ КОНВЕЙЕРА

	 При передаче объектов по конвейеру (т. е. передаче выходных 
	 объектов одной команды в другую команду) Windows PowerShell 
	 пытается сопоставить переданные объекты с одним из параметров 
	 принимающего командлета. 

	 Для этого компонент "привязки параметров" Windows PowerShell, 
	 сопоставляющий объекты ввода с параметрами командлета, пытается 
	 найти параметр, соответствующий следующим критериям:

	 -- Параметр должен принимать входные данные с конвейера (такая 
		возможность есть не у всех параметров).
	 -- Параметр должен принимать тип переданного объекта (или тип, в 
		который его можно преобразовать).
	 -- Параметр не должен быть уже использован в команде.

	 Например, командлет Start-Service имеет множество параметров, но 
	 только два из них принимают входные данные с конвейера: Name и 
	 InputObject. Параметр Name принимает строки, а параметр 
	 InputObject принимает объекты служб. Поэтому командлету 
	 Start-Service можно передавать по конвейеру строки и объекты 
	 служб (а также объекты, свойства которых можно преобразовать в 
	 строки и объекты служб).

	 Если компоненту Windows PowerShell для привязки параметров не 
	 удается связать переданные по конвейеру объекты с параметром 
	 принимающего объекта, команда не выполняется, и Windows 
	 PowerShell запрашивает ввод отсутствующих значений параметров.

	 Компоненту привязки параметров нельзя принудительно предписать 
	 связывать переданные по конвейеру объекты с определенным 
	 параметром. Нельзя даже предложить такой параметр. Вместо этого 
	 логика компонента управляет обработкой конвейера с максимально 
	 возможной эффективностью.


ПООЧЕРЕДНАЯ ОБРАБОТКА

	 Передача объектов команде по конвейеру во многом подобна их 
	 передаче с помощью параметра команды.

	 Например, передача по конвейеру объектов, представляющих службы 
	 на компьютере, команде Format-Table, например следующим образом:

				get-service | format-table -property name, dependentservices

	 во многом подобна сохранению объектов служб в переменной и их 
	 передаче с помощью командлета Format-Table с параметром InputObject:

				$services = get-service
				format-table -inputobject $services -property name, 
				dependentservices

	 или внедрению команды в значение параметра:

				format-table -inputobject (get-service wmi) 
				-property name, dependentservices

	 Впрочем, имеется важное различие. Если несколько объектов 
	 передаются команде по конвейеру, Windows PowerShell отправляет 
	 объекты команде поочередно. При использовании параметра команды 
	 объекты передаются в виде единого объекта массива.

	 Это различие, на первый взгляд кажущееся чисто техническим, 
	 имеет некоторые интересные (а иногда полезные) следствия.

	 Например, если передать по конвейеру несколько объектов 
	 процессов от командлета Get-Process командлету Get-Member, 
	 Windows PowerShell поочередно отправляет каждый объект 
	 командлету Get-Member. Get-Member отображает классы (типы) 
	 .NET объектов процессов, их свойства и методы.
	 (Командлет Get-Member исключает дубликаты, поэтому если все 
	 объекты принадлежат к одинаковому типу, отображается только один 
	 тип объекта.)

	 В этом случае командлет Get-Member отображает только свойства и 
	 методы каждого объекта процесса, т. е. объекта System.Diagnostics
	 .Process.

				 get-process | get-member

					TypeName: System.Diagnostics.Process


				 Name						 MemberType	 Definition
				 ----						 ----------	 ----------
				 Handles						AliasProperty  Handles = Handlecount
				 Name						 AliasProperty  Name = ProcessName
				 NPM							AliasProperty  NPM = NonpagedSystemMemorySize
				 ...

	Впрочем, если используется параметр InputObject командлета 
	Get-Member, командлет Get-Member получает массив объектов 
	System.Diagnostics.Process как единый блок и отображает свойства 
	массива объектов. (Обратите внимание на символ массива ([]) после 
	имени типа System.Object.)


				get-member -inputobject (get-process)


				TypeName: System.Object[]

				 Name			 MemberType	Definition
				----			 ----------	----------
				Count			AliasProperty Count = Length
				Address			Method		System.Object& Address(Int32 )
				Clone			Method		System.Object Clone()
				...

	 Этот результат может не соответствовать вашим ожиданиям, но 
	 изучив его природу, его можно использовать. Например, массив 
	 объектов процессов имеет свойство Count, с помощью которого 
	 можно подсчитать количество процессов на компьютере.

				(get-process).count
			
	 Это важное различие, и при передаче объектов командлету по 
	 конвейеру необходимо учитывать, что они доставляются поочередно. 


ПРИЕМ ВХОДНЫХ ДАННЫХ С КОНВЕЙЕРА

	Чтобы командлет принимал входные данные с конвейера, у него 
	должен быть параметр, принимающий входные данные с конвейера. С 
	помощью командлета Get-Help с параметром Full или Parameter можно 
	определить, какой параметр командлета принимает входные данные с 
	конвейера (и есть ли вообще такой параметр).

	По умолчанию командлет Get-Help отображает элемент "Принимает 
	входные данные с конвейера" в таблице атрибутов параметра. Эта 
	таблица выводится только при использовании командлета Get-Help с 
	параметром Full или Parameter.

	Например, чтобы определить, какой из параметров командлета 
	Start-Service принимает входные данные с конвейера, введите 
	следующую команду:
	 
		get-help start-service -full

		get-help start-service -parameter *

	Например, в справке по командлету Start-Service отображается, что 
	параметры Name и InputObject принимают входные данные с конвейера 
	(значение "true"). Для всех остальных параметров в строке 
	"Принимать входные данные с конвейера?" отображается "false".

		-name <string[]>
		 Задает имена служб, которые необходимо запустить.
		 Имя параметра указывать необязательно. Можно использовать 
		 "-Name" или его псевдоним ("-ServiceName") либо опустить 
		 имя параметра.

		 Требуется?							true
		 Позиция?							1
		 Значение по умолчанию
	-->  Принимать входные данные с конвейера? true (ByValue, ByPropertyName)
		 Принимать подстановочные знаки?	 true

		-inputObject <ServiceController[]>
		 Задает объекты ServiceController, представляющие 
		 запускаемые службы. Введите переменную, содержащую 
		 объекты, либо получающую их команду или выражение.

		 Требуется?							false
		 Позиция?							именованный
		 Значение по умолчанию
	-->  Принимать входные данные с конвейера? true (ByValue)
		 Принимать подстановочные знаки?	 false

	 Это значит, что можно передавать объекты (PsObjects) командлету 
	 Where-Object по конвейеру и Windows PowerShell будет связывать 
	 эти объекты с параметром InputObject.


МЕТОДЫ ПРИЕМА ВХОДНЫХ ДАННЫХ С КОНВЕЙЕРА

	 Параметры командлетов могут принимать входные данные с конвейера 
	 двумя разными способами.

	 -- ByValue (По значению): параметры, принимающие входные данные 
		по значению, могут принимать с конвейера объекты, принадлежащие 
		к тем же типам .NET, что и значения этих параметров, либо объекты, 
		которые можно преобразовать в эти типы. 

		Например, параметр Name командлета Start-Service принимает 
		входные данные с конвейера по значению. Он принимает 
		строковые объекты и объекты, которые можно преобразовать в строки.

	 -- ByPropertyName (По имени свойства): параметры, принимающие 
		входные данные по имени свойства, могут принимать с конвейера 
		только объекты, имеющие свойство с таким же именем, как и имя 
		самого параметра.

		Например, параметр Name командлета Start-Service может 
		принимать только объекты, имеющие свойство Name. 

		(Чтобы вывести свойства объекта, передайте его командлету 
		Get-Member по конвейеру.)

	 Некоторые параметры могут принимать объекты по значению или по 
	 имени свойства. Эти параметры разработаны с учетом удобства 
	 приема входных данных с конвейера.


ПРОВЕРКА ОШИБОК КОНВЕЙЕРА

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

	 Например, следующая команда пытается переместить запись из 
	 одного раздела реестра в другой. Для этого с помощью командлета 
	 Get-Item получается конечный путь, который затем передается 
	 командлету Move-ItemProperty по конвейеру.

	 А именно, эта команда получает конечный путь с помощью 
	 командлета Get-Item. Результат передается командлету 
	 Move-ItemProperty с помощью оператора конвейера (|). Команда 
	 Move-ItemProperty указывает текущий путь и имя перемещаемой 
	 записи реестра. 

		get-item -path hklm:\software\mycompany\sales | 
		move-itemproperty -path hklm:\software\mycompany\design 
		-name product

	 Выполнить команду не удается, и Windows PowerShell выводит 
	 следующее сообщение об ошибке:  

		 Move-ItemProperty : Не удается привязать объект ввода к 
		 любым параметрам команды, так как команда не принимает 
		 входные данные конвейера, либо входные данные и их свойства 
		 не совпадают с любыми из параметров, принимающих входные 
		 данные конвейера.
		 В строке:1 знак:23
		 + $a | move-itemproperty <<<< -path hklm:\software\mycompany\
		 design -name product

	Чтобы проверить эту ошибку, воспользуйтесь командлетом 
	Trace-Command для трассировки компонента привязки параметров 
	Windows PowerShell. Следующая команда выполняет трассировку 
	компонента привязки параметров во время обработки команды. 
	Параметр -pshost используется для вывода результатов в консоль, а 
	команда -filepath - для отправки результатов в файл debug.txt для 
	дальнейшего использования.

		 trace-command -name parameterbinding -expression {get-item -path 
		 hklm:\software\mycompany\sales | move-itemproperty -path 
		 hklm:\software\mycompany\design -name product} -pshost -filepath debug.txt

	Результаты трассировки имеют существенный размер, но они 
	показывают значения, привязываемые к командлету Get-Item, а затем 
	именованные значения, привязываемые к командлету Move-ItemProperty. 

	 ... 
		BIND NAMED cmd line args [Move-ItemProperty] BIND arg 
		[hklm:\software\mycompany\design] to parameter [Path] 
	 ...
			BIND arg [product] to parameter [Name] 
	 ....
		BIND POSITIONAL cmd line args [Move-ItemProperty] 
	 ...


	И наконец, отображаются сведения о том, что попытка привязать 
	путь к параметру Destination командлета Move-ItemProperty не удалась.
		...
		BIND PIPELINE object to parameters: [Move-ItemProperty]
			PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
			RESTORING pipeline parameter's original values
			Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
			Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
		... 

	 Чтобы проверить ошибку, с помощью командлета Get-Help просмотрите 
	 атрибуты параметра Destination. Следующая команда получает подробные 
	 сведения о параметре Destination.

		get-help move-itemproperty -parameter destination

	 Результаты показывают, что параметр Destination принимает 
	 входные данные с конвейера только по имени свойства.
	 Т. е. у передаваемого по конвейеру объекта должно быть свойство 
	 Destination.

		-destination <string>
			Определяет путь к целевому местоположению.

			Требуется?							 true
			Позиция?							 2
			Значение по умолчанию
			Принимать входные данные с конвейера?  true (ByPropertyName) 
			Принимать подстановочные знаки?		true  

	 Чтобы просмотреть свойства и методы объекта, переданному по 
	 конвейеру командлету Move-ItemProperty, передайте его по 
	 конвейеру командлету Get-Member. В следующей команде результаты 
	 выполнения первой части команды передаются командлету Get-Member 
	 по конвейеру.

		get-item -path hklm:\software\mycompany\sales | get-member 

	 Выходные данные показывают, что элемент является разделом реестра 
	 Microsoft.Win32.RegistryKey, не имеющим свойства Destination. Это 
	 объясняет причины сбоя команды.

	 Чтобы исправить команду, необходимо указать конечный путь в 
	 командлете Move-ItemProperty. Этот путь можно получить с помощью 
	 командлета Get-ItemProperty, но имя и назначение необходимо 
	 указать в той части команды, где находится командлет 
	 Move-ItemProperty.
	
		 get-item -path hklm:\software\mycompany\design | 
			 move-itemproperty -dest hklm:\software\mycompany\design -name product  

	 Чтобы убедиться, что команда сработала, воспользуйтесь командой 
	 Get-ItemProperty.

		get-itemproperty hklm:\software\mycompany\sales

	 Результаты показывают, что запись реестра Product перемещена в 
	 раздел реестра Sales.

		PSPath	 : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\mycompany\sales
		PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\mycompany
		PSChildName  : sales
		PSDrive	: HKLM
		PSProvider   : Microsoft.PowerShell.Core\Registry
		Product	: 18

CМ. ТАКЖЕ

	about_objects

	about_parameters

	about_command_syntax

	about_foreach