Один из методов, который можно использовать для фильтрации объектов является Where-Object в Powershell. Формально этот командлет не относится к условиям, но его можно применять и так. Основное преимущество этой команды это удобное использование.
Синтаксис
Допустим у нас есть какой-то список процессов на примере этого:
Get-Process
Допустим мы хотим вывести объекты, где значения CPU больше 1.0. С помощью Where-Object мы можем сделать это:
Get-Process | Where-Object -Property CPU -GE 1
GE - переводится как "Больше или равно". В Powershell не используются обычные методы сравнения типа ">,<,= ". Вместо них есть аббревиатуры. Более подробно с операторами условий вы можете познакомиться в статье "Как работать с логическими условиями IF в Powershell ELSEIF и ELSE на примерах", но часть из них будет приведена в этой статье.
Если вы примените команду без оператора мы не получим ошибку:
Get-Process | Where-Object -Property SI
По сути у нас будет возвращаться только существующие значения (равные $True), где 0 и пустые строки будут равны $False и не будут возвращены. За кадром это будет выглядеть так:
SI -eq $True
Все свойства, по которым мы можем фильтровать, можно вывести так:
Get-Process | Get-Member -MemberType *Property*
Чтобы вывести все значения после фильтрации используйте select:
Get-Process | Where-Object -Property SI | Select *
Алиасы
У нас доступно два алиаса, которые работают таким де способом. Чаще вы могли встречать именно работу Where. В следующем примере используется "LE", который покажет значения меньше либо равные 0.5:
Get-Process | where -Property CPU -LE 0.5
Так же можно применять алиас в виде знака "?". Следующий пример, вернет результат аналогичный предыдущему:
Get-Process | ? -Property CPU -LE 0.5
Конвейер
Если вы читали статью про функции в Powershell, то должны знать что у большинства команд есть параметр, который принимает значения через конвейер. В данном случае это InputObject. Если в коде есть проблемы с читаемостью, то мы можем передавать объект напрямую. Следующий пример аналогичен предыдущему:
$proc = Get-Process
Where -Property CPU -LE 0.5 -InputObject $proc
Фильтрация вывода FilterScript
Другие возможности и условия реализуются через параметр FilterScript, который легче понять как ScriptBlock. Через него мы можем использовать выражения и добавлять условия.
В предыдущем примере мы возвращали значения, где CPU меньше или равно 0.5. Это так же можно реализовать с FilterScript:
$data = Get-Process
$data | Where-Object -FilterScript {$PSItem.CPU -le 0.5}
Этот параметр позволяет использовать дополнительные выражения, которые экранируются фигурными скобками {}. $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}
Когда мы используем "and", что в переводе значит "и", мы ищем объекты, которые попадут под оба условия (оба равны $True). Если нужно вывести объекты совпадающие с одним из условий используйте -or:
$array | Where-Object {$_ -eq 2 -or $_ -eq 4}
Таких условий может быть неограниченно количество и их можно комбинировать как угодно:
Get-Service | Where-Object {$_.Status -eq 'Running' -or $_.Status -eq 'Stopped' -and $_.Name -eq 'WinRM' }
Если сомневаетесь в логике выполнения, то можете использовать круглые скобки для явного обозначения. Предыдущее выражение будет выполнятся в такой последовательности:
{($_.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
}
Операторы условий
Выше уже приведены примеры используя условия EQ (эквивалентно) и GT (больше чем), но таких параметров больше.
Когда нам нужно отфильтровать данные на упоминание какого-то значения используются следующие операторы:
- Contains - проверяет упоминание в данных;
- NotContains - проверяет отсутствие упомянутых данных;
- CContains - включает чувствительность к регистру при проверке упоминания;
- CNotContains - включает чувствительность к регистру при проверке отсутствия значения в данных.
$services = Get-Service
$services | where -Property Name -contains WinRM
$services | where -Property Name -NotContains WinRM
При фильтрации аналогично contains работает In:
- In - проверяет вхождение;
- NotIn - проверяет отсутствие вхождения;
- CIn - проверяет вхождение с учетом регистра;
- CNotIn - проверяет отсутствие вхождения с учетом регистра.
$services = Get-Service
$services | ? -Property Name -in WinRM
$services | ? -Property Name -NotIn WinRM
Когда мы не уверены в значениях, которые ищем можно использовать 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*"
Можно использовать регулярные выражения. Для этого используется match:
- Match - поиск по маске регулярных выражений;
- NotMatch - отсутствие маски регулярных выражений;
- CMatch - учет регистра с регулярными выражениями;
- CNotMatch - учет регистра при отсутствии упомянутой маски.
$massive = @(1,'s',2,'d')
$massive | ? {$_ -match "\d"}
$massive | ? {$_ -NotMatch "\d"}
Когда работаем с датой и числами можно искать меньшее значение:
- LT - меньше чем;
- CLT - меньше чем с учетом регистра ( не знаю где это использовать);
- LE - меньше или равно;
- CLE - меньше или равно с учетом регистра.
$massive = @(1,'s',2,'d')
$massive | where {$PSItem -LT 2}
$massive | where {$PSItem -LE 2}
Противоположны, то есть большие значения фильтруются используя эти операторы:
- GT - больше чем;
- CGT - больше чем с учетом регистра;
- GE - больше или равно;
- CGE - больше или равно с учетом регистра.
$array = @(1, 2, 3, 4)
$array | Where-Object {$PSItem -GT 3}
$array | Where-Object {$PSItem -GE 3}
Операторы, которые проверяют равенство:
- EQ - объект равен;
- NE - объект не равен;
- CEQ - равно с учетом регистра;
- CNE - объект не равен с учетом регистра.
$array = @(1, 2, 3, 4)
$array | ? {$PSItem -EQ 3}
$array | ? {$PSItem -NE 3}
Через IS обычно проверяются типы данных:
- IS
- IsNot
$array = @(1, 's', 'd', 4)
$array | where {$_ -Is [int]}
$array | where {$_ -IsNot [int]}
Not преобразует правдивое $True в $False и наоборот. Так будет выглядеть предыдущий пример с not:
$array = @(1, 's', 'd', 4)
$array | where { -not ($PSItem -Is [int])}
$array | where { -not ($PSItem -IsNot [int])}
Метод Where
По аналогии с командой доступен метод Where. Синтаксис такой:
(Get-Process).Where({ $PSItem.Name -like "*sv*" })
С ним можно работать так же как и с FilterScript:
(Get-NetAdapter).Where({$PSItem -Like "*1*" -and $PSItem.Name -like "*Eth*"})
...
Подписывайтесь на наш Telegram канал
Теги: #powershell