Овладение PowerShell Where-Object: Полное руководство

При работе с значениями свойств в коллекции объектов PowerShell иногда вам потребуется способ фильтрации всех вещей, которые вам не нужны. Знание того, как использовать командлет PowerShell Where-Object, является важным навыком в вашем наборе инструментов PowerShell.

Командлет Where-Object является удобным способом фильтрации объектов. В этом руководстве вы узнаете различные способы создания командлета Where-Object, доступные параметры, синтаксис, а также как использовать несколько условий как профессионал!

Предварительные требования

В этой статье есть только одно предварительное требование. Вы должны иметь некоторое базовое знакомство с командами и синтаксисом PowerShell.

Все примеры в этой статье будут основаны на текущем стабильном выпуске PowerShell (7.1.0 на момент написания). Но если у вас установлен PowerShell 4.0 и выше, команды будут работать одинаково.

Понимание работы командлета PowerShell Where-Object

Основная цель командлета PowerShell Where-Object – это фильтрация вывода команды так, чтобы возвращалась только информация, которую вы хотите видеть.

В двух словах, командлет Where-Object – это фильтр; всё. Он позволяет вам создать условие, которое возвращает True или False. В зависимости от результата этого условия командлет либо возвращает вывод, либо нет.

Вы можете создать это условие одним из двух способов: “старым” способом с блоками скриптов scriptblocks и “новым” способом с использованием параметров или операторов сравнения.

Создание условий фильтра с помощью скриптовых блоков

Скриптовые блоки являются ключевым компонентом в PowerShell. Скриптовые блоки используются в сотнях мест во всем языке. Скриптовый блок – это анонимная функция. Это способ компартментализации кода и его выполнения в различных местах. Вы можете создать фильтр для Where-Object с помощью скриптового блока.

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

Если скриптовый блок возвращает значение, отличное от логического False или нулевой переменной, это считается True. В противном случае, это считается False.

Например, предположим, вам нужно найти все службы Windows, которые в настоящее время имеют тип запуска Автоматический. Сначала вы соберете все текущие службы с помощью Get-Service. Get-Service затем возвращает множество различных объектов служб с различными свойствами.

Используя конвейер PowerShell, вы можете направить эти объекты в командлет Where-Object и использовать параметр FilterScript. Поскольку параметр FilterScript принимает скриптблок, вы можете создать условие для проверки того, равно ли свойство StartType каждого объекта Automatic, как показано ниже.

{$_.StartType -EQ 'Automatic'}

После создания блока фильтрации вы передаете этот скриптблок параметру FilterScript. Where-Object будет выполнять этот скриптблок для каждого объекта, поступающего по конвейеру, и оценивать каждое свойство StartType. Если свойство равно Automatic, Where-Object передаст объект. В противном случае объект будет отброшен.

Приведен простой пример этой методологии ниже.

Get-Service | Where-Object -FilterScript {$_.StartType -EQ 'Automatic'}
Script Block construct

Многие люди используют позиционные параметры с командлетом Where-Object и не включают имя параметра FilterScript. Вместо этого они просто предоставляют сам скриптблок, например, Where-Object {$_.StartType -eq 'Automatic'}.

Хотя этот тип конструкции работает для данного сценария, концепция скриптблока с фигурными скобками или даже переменной конвейера $_ делает код менее читаемым и более сложным для менее опытных пользователей PowerShell. Проблема читаемости именно такой конструкции заставила команду PowerShell ввести параметры или операторы сравнения.

Операторы сравнения

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

Get-Service | Where-Object -Property StartType -EQ 'Automatic'

Обратите внимание, что вместо использования блока сценария команда указывает свойство объекта как значение параметра для параметра Property. Оператор eq теперь также является параметром, что позволяет передавать ему значение Automatic.

Использование параметров таким образом теперь устраняет необходимость в блоке сценария полностью.

A scriptblock is a better choice when defining more complex filtering conditions. The Property parameter may not always be the best choice. If using a scriptblock, just remember to document your code using comments!

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

Основы фильтрации

Используя параметры, Where-Object фильтрует коллекции объектов с использованием обычных операторов сравнения. Давайте рассмотрим несколько примеров их работы.

Операторы содержания

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

Например, предположим, вы хотите отфильтровать определенное значение свойства в коллекции. Для этого можно использовать операторы содержания.

В PowerShell есть несколько различных операторов содержания:

  • -contains / -ccontains – Фильтрует коллекцию, содержащую значение свойства.
  • -notcontains / -cnotcontains – Фильтрует коллекцию, которая не содержит значение свойства.
  • -in / -cin – значение находится в коллекции, возвращает значение свойства, если найдено совпадение.
  • -notin / -cnotin – значение не находится в коллекции, null/$false, если значение свойства отсутствует.

Для учета регистра используйте операторы содержания, начинающиеся с -c[operator]

Связано: Понимание операторов сравнения PowerShell на примерах

Предположим, вы хотите проверить статус службы Windows BITS. Вы можете сделать это, используя параметр contains (оператор), передав ему значение BITS следующим образом.

Get-Service | Where-Object -Property Name -Contains 'BITS'

А вот что вы ожидали увидеть:

Where-Object equivalent to Get-Service -ServiceName ‘BITS’

Всегда помните про фильтрацию слева! Предыдущий пример эквивалентен выполнению Get-Service -ServiceName 'BITS'.

Возможно, вам хочется сделать что-то более изысканное и найти все службы с Статусом, который не Запущен и с ТипомЗапуска, который находится в одной строке (или может быть массивом) с именем Manual. Используя блок скрипта ниже, команда использует параметр FilterScript для передачи блока скрипта, который оценивает обе эти условия.

Связано: Возвращаемся к основам: Понимание объектов PowerShell

Get-Service |
	Where-Object {($_.Status -notcontains 'Running') -and ($_.StartType -in 'Manual')}

Когда вы запускаете вышеуказанную команду, вы увидите только службы, которые остановлены и имеют StartType Manual.

More advanced filtering of a collection of objects

Фильтрация с операторами содержания хорошо работает с коллекциями, которые содержат много значений свойств. Учитывая количество свойств, которые возвращает Get-Service, фильтрация через все эти свойства становится проще, когда вы комбинируете операторы содержания и логические операторы.

Операторы сопоставления

Подобно тому, как вы используете операторы содержания с Where-Object, вы также можете использовать операторы сопоставления. Операторы сопоставления позволяют сопоставлять строки внутри строк. Например, 'foofoo' -like '*foo*' возвращает True или 'foofoo' -match 'foo' возвращает True. Операторы сопоставления сопоставляют строки внутри строк.

В PowerShell у вас есть несколько различных операторов сопоставления, которые вы можете использовать внутри Where-Object.

  • -like / -clike – строка соответствует шаблону подстановки.
  • -notlike / -cnotlike – строка не соответствует шаблону подстановки.
  • -match / -cmatch – строка соответствует шаблону регулярного выражения.
  • -notmatch / -cnotmatch – строка не соответствует шаблону регулярного выражения

Для учета регистра используйте операторы сопоставления, которые начинаются с -c[operator]

Почти идентично по форме операторам содержания, вы можете использовать операторы сопоставления, как показано ниже. Приведенный ниже пример находит все службы, у которых в значении свойства DisplayName есть Windows.

Get-Service | Where-Object { $_.DisplayName -match 'Windows'}
The match operator uses regular expressions to match on certain values.

Связано: Начало работы с PowerShell и Regex

Вы также можете использовать оператор like, чтобы использовать общие методы сопоставления, такие как использование подстановочного знака (*) для сопоставления любого символа или, возможно, ?, чтобы сопоставить один символ.

Get-Service | Where-Object {($_.Name -like 'Win*')}

Теперь результаты фильтруются, чтобы оставить только те имена служб, у которых первые три символа – ‘Win‘:

service names with ‘Win

Использование подстановочного знака означает, что вам не нужно знать полное название службы. Достаточно нескольких букв строки. Эти операторы также могут быть объединены с логическими операторами, чтобы улучшить фильтрацию еще больше.

Операторы равенства

Аналогично использованию операторов содержания и сравнения вы также можете использовать операторы равенства с Where-Object. Операторы равенства полезны, когда нужно сравнивать числовые значения.

Например, 1 -eq 1 будет True, в то время как 1 -gt 2 будет False. В PowerShell есть множество различных операторов равенства, которые вы можете использовать в качестве параметров Where-Object или внутри условных скриптовых блоков.

  • -eq / -ceq – значение равно указанному значению.
  • -ne / -cne – значение не равно указанному значению.
  • -gt / -cgt – значение больше указанного значения.
  • -ge / -cge – значение больше или равно указанному значению.
  • -lt / -clt – значение меньше указанного значения.
  • -le / -cle – значение меньше или равно указанному значению.

Например, возможно, вам захочется найти все работающие процессы, которые занимают от двух до 10 процентов вашего процессора. Нет проблем с использованием командлетов PowerShell Get-Process и Where-Object.

Используя скриптблок, вы можете объединить два условия вместе, используя оператор and, который оценит их оба. Если оба возвращают True, Where-Object вернет объект процесса, переданный через конвейер. Если хотя бы одно из условий возвращает False, Where-Object исключит объект.

Get-Process | Where-Object {($_.CPU -gt 2.0) -and ($_.CPU -lt 10)}

Вот что вы увидите:

Filtering with greater than and less than

Фильтрация с использованием операторов равенства Where-Object поможет вам в создании системных отчетов или сравнении значений.

Следующие шаги

Теперь, когда вы знаете больше о том, как использовать командлет PowerShell Where-Object для фильтрации всего, что угодно, что еще вы можете сделать? Попробуйте выполнить более сложные задачи фильтрации, используя множественные условия и операторы на коллекциях для отфильтровывания значений свойств и форматирования вывода по вашему вкусу.

Source:
https://adamtheautomator.com/powershell-where-object/