Поделиться через


ForEach-Object

Выполняет операцию по каждому элементу в коллекции входных объектов.

Синтаксис

ForEach-Object
            [-InputObject <PSObject>]
            [-Begin <ScriptBlock>]
            [-Process] <ScriptBlock[]>
            [-End <ScriptBlock>]
            [-RemainingScripts <ScriptBlock[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]
ForEach-Object
            [-InputObject <PSObject>]
            [-MemberName] <String>
            [-ArgumentList <Object[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

Описание

Командлет ForEach-Object выполняет операцию по каждому элементу в коллекции входных объектов. Входные объекты можно передать в командлет или указать с помощью параметра InputObject.

Начиная с Windows PowerShell 3.0, существует два разных способа создания команды ForEach-Object.

  • блок скрипта. Чтобы указать операцию, можно использовать блок скрипта. В блоке скрипта используйте переменную $_ для представления текущего объекта. Блок скрипта — это значение параметра процесса. Блок скрипта может содержать любой скрипт PowerShell.

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

    Get-Process | ForEach-Object {$_.ProcessName}

    ForEach-Object поддерживает блоки begin, processи end, как описано в about_functions.

    Заметка

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

  • инструкции operation. Вы также можете написать инструкцию операции, которая гораздо больше похожа на естественный язык. Инструкцию операции можно использовать для указания значения свойства или вызова метода. Инструкции операций появились в Windows PowerShell 3.0.

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

    Get-Process | ForEach-Object ProcessName

Примеры

Пример 1. Разделение целых чисел в массиве

Этот пример принимает массив из трех целых чисел и делит каждый из них на 1024.

30000, 56798, 12432 | ForEach-Object -Process {$_/1024}

29.296875
55.466796875
12.140625

Пример 2. Получение длины всех файлов в каталоге

В этом примере файлы и каталоги в каталоге установки PowerShell $PSHOME.

Get-ChildItem $PSHOME |
  ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}

Если объект не является каталогом, блок скрипта получает имя файла, делит значение его свойства Length на 1024, а также добавляет пробел (""), чтобы отделить его от следующей записи. Командлет использует свойство PSISContainer, чтобы определить, является ли объект каталогом.

Пример 3. Работа с последними событиями системы

В этом примере записывается 1000 последних событий из журнала событий системы в текстовый файл. Текущее время отображается до и после обработки событий.

Get-EventLog -LogName System -Newest 1000 |
    ForEach-Object -Begin {Get-Date} -Process {
        Out-File -FilePath Events.txt -Append -InputObject $_.Message
    } -End {Get-Date}

Get-EventLog возвращает 1000 последних событий из журнала событий системы и передает их командлету ForEach-Object. Параметр Begin отображает текущую дату и время. Затем параметр процесса использует командлет Out-File для создания текстового файла с именем events.txt и сохраняет свойство сообщения каждого события в этом файле. Наконец, параметр end используется для отображения даты и времени после завершения обработки.

Пример 4. Изменение значения раздела реестра

В этом примере изменяется значение записи реестра RemotePath во всех вложенных разделах в разделе HKCU:\Network в верхний регистр текста.

Get-ItemProperty -Path HKCU:\Network\* |
  ForEach-Object {
    Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
  }

Этот формат можно использовать для изменения формы или содержимого значения записи реестра.

Каждый подраздел в ключе сети представляет сопоставленный сетевой диск, который повторно подключается при входе. Запись RemotePath содержит UNC-путь подключенного диска. Например, если вы сопоставляете диск E: с \\Server\Share, то в HKCU:\Network создается подключ E HKCU:\Network со значением реестра remotePath RemotePath значением \\Server\Share.

Команда использует командлет Get-ItemProperty для получения всех подразделов ключа сети и командлета Set-ItemProperty для изменения значения записи реестра RemotePath в каждом разделе. В команде Set-ItemProperty путь — это значение свойства PSPath раздела реестра. Это свойство объекта Microsoft .NET Framework, представляющего раздел реестра, а не запись реестра. Команда использует метод ToUpper() значения RemotePath, который является строковым REG_SZ.

Так как Set-ItemProperty изменяет свойство каждого ключа, для доступа к свойству требуется командлет ForEach-Object.

Пример 5. Использование автоматической переменной $null

В этом примере показан эффект подключения $null автоматической переменной к командлету ForEach-Object.

1, 2, $null, 4 | ForEach-Object {"Hello"}

Hello
Hello
Hello
Hello

Так как PowerShell обрабатывает $null как явный заполнитель, командлет ForEach-Object создает значение для $null, как и для других объектов, которые передаются в него.

Пример 6. Получение значений свойств

В этом примере возвращается значение свойства Path всех установленных модулей PowerShell с помощью параметра MemberName командлета ForEach-Object.

Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path

Вторая команда эквивалентна первой. Он использует псевдоним Foreach командлета ForEach-Object и не указывает имя параметра MemberName, который является необязательным.

Командлет ForEach-Object полезен для получения значений свойств, так как он получает значение без изменения типа, в отличие от командлетов формата или командлета Select-Object, который изменяет тип значения свойства.

Пример 7. Разделение имен модулей на имена компонентов

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

"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object {$_.Split(".")}
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object -MemberName Split -ArgumentList "."
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    Foreach Split "."

Microsoft
PowerShell
Core
Microsoft
PowerShell
Host

Первая команда использует традиционный синтаксис, который включает блок скрипта и текущий оператор объекта $_. Он использует синтаксис точки для указания метода и круглых скобок для заключения аргумента разделителя.

Вторая команда использует параметр MemberName для указания метода split и параметра ArgumentList для идентификации точки (.) в качестве разделителя разбиения.

Третья команда использует псевдоним foreach командлета ForEach-Object и не указывает имена параметров MemberName и ArgumentList, которые являются необязательными.

Пример 8. Использование ForEach-Object с двумя блоками скриптов

В этом примере мы передаваем два блока скрипта позиционально. Все блоки скрипта привязываются к параметру процесса. Однако они рассматриваются как будто они были переданы в параметры Begin и Process.

1..2 | ForEach-Object { 'begin' } { 'process' }

begin
process
process

Пример 9. Использование ForEach-Object с более чем двумя блоками скриптов

В этом примере мы передаваем четыре блока скрипта позиционально. Все блоки скрипта привязываются к параметру процесса. Однако они обрабатываются так, как если бы они были переданы в параметры Begin, Processи End.

1..2 | ForEach-Object { 'begin' } { 'process A' }  { 'process B' }  { 'end' }

begin
process A
process B
process A
process B
end

Заметка

Первый блок скрипта всегда сопоставляется с блоком begin, последний блок сопоставляется с блоком end, а два средних блока сопоставляются с блоком process.

Пример 10. Запуск нескольких блоков скриптов для каждого элемента конвейера

Как показано в предыдущем примере, несколько блоков скриптов, передаваемых с помощью параметра процесса, сопоставляются с параметрами Begin и End. Чтобы избежать этого сопоставления, необходимо указать явные значения для параметров Begin и End.

1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null

one
two
three
one
two
three

Параметры

-ArgumentList

Задает массив аргументов для вызова метода. Дополнительные сведения о поведении ArgumentListсм. в about_Splatting.

Этот параметр появился в Windows PowerShell 3.0.

Тип:Object[]
Aliases:Args
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-Begin

Задает блок скрипта, который выполняется перед обработкой входных объектов этого командлета. Этот блок скрипта выполняется только один раз для всего конвейера. Дополнительные сведения о блоке begin см. в about_Functions.

Тип:ScriptBlock
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-Confirm

Запрашивает подтверждение перед запуском командлета.

Тип:SwitchParameter
Aliases:cf
Position:Named
Default value:False
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-End

Указывает блок скрипта, который выполняется после этого командлета, обрабатывает все входные объекты. Этот блок скрипта выполняется только один раз для всего конвейера. Дополнительные сведения о блоке end см. в about_Functions.

Тип:ScriptBlock
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-InputObject

Указывает входные объекты. ForEach-Object запускает блок скрипта или инструкцию операции для каждого входного объекта. Введите переменную, содержащую объекты, или введите команду или выражение, которое получает объекты.

При использовании параметра InputObject с ForEach-Objectвместо ForEach-Objectрезультаты команды piping InputObject рассматривается как один объект. Это верно, даже если значение является коллекцией, которая является результатом команды, например -InputObject (Get-Process). Так как InputObject не могут возвращать отдельные свойства из массива или коллекции объектов, рекомендуется использовать ForEach-Object для выполнения операций с коллекцией объектов для тех объектов, которые имеют определенные значения в определенных свойствах, используйте ForEach-Object в конвейере, как показано в примерах этого раздела.

Тип:PSObject
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:True
Принять подстановочные знаки:False

-MemberName

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

Подстановочные знаки разрешены, но работают только в том случае, если результирующая строка разрешает уникальное значение. Например, при запуске Get-Process | ForEach -MemberName *Nameшаблон подстановочного знака соответствует нескольким членам, что приводит к сбою команды.

Этот параметр появился в Windows PowerShell 3.0.

Тип:String
Position:0
Default value:None
Обязательно:True
Принять входные данные конвейера:False
Принять подстановочные знаки:True

-Process

Указывает операцию, выполняемую для каждого входного объекта. Этот блок скрипта выполняется для каждого объекта в конвейере. Дополнительные сведения о блоке process см. в about_Functions.

При предоставлении нескольких блоков скриптов параметру процесса первый блок скрипта всегда сопоставляется с блоком begin. Если существует только два блока скриптов, второй блок сопоставляется с блоком process. Если существует три или более блоков скриптов, первый блок скрипта всегда сопоставляется с блоком begin, последний блок сопоставляется с блоком end, а средние блоки сопоставляются с блоком process.

Тип:ScriptBlock[]
Position:0
Default value:None
Обязательно:True
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-RemainingScripts

Указывает все блоки скриптов, которые не принимаются параметром процесса.

Этот параметр появился в Windows PowerShell 3.0.

Тип:ScriptBlock[]
Position:Named
Default value:None
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

-WhatIf

Показывает, что произойдет, если командлет выполняется. Командлет не выполняется.

Тип:SwitchParameter
Aliases:wi
Position:Named
Default value:False
Обязательно:False
Принять входные данные конвейера:False
Принять подстановочные знаки:False

Входные данные

PSObject

Вы можете передать любой объект в этот командлет.

Выходные данные

PSObject

Этот командлет возвращает объекты, определяемые входными данными.

Примечания

Windows PowerShell включает следующие псевдонимы для ForEach-Object:

  • %
  • foreach

Командлет ForEach-Object работает так же, как оператор foreach , за исключением того, что невозможно передать входные данные в инструкцию Foreach. Дополнительные сведения об инструкции foreach см. в about_Foreach.

Начиная с PowerShell 4.0, были добавлены методы Where и ForEach для использования с коллекциями. Дополнительные сведения об этих новых методах см. здесь about_arrays