Когда вы впервые начинаете писать сценарии PowerShell, вы непременно дойдете до момента, когда вам потребуется обработать несколько элементов из коллекции. Именно тогда вам придется изучить циклы foreach в PowerShell и понять, в чем заключается их суть.
Практически все языки программирования имеют конструкцию, называемую циклами; PowerShell здесь не исключение. Один из самых популярных типов циклов в PowerShell – это цикл foreach. В своей основе цикл foreach считывает всю коллекцию элементов и для каждого элемента выполняет определенный код.
Одним из самых запутанных аспектов цикла foreach в PowerShell для начинающих является множество вариантов его использования. Есть не только один способ обработки каждого элемента в коллекции; их три!
В этой статье вы узнаете, как работает каждый тип цикла foreach и когда стоит использовать один вместо другого. К моменту завершения этой статьи у вас будет хорошее понимание каждого типа цикла foreach.
Основы цикла PowerShell ForEach
Один из самых распространенных типов циклов, которые вы будете использовать в PowerShell, – это цикл типа foreach
. Цикл foreach
считывает набор объектов (итерирует) и завершается, когда завершается работа с последним из них. Коллекция объектов, которую считывает цикл, обычно представлена массивом или хэш-таблицей.
ПРИМЕЧАНИЕ: Термин “итерация” – это программный термин, который относится к каждому выполнению цикла. Каждый раз, когда цикл завершает цикл, это называется итерацией. Действие запуска цикла по набору объектов обычно называется итерацией по набору.
Возможно, вам нужно создать текстовый файл в разных папках, распределенных по файловой системе. Допустим, пути к папкам таковы: C:\Folder
, C:\Program Files\Folder2
и C:\Folder3
. Без использования цикла нам пришлось бы ссылаться на команду Add-Content
три раза.
Единственное отличие между каждой из этих командных ссылок – это значение Path
. Значение для Path
– единственное значение, которое меняется среди каждого из них.
Вы дублируете много кода. Вы тратите время на набор и открываете себя проблемам в будущем. Вместо этого вы должны создать “набор”, который включает все элементы, которые изменяются. В данном примере мы будем использовать массив.
Теперь у вас есть каждый из этих путей, сохраненных в одном “наборе” или массиве. Теперь вы готовы использовать цикл, чтобы перебрать каждый из этих элементов. Прежде чем сделать это, хорошее время упомянуть тему, которая обычно сбивает с толку тех, кто только начинает использовать PowerShell. В отличие от других типов циклов, циклы foreach
в PowerShell не являются одним и тем же.
Технически существует три типа циклов foreach
в PowerShell. Хотя каждый из них похож в использовании, важно понимать разницу.
Цикл foreach
Первый тип цикла foreach
– это оператор. foreach
– внутренний ключевой элемент PowerShell, который не является cmdlet или функцией. Оператор foreach
всегда используется в форме: foreach ($i in $array)
.
Используя приведенный выше пример, переменная $i
представляет собой итератор или значение каждого элемента в $path
, поскольку он проходит через каждый элемент в массиве.
Обратите внимание, что переменная итератора не обязательно должна быть
$i
. Имя переменной может быть любым.
В приведенном ниже примере вы можете выполнить ту же задачу, что и повторение ссылки Add-Content
, сделав следующее:
Выражение foreach
известно как более быстрый альтернативный способ, чем использование ForEach-Object
командлета.
The ForEach-Object CmdLet
Если foreach
– это выражение и его можно использовать только одним способом, то ForEach-Object
– это командлет с параметрами, который можно использовать многими различными способами. Как и выражение foreach
, командлет ForEach-Object
может выполнять итерацию по набору объектов. Но на этот раз он передает этот набор объектов и действие, которое нужно выполнить с каждым объектом, в качестве параметра, как показано ниже.
Примечание: Чтобы сделать вещи запутанными, у командлета
ForEach-Object
есть псевдоним с именемforeach
. В зависимости от того, как вызывается термин “foreach”, запускается выражениеforeach
или выполняетсяForEach-Object
.A good way to differentiate these situations is to notice if the term “foreach” is followed by
($someVariable in $someSet)
. Otherwise, in any other context, the code author is probably using the alias forForEach-Object
.
Метод foreach()
Один из самых новых циклов foreach
был представлен в PowerShell v4 и называется методом foreach()
. Этот метод существует на массиве или объекте коллекции. Метод foreach()
имеет стандартный параметр блока сценария, который содержит действия для выполнения на каждой итерации, как и другие.
Самое значительное отличие метода foreach()
заключается в том, как он работает внутри.
Использование метода
foreach()
значительно быстрее и заметно на больших наборах данных. Рекомендуется использовать этот метод, если это возможно.
Мини-проект: Перебор набора имен серверов
Одно из самых распространенных применений цикла в PowerShell – чтение набора серверов из какого-либо источника и выполнение некоторого действия с каждым из них. Для нашего первого мини-проекта давайте создадим код, который позволит нам считывать имена серверов (по одному на строке) из текстового файла и выполнять пинг для каждого сервера, чтобы определить, в сети он или нет.

