Логические операторы IF ElseIf и Else в Powershell относятся к основным командам условий не только в этом языке, но и в других. Благодаря таким операторам в наших скриптах добавляются условия.
Вы можете представить скрипт, где вам нужно поставить запятую в выражении "Казнить нельзя помиловать". В зависимости от того к чему это выражение применяется запятая будет стоять в разных местах и эту проблему решает условный оператор.
Условия
Самих условий может быть несколько. Каждый будет разобран дальше.
If
Этот оператор работает самый первый из блока условий и является обязательным в случае любых условий. Когда мы хотим проверить само существование значение достаточно указать переменную:
$uslovie = $true
if ($uslovie) {
Write-Output "Условие выполнено"
}
Результат любого сравнение приравнивается к 2 булевым значениям - это True (правда, существует) и False (ложь, не существует, $None). Если вы передаете переменную в условие без каких либо дополнительных операторов, то само существование значения у переменной позволяет выполнить следующую часть и написать "Условие выполнено". Та часть, которая экранируется в фигурные скобки называется ScriptBlock.
На следующем примере, в первом случае у нас вернется True, так как значение у переменной существует. Во втором случае мы проверяем переменную, которая не хранит никаких значений (она не была объявлена), а значит соответствует $null и вернет False:
$uslovie = 1
if ($uslovie) {
Write-Output "Условие выполнено"
}
# Переменная notexist не имеет значения, т.е. равно $null
if ($notexist) {
Write-Output "Условие не выполнено"
}
Else
Этот оператор не является обязательным. Else используется когда результаты предыдущих проверок равен Fasle:
$uslovie = $false
if($uslovie) {
Write-Output "Условие равно True"
}
else {
Write-Output "Условия равны False"
}
Обратите внимание, что я использую Powershell ISE, а не консоль. При запуске в консоли, при таком написании, у нас будут ошибки:
- Имя "else" не распознано как имя командлета, функции, файла сценария или выполняемой программы.
- The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program.
Связано это с тем, что консоль выполняет каждою строку отдельно и оператор else воспринимается как отдельный. Для избежания таких ситуаций есть множество способов решения:
- Объявлять операторы в одну строку.
- Использовать функции.
- Хранить скрипт в файле и импортировать его.
Эти способы и другие будут рассмотрены далее.
Elseif
Представим, что нам нужно проверить существование нескольких значений. Мы можем это сделать так:
Для избежания таких сложно читаемых конструкций используется дополнительное условие elseif.
Elseif не является обязательным и выполняется после IF. В отличие от else, который работает в случае когда все операторы вернули False, оператор elseif может проверять на True и False. Переписав предыдущий пример, но с новым оператором, условие будет выглядеть так:
$uslovie1 = $false
$uslovie2 = $true
if ($uslovie1) {
Write-Output "Первое условие выполнено"
}
elseif ($uslovie2) {
Write-Output "Первое условие не выполнено"
Write-Output "Второе условие выполнено"
}
else {
Write-Output "Условия не выполнены"
}
В отличие от других операторов elseif может использоваться множество раз. Тот оператор, который первый вернет True, отменит выполнение следующих условий.
Примеры работы с Powershell Filter с объектами AD
Операторы сравнения
Когда нам нужно проверить не только существование значения, но и эквивалентность или упоминание, нам нужно использовать операторы сравнения.
-eq проверка эквивалентности
С помощью оператора -eq можно проверить полное соответствие между значениями. Для примера это может быть строка или число:
$num = 33
if($num -eq 33) {
Write-Output "Число совпадает"
}
Если бы значения не совпадали, то результат был бы False и условие было бы не выполненным. Проведем пример со всеми условиями:
$num = 33
if ($num -eq 33) {
Write-Output "Число 33"
}
elseif ($num -eq 34) {
Write-Output "Число 34"
}
else{
Write-Output "Другое число"
}
Powershell, по умолчанию, не является зависимым от регистра. Это значит, что "Строка" и "строка" будут эквивалентны друг другу. Что бы проверить равенство с учетом регистра нужно использовать -ceq:
$str = 'Строка'
if ($str -ceq 'строка') {
Write-Output 'Первая буква маленькая'
}
elseif ($str -ceq 'Строка') {
Write-Output 'Первая буква большая'
}
else{
Write-Output 'Другое число'
}
Самые первые примеры, которые были показаны выше, являются сокращенным вариантом написания с оператором -eq:
$str = 'строка'
if($str) {Write-Host 'Ok' }
# Одинаковые условия
if($str -eq $True ) {Write-Host 'Ok'}
Важно понять работу следующего примера:
$bo = $false
if ($bo -eq $false){'Pass'}
Так как проверка на эквивалентность $false правдива, результат работы условия будет True.
-ne или не соответствие
Когда нужно проверить отсутствие конкретного значения используется команда -ne:
if( 5 -ne $value )
{
'Pass'
}
Как уже писалось выше, если первое условие возвращает True второе выполняться не будет:
$value = 6
if ( 5 -ne $value )
{
'Pass Ne'
}
elseif (6 -eq $value)
{
'Pass Eq'
}
Так же как и в предыдущем случае если оператор учета регистра -cne.
Для примера так мы запустим сервис, если он не равен Running:
$Service = 'WinRM'
if ( (Get-Service -Name $service).Status -ne 'Running' )
{
Start-Service -Name $Service
Write-Host "Сервис запущен"
}
-gt -ge -lt -le проверка на большее и меньшее значение
Аналогично предыдущим примерам мы можем включать проверку на большее и меньшее значение, для примера выполним такое условие:
$numeric = 5
if ( $numeric -lt 5 ){
'Число меньше 5'
}
elseif ($numeric -ge 5){
'Число больше 5'
}
else{
'Число равно 5'
}
Дословно операторы выше переводятся как Less than (меньше чем) и Gt (больше чем) и именно поэтому выполняется условие else. Другие операторы, включающие букву 'e' вместо 't' выполняют так же проверку на равенство, например ge - Greater or equal (больше или равно). Таких операторов достаточно много:
- gt - больше чем;
- cgt - больше чем, но с учетом регистра;
- ge - больше или равно;
- cge - больше или равно с учетом регистра;
- lt - меньше чем;
- clt - меньше чем, но с учетом регистра;
- le - меньше чем или равно;
- cle - меньше чем или равно с учетом регистра.
Не совсем ясно зачем делать учет регистра в определении количества, но такая возможность тоже есть.
-like проверка вхождений
В Powershell есть возможность проверки вхождений используя -like и определенный синтаксис:
- ? - обозначение единственного пропущенного символа;
- * - обозначение любого количества пропущенных символов.
$computer = 'AD-Moscow-001'
if ($computer -like 'AD*') {'Этот компьютер AD'}
Выше мы проверяли начинается ли строка с символов AD. Если бы мы искали конец строки нужно было указывать символ * до последнего элемента:
$computer = 'AD-Moscow-001'
# Это условие не пройдет, так как проверяется конец строки
if ($computer -like '*AD') {'Pass if'}
# Это условие не пройдет, так как проверяется полное соответствие
elseif ($computer -like 'AD') {'Pass elsif 1'}
# Это пройдет
elseif ($computer -like 'AD*1') {'Pass elsif 2'}
Варианты использования:
- like - поиск вхождения, не чувствителен к регистру;
- clike - поиск вхождения, чувствителен к регистру;
- notlike - проверка на отсутствие вхождения, не чувствителен к регистру;
- cnotlike - проверка на отсутствие вхождения, чувствителен к регистру.
-match использование регулярных выражений
Для проверки с использованием регулярных выражений есть свой оператор -match. Конечно, синтаксис в использовании регулярных выражений и -like отличается:
$computer = 'AD-Moscow-001'
if ($computer -match '^AD-\w\w\w\w\w\w-001') {'Pass if'}
Если не указывать маску/шаблон, то match будет искать по полному совпадению:
$computer = 'AD-Moscow-001'
if ($computer -match 'AD-Moscow-001') {'Pass if'}
Так же есть несколько вариантов использования регулярных выражений:
- match - регулярные выражения не чувствительные к регистру:
- cmatch - чувствительные к регистру;
- notmatch - поиск не совпадающих, не чувствительных к регистру значений;
- cnotmatch - поиск не совпадающих, чувствительных к регистру значений.
-is проверка типов
Часто бывает необходимость проверить тип данных перед дальнейшем использованием. Использование сложения со строкой и числом приводит к разным последствиям. Для избежания этих проблем нужно проверять типы. На примере ниже я проверяю является ли значение числом:
$int = 1
if ($int -is [int]){'Значение число'}
Таких типов данных в Powershell около 13:
- [string] - строка;
- [char] - 16-битовая строка Unicode;
- [byte] - 8 битовый символ;
- [int] - целое 32 битовое число;
- [long] - целое 64 битовое число;
- [bool] - булево значение True/False;
- [decimal] - 128 битовое число с плавающей точкой;
- [single] - 32 битовое число с плавающей точкой;
- [double] - 64 битовое число с плавающей точкой;
- [DateTime] - тип данных даты и времени;
- [xml] - объект xml;
- [array] - массив;
- [hashtable] - хэш таблица.
Так же можно использовать ключ -isnot, который выполняет противоположные действия.
Условия в массивах
Когда мы работаем с коллекциями, массивами или листами проверка вхождений работает немного иначе чем в предыдущих примерах. Тут важно учитывать не только порядок, но и логику:
@(1,3,4,5) -eq 4
4 -eq @(1,2,3,4)
Этот пример так же будет работать с логическими операторами:
$array = @(1,2,3,4)
if (4 -eq $array){'Проверка пройдена 1'}
elseif ($array -eq 4){'Проверка пройдена 2'}
Обратите внимание, что в случае с -ne, который ищет неравенство, результат будет True если хотя бы одно число и строка не совпадает с указанной:
$array = @('string1','string4','string3','string2')
$array -ne 'string1'
if ($array -ne 'string2'){'Проверка пройдена'}
Когда используются операторы типа ge, lt и другие, результат будет True если хотя бы одно из значений будет больше:
$array = @(6,2,3,4)
$array -ge 4
if ($array -ge 4){'Passed'}
Для поиска вхождений в массивах обычно используются операторы описанные далее.
-contains
При использовании contains у нас возвращаются булевы значения True и False и является более логичным для проверки массивов:
$massive = @('node1','node2','node3')
$massive -contains 'node1'
if ($massive -contains 'node1'){'Passed'}
Другие варианты использования:
- contains - без учета регистра;
- ccontains - с учетом регистра;
- notcontains - отсутствие значения без учета регистра;
- cnotcontains - отсутствие значение с учетом регистра.
-in
Этот оператор создан для удобства людей, которые пишут на других языках. Он отличается от contains порядком проверяемых значений. В этом случае массив должен находиться справа:
$massive = @('node1','node2','node3')
$massive -in 'node1'
'node1' -in $massive
if ($massive -in 'node1'){'Passed 1'}
elseif ('node1' -in $massive){'Passed 2'}
Доступные варианты:
- in - регистр не имеет значения;
- cin - регистр имеет значение;
- notin - отсутствие вхождения, регистр не имеет значения;
- cnotin - отсутствие вхождения, регистр имеет значения.
Больше примеров можно увидеть в статье Работа с массивом в Powershell и листами на примерах.
Логические операторы
Когда нам нужно комбинировать условия удобно использовать логические операторы.
-not
Использование этого оператора переворачивает результат. Если результат значения равен False, то используя not, выражение все равно будет выполнен:
if (-not $notexist ){'Passed 1'}
Если вы хотите использовать предыдущие операторы тоже, тогда их нужно помещать между скобок:
$hs = @('ex1','ex2','ex3')
if (-not ('ex4' -in $hs) ){'Passed 1'}
У -not есть алиас в виде восклицательного знака ! :
if (!('ex4' -in $hs) ){'Passed 1'}
-and
And позволяет связывать несколько значений. Условие будет выполнено только в том случае, если все значения будут True:
$cost = 13
if (($cost -gt 2) -and ($cost -lt 16)){Write-Host 'Выполнено'}
Если хотя бы одно из выражений было бы равно False, то все условие относилось бы к False:
$cost = 13
if (($cost -gt 2) -and ($cost -lt 10)){Write-Host 'Выполнено 1'}
elseif (($cost -gt 2) -and ($cost -lt 14)){Write-Host 'Выполнено 2'}
Мы так же можем проверять существование нескольких значений:
$cost = 13,14,15
if (($cost[0]) -and ($cost[1]) -and ($cost[2]) ) {'Верно'}
-or
Отличия -and от -or в том, что нам достаточно получить True только от одного выражения:
$a = 4
$b = 7
if (($a -ge 4) -or ($b -eq 2)){Write-Host 'ок'}
Вы можете комбинировать несколько операторов для верного выполнения условия, главное помещать их в кавычки:
$a = 4
$b = 7
if (($a -ge 4) -and ($b -eq 7) -or ($b -eq 7)){Write-Host 'ок'}
Функции по работе со строками в Powershell
Использование выражений при сравнении в Powershell
Мы можем использовать команды Powershell в сравнениях:
if (Get-NetAdapter){Write-Host "Сетевой адаптер установлен"}
Командой Get-NetAdapte мы получаем список адаптеров. Если бы список был пуст, то он бы вернул $null и выражение бы не выполнилось.
Можно использовать серию скриптов, но главное экранировать в скобки:
if ( (Get-Process -Name *powersh*) -and (Get-Service) ) {'Ok'}
Проверка на $null
Мы уже писали о сложностях работы с $null в Powershell, но главное придерживаться правила, что это значение должно быть слева:
if ( $null -eq $value )
Переменные
Вы можете назначать переменную через условие, а в самом ScriptBlock работать с ней:
if ( $proc = Get-Process Notepad* ){$proc | Stop-Process}
Процесс Notepad будет остановлен в случае, если такой процесс существует.
Мы так же можем назначать результат работы условий с помощью переменной:
$a = 33
$result =if ( $a -eq 22 ){$a += $a}
elseif ($a -eq 33){$a += 1}
else {$a}
$a
Эти способы весомо ухудшают читаемость кода и я бы не советовал их использовать.
...
Подписывайтесь на наш Telegram канал
Теги: #powershell