РАЗДЕЛ
    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





Содержание