Для этого рабочего процесса, какой тип цикла, на ваш взгляд, будет работать лучше?
Обратите внимание, что я упомянул слово “набор”, как “набор серверов”. Это уже подсказка. У вас уже есть определенное количество имен серверов, и вы хотели бы выполнить некоторое действие с каждым из них. Это звучит как отличный случай для применения самого распространенного цикла PowerShell – цикла foreach
.
Первая задача – создать набор имен серверов в коде. Самый распространенный способ сделать это – создать массив. К счастью для нас, Get-Content
, по умолчанию, возвращает массив, в котором каждый элемент представлен одной строкой в текстовом файле.
Сначала создайте массив всех моих имен серверов и назовите его $servers
.
Теперь, когда у вас создан массив, вам нужно подтвердить, онлайн ли каждый сервер или нет. Отличным командлетом для проверки подключения к серверу является Test-Connection
. Этот командлет выполняет несколько тестов подключения к компьютеру, чтобы определить, онлайн ли он или нет.
Выполнив Test-Connection
внутри цикла foreach
, чтобы прочитать каждую строку файла, вы можете передать каждое имя сервера, представленное переменной $server
, в Test-Connection
. Вот как PowerShell перебирает текстовый файл. Пример работы приведен ниже.
Когда выполнится цикл foreach
, он будет выглядеть примерно так:

Вы успешно проверили подключение к текстовому файлу, полному имен серверов! На этом этапе вы можете добавлять или удалять имена серверов в текстовом файле по своему усмотрению, не изменяя код.
Вы успешно практиковали то, что мы проповедуем, метод DRY.
Примеры использования цикла ForEach в PowerShell
Давайте рассмотрим несколько примеров того, как использовать цикл ForEach. Они основаны на реальных сценариях использования, демонстрируя концепцию, которую вы можете изменить под свои требования.
Пример 1: Создание файла в каждой подпапке в каталоге с использованием оператора ForEach
Этот пример демонстрирует общее использование цикла PowerShell для обработки каждой папки в каталоге.
Предположим, что в папке C:\ARCHIVE_VOLUMES
есть десять подпапок. Каждая подпапка представляет собой архивный объем, который ежедневно резервируется. После завершения каждого резервного копирования создается файл с именем BackupState.txt
внутри каждой папки, содержащий дату его создания.
Приведен пример того, как это может выглядеть.

Сценарий ниже выполняет три действия:
- получает список всех подпапок внутри
C:\ARCHIVE_VOLUMES
- проходит по каждой папке
- создает текстовый файл с именем
BackupState.txt
, содержащий текущую дату и время его значения
В этом примере используется оператор foreach
.
С использованием cmdlet Get-ChildItem
вы можете подтвердить, что файлы были созданы или обновлены в каждой из подпапок.
Снимок экрана ниже показывает вывод скрипта, отображающего все файлы BackupState.txt
, найденные в каждом подкаталоге.

Пример 2: Чтение содержимого каждого текстового файла в подкаталогах
Далее, чтобы продемонстрировать использование цикла PowerShell для каждого файла в каталоге, ниже приведенный скрипт будет читать каждый файл BackupState.txt
, созданный в Примере 1.
- Рекурсивно найти все файлы
BackupState.txt
внутри каждого подкаталога. - Используя оператор
foreach
, читайте каждый текстовый файл, чтобы получить значение “последнего времени резервного копирования”. - Отобразите результат на экране.
После выполнения скрипта в вашей сессии PowerShell вы должны увидеть аналогичный вывод, как на снимке экрана ниже. Это показывает, что PowerShell проходит по файлам, читает содержимое и отображает результат.

Пример 3: Получение служб и их запуск с использованием командлета ForEach-Object
Системным администраторам часто требуется получать состояние служб и запускать либо ручной, либо автоматический рабочий процесс для устранения неполадок в службах. Давайте рассмотрим примерный скрипт с использованием командлета ForEach-Object
.
Для этого примера ниже приведен скрипт, который выполнит следующее:
- Получить список служб, настроенных на автоматический запуск, но в настоящее время не находящихся в запущенном состоянии.
- Далее элементы списка передаются в командлет
ForEach-Object
, чтобы попытаться запустить каждую службу. - A message of either success or failed is displayed depending on the result of the
Start-Service
command.
При выполнении сценария он будет выглядеть так, как показано на скриншоте ниже. Как видите, каждой службе была отправлена команда на запуск. Некоторые из них были успешно запущены, в то время как некоторые из них не удалось запустить.

Пример 4: Чтение данных из CSV с использованием метода ForEach()
Использование данных из файлов CSV популярно среди системных администраторов. Размещение записей в файле CSV упрощает выполнение массовых операций с использованием комбинации Import-CSV
и ForEach
. Эта комбинация обычно используется для создания нескольких пользователей в Active Directory.
В этом следующем примере предполагается, что у вас есть файл CSV с двумя столбцами – Firstname и Lastname. Затем этот файл CSV должен быть заполнен именами новых пользователей, которых нужно создать. Файл CSV будет выглядеть примерно следующим образом.
Теперь переходим к следующему блоку сценария. Сначала импортируйте CSV-файл, передав путь к содержимому в cmdlet Import-CSV
. Затем, используя метод foreach()
, перебирайте имена и создавайте новых пользователей в Active Directory.
При выполнении этого кода у вас теперь должен быть создан пользователь AD для каждой строки в CSV-файле!
Summary
Логика цикла foreach в PowerShell ничем не отличается от других языков программирования. Она изменяется только в том, как она используется и какой вариант цикла foreach выбран для конкретной задачи.
В этой статье вы узнали о различных типах циклов foreach, доступных в PowerShell, и о том, что следует учитывать при выборе того или иного варианта цикла foreach. Вы также увидели три типа циклов foreach в действии, используя различные примеры сценариев.