Фильтрация через Where-Object в Powershell с примерами


07 ноября 2019


Фильтрация объектов с Where-Object в Powershell объектов на примерах

Один из методов, который можно использовать для фильтрации объектов является Where-Object в Powershell. Формально этот командлет не относится к условиям, но его можно применять и так. Основное преимущество этой команды это удобное использование.

Синтаксис

Допустим у нас есть какой-то список процессов на примере этого:

Get-Process

Получения списка процессов в Powershell

Допустим мы хотим вывести объекты, где значения CPU больше 1.0. С помощью Where-Object мы можем сделать это:

Get-Process | Where-Object -Property CPU -GE 1

Фильтрация powershell where object

GE - переводится как "Больше или равно". В Powershell не используются обычные методы сравнения типа ">,<,= ". Вместо них есть аббревиатуры. Более подробно с операторами условий вы можете познакомиться в статье "Как работать с логическими условиями IF в Powershell ELSEIF и ELSE на примерах", но часть из них будет приведена в этой статье.

Если вы примените команду без оператора мы не получим ошибку:

Get-Process | Where-Object -Property SI

Фильтрация powershell where object

По сути у нас будет возвращаться только существующие значения (равные $True), где 0 и пустые строки будут равны $False и не будут возвращены. За кадром это будет выглядеть так:

SI -eq $True

Все свойства, по которым мы можем фильтровать, можно вывести так:

Get-Process | Get-Member -MemberType *Property* 

Свойства для фильтрации через powershell where object

Чтобы вывести все значения после фильтрации используйте select:

Get-Process | Where-Object -Property SI | Select *

Алиасы

У нас доступно два алиаса, которые работают таким де способом. Чаще вы могли встречать именно работу Where. В следующем примере используется "LE", который покажет значения меньше либо равные 0.5:

Get-Process | where -Property CPU -LE 0.5

Фильтр вывода powershell Where-Object

Так же можно применять алиас в виде знака "?". Следующий пример, вернет результат аналогичный предыдущему:

Get-Process | ? -Property CPU -LE 0.5

Фильтр вывода powershell Where-Object

Конвейер

Если вы читали статью про функции в Powershell, то должны знать что у большинства команд есть параметр, который принимает значения через конвейер. В данном случае это InputObject. Если в коде есть проблемы с читаемостью, то мы можем передавать объект напрямую. Следующий пример аналогичен предыдущему:

$proc = Get-Process 
Where -Property CPU -LE 0.5 -InputObject $proc

Фильтр вывода powershell Where-Object с конвейером

 

Фильтрация вывода FilterScript

Другие возможности и условия реализуются через параметр FilterScript, который легче понять как ScriptBlock. Через него мы можем использовать выражения и добавлять условия.

В предыдущем примере мы возвращали значения, где CPU меньше или равно 0.5. Это так же можно реализовать с FilterScript:

$data = Get-Process
$data | Where-Object -FilterScript {$PSItem.CPU -le 0.5}

Фильтр вывода powershell Where-Object с FilterScript

Этот параметр позволяет использовать дополнительные выражения, которые экранируются фигурными скобками {}. $PSItem это значения, которые передаются через конвейер, вы можете так же знать эту переменную в виде "$_".

Параметр фильтрации первый принимает значения и его не обязательно указывать. Такой синтаксис не приведет к ошибке:

$data | Where-Object {$PSItem.CPU -le 0.5}

Несколько условий

Когда нужно применять несколько сравнений необходимо использовать этот параметр. Найдем значения, которые больше 2 и не более 4:

$array = @(1,2,3,4,5,6,7,8)
$array | Where-Object {$PSItem -gt 2 -and $PSItem -lt 4}

powershell where несколько условий

Когда мы используем "and", что в переводе значит "и", мы ищем объекты, которые попадут под оба условия (оба равны $True). Если нужно вывести объекты совпадающие с одним из условий используйте -or:

$array | Where-Object {$_ -eq 2 -or $_ -eq 4} 

powershell where несколько условий

Таких условий может быть неограниченно количество и их можно комбинировать как угодно:

Get-Service | Where-Object {$_.Status -eq 'Running' -or $_.Status -eq 'Stopped' -and $_.Name -eq 'WinRM' } 

powershell where несколько условий

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

{($_.Status -eq 'Running' -or $_.Status -eq 'Stopped') -and $_.Name -eq 'WinRM' } 

В FilterScript так же можно использовать командлеты. Так мы получим все процессы, которые имеют сетевые подключения:

Get-Process | where {
      (Get-NetTCPConnection -OwningProcess $_.ID -ErrorAction SilentlyContinue) `
      -and $PSItem.ID -ne 1
}

powershell фильтр вывода

 

Операторы условий

Выше уже приведены примеры используя условия EQ (эквивалентно) и GT (больше чем), но таких параметров больше.

Когда нам нужно отфильтровать данные на упоминание какого-то значения используются следующие операторы:

  • Contains - проверяет упоминание в данных;
  • NotContains - проверяет отсутствие упомянутых данных;
  • CContains - включает чувствительность к регистру при проверке упоминания;
  • CNotContains - включает чувствительность к регистру при проверке отсутствия значения в данных.
$services = Get-Service
$services | where -Property Name -contains WinRM
$services | where -Property Name -NotContains WinRM

where object

При фильтрации аналогично contains работает In:

  • In - проверяет вхождение;
  • NotIn - проверяет отсутствие вхождения;
  • CIn - проверяет вхождение с учетом регистра;
  • CNotIn - проверяет отсутствие вхождения с учетом регистра.
$services = Get-Service
$services | ? -Property Name -in WinRM
$services | ? -Property Name -NotIn WinRM

powershell where object

Когда мы не уверены в значениях, которые ищем можно использовать Like. С помощью Like можно использовать маски в виде знака *, которые заменяют символы:

  • Like - фильтрация по маске;
  • NotLike - фильтрация по значениям где отсутствует указанная маска;
  • CLike - фильтрация с учетом регистра;
  • CNotLike - фильтрация с учетом регистра и отсутствием маски
$adapters = Get-NetAdapter
$adapters | ? -Property LinkSpeed -Like "*0 Gbps"
$adapters | ? -Property LinkSpeed -NotLike "10*"
$adapters | ? -Property Name -Like "*Ext*"

оператор where object powershell

Можно использовать регулярные выражения. Для этого используется match:

  • Match - поиск по маске регулярных выражений;
  • NotMatch - отсутствие маски регулярных выражений;
  • CMatch - учет регистра с регулярными выражениями;
  • CNotMatch - учет регистра при отсутствии упомянутой маски.
$massive = @(1,'s',2,'d')
$massive | ? {$_ -match "\d"}
$massive | ? {$_ -NotMatch "\d"}

оператор where object powershell

Когда работаем с датой и числами можно искать меньшее значение:

  • LT - меньше чем;
  • CLT - меньше чем с учетом регистра ( не знаю где это использовать);
  • LE - меньше или равно;
  • CLE - меньше или равно с учетом регистра.
$massive = @(1,'s',2,'d')
$massive | where {$PSItem -LT 2}
$massive | where {$PSItem -LE 2}

оператор where object powershell

Противоположны, то есть большие значения фильтруются используя эти операторы:

  • GT - больше чем;
  • CGT - больше чем с учетом регистра;
  • GE - больше или равно;
  • CGE - больше или равно с учетом регистра.
$array = @(1, 2, 3, 4)
$array | Where-Object {$PSItem -GT 3}
$array | Where-Object {$PSItem -GE 3}

оператор where object powershell

Операторы, которые проверяют равенство:

  • EQ - объект равен;
  • NE - объект не равен;
  • CEQ - равно с учетом регистра;
  • CNE - объект не равен с учетом регистра.
$array = @(1, 2, 3, 4)
$array | ? {$PSItem -EQ 3}
$array | ? {$PSItem -NE 3}

оператор where object powershell

Через IS обычно проверяются типы данных:

  • IS
  • IsNot
$array = @(1, 's', 'd', 4)
$array | where {$_ -Is [int]}
$array | where {$_ -IsNot [int]}

оператор where object powershell

Not преобразует правдивое $True в $False и наоборот. Так будет выглядеть предыдущий пример с not:

$array = @(1, 's', 'd', 4)
$array | where { -not ($PSItem -Is [int])}
$array | where { -not ($PSItem -IsNot [int])}

оператор where object powershell

 

Метод Where

По аналогии с командой доступен метод Where. Синтаксис такой:

(Get-Process).Where({ $PSItem.Name -like "*sv*" })

Метод where powershell

С ним можно работать так же как и с FilterScript:

(Get-NetAdapter).Where({$PSItem -Like "*1*" -and $PSItem.Name -like "*Eth*"})

Метод where powershell 

...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.