Как работать с логическими условиями IF в Powershell ELSEIF и ELSE на примерах


17 октября 2019


Работа с операторами условий IF в Powershell ELSEIF и ELSE на примерах

Логические операторы IF ElseIf и Else в Powershell относятся к основным командам условий не только в этом языке, но и в других. Благодаря таким операторам в наших скриптах добавляются условия.

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

Условия

Самих условий может быть несколько. Каждый будет разобран дальше.

If

Этот оператор работает самый первый из блока условий и является обязательным в случае любых условий. Когда мы хотим проверить само существование значение достаточно указать переменную:

$uslovie = $true
if ($uslovie) {
   Write-Output "Условие выполнено"
}

логические условия powershell if

Результат любого сравнение приравнивается к 2 булевым значениям - это True (правда, существует) и False (ложь, не существует, $None). Если вы передаете переменную в условие без каких либо дополнительных операторов, то само существование значения у переменной позволяет выполнить следующую часть и написать "Условие выполнено". Та часть, которая экранируется в фигурные скобки называется ScriptBlock.

На следующем примере, в первом случае у нас вернется True, так как значение у переменной существует. Во втором случае мы проверяем переменную, которая не хранит никаких значений (она не была объявлена), а значит соответствует $null и вернет False:

$uslovie = 1
if ($uslovie) {
   Write-Output "Условие выполнено"
}

# Переменная notexist не имеет значения, т.е. равно $null
if ($notexist) {
   Write-Output "Условие не выполнено"
}

логические условия powershell if

Else

Этот оператор не является обязательным. Else используется когда результаты предыдущих проверок равен Fasle:

$uslovie = $false
if($uslovie) {
   Write-Output "Условие равно True"
}
else { 
   Write-Output "Условия равны False"
}

логические условия powershell else

Обратите внимание, что я использую Powershell ISE, а не консоль. При запуске в консоли, при таком написании, у нас будут ошибки:

  • Имя "else" не распознано как имя командлета, функции, файла сценария или выполняемой программы.
  • The term 'else' is not recognized as the name of a cmdlet, function, script file, or operable program.

Связано это с тем, что консоль выполняет каждою строку отдельно и оператор else воспринимается как отдельный. Для избежания таких ситуаций есть множество способов решения:

  1. Объявлять операторы в одну строку.
  2. Использовать функции.
  3. Хранить скрипт в файле и импортировать его.

Эти способы и другие будут рассмотрены далее.

Elseif

Представим, что нам нужно проверить существование нескольких значений. Мы можем это сделать так:логические условия powershell 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 "Условия не выполнены"
}

логические условия powershell elseif

В отличие от других операторов elseif может использоваться множество раз. Тот оператор, который первый вернет True, отменит выполнение следующих условий.

 

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

Когда нам нужно проверить не только существование значения, но и эквивалентность или упоминание, нам нужно использовать операторы сравнения.

-eq проверка эквивалентности

С помощью оператора -eq можно проверить полное соответствие между значениями. Для примера это может быть строка или число:

$num = 33
if($num -eq 33) {
   Write-Output "Число совпадает"
}

логические условия powershell if else eq

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

$num = 33
if ($num -eq 33) {
   Write-Output "Число 33"
}
elseif ($num -eq 34) {
   Write-Output "Число 34"
}
else{
   Write-Output "Другое число"
}

логические условия powershell if else eq

Powershell, по умолчанию, не является зависимым от регистра. Это значит, что "Строка" и "строка" будут эквивалентны друг другу. Что бы проверить равенство с учетом регистра нужно использовать -ceq:

$str = 'Строка'
if ($str -ceq 'строка') {
   Write-Output 'Первая буква маленькая'
}
elseif ($str -ceq 'Строка') {
   Write-Output 'Первая буква большая'
}
else{
   Write-Output 'Другое число'
}

логические условия powershell if else eq

Самые первые примеры, которые были показаны выше, являются сокращенным вариантом написания с оператором -eq:

$str = 'строка'

if($str) {Write-Host 'Ok' }
# Одинаковые условия
if($str -eq $True ) {Write-Host 'Ok'}

Важно понять работу следующего примера:

$bo = $false

if ($bo -eq $false){'Pass'}

логические условия powershell if else eq

Так как проверка на эквивалентность $false правдива, результат работы условия будет True.

-ne или не соответствие

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

if( 5 -ne $value )
{
    'Pass'
}

Как уже писалось выше, если первое условие возвращает True второе выполняться не будет:

$value = 6
if ( 5 -ne $value )
{
    'Pass Ne'
}
elseif (6 -eq $value)
{
    'Pass Eq'
}

логические условия powershell if else ne

Так же как и в предыдущем случае если оператор учета регистра -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'
}

логические условия powershell if else ge gt lt le

Дословно операторы выше переводятся как 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'}

логические условия powershell if else like

Выше мы проверяли начинается ли строка с символов 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'}

логические условия powershell if else like

Варианты использования:

  • 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'}

логические условия powershell if else match

Так же есть несколько вариантов использования регулярных выражений:

  • match - регулярные выражения не чувствительные к регистру:
  • cmatch - чувствительные к регистру;
  • notmatch - поиск не совпадающих, не чувствительных к регистру значений;
  • cnotmatch - поиск не совпадающих, чувствительных к регистру значений.

-is проверка типов

Часто бывает необходимость проверить тип данных перед дальнейшем использованием. Использование сложения со строкой и числом приводит к разным последствиям. Для избежания этих проблем нужно проверять типы. На примере ниже я проверяю является ли значение числом:

$int = 1
if ($int -is [int]){'Значение число'}

логические условия powershell if else is

Таких типов данных в 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)

логические условия powershell if else в массивах

Этот пример так же будет работать с логическими операторами:

$array = @(1,2,3,4)
if (4 -eq $array){'Проверка пройдена 1'}
elseif ($array -eq 4){'Проверка пройдена 2'}

логические условия powershell if else в массивах

Обратите внимание, что в случае с -ne, который ищет неравенство, результат будет True если хотя бы одно число и строка не совпадает с указанной:

$array = @('string1','string4','string3','string2')
$array -ne 'string1'
if ($array -ne 'string2'){'Проверка пройдена'}

логические условия powershell if else в массивах

Когда используются операторы типа ge, lt и другие, результат будет True если хотя бы одно из значений будет больше:

$array = @(6,2,3,4)
$array -ge 4
if ($array -ge 4){'Passed'} 

powershell логические операторы

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

-contains

При использовании contains у нас возвращаются булевы значения True и False и является более логичным для проверки массивов:

$massive = @('node1','node2','node3') 
$massive -contains 'node1'
if ($massive -contains 'node1'){'Passed'} 

логические условия powershell else if containsДругие варианты использования:

  • 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'} 

логические условия powershell else if in

Доступные варианты:

  • in - регистр не имеет значения;
  • cin - регистр имеет значение;
  • notin - отсутствие вхождения, регистр не имеет значения;
  • cnotin - отсутствие вхождения, регистр имеет значения.

Больше примеров можно увидеть в статье Работа с массивом в Powershell и листами на примерах.

 

Логические операторы

Когда нам нужно комбинировать условия удобно использовать логические операторы.

-not

Использование этого оператора переворачивает результат. Если результат значения равен False, то используя not, выражение все равно будет выполнен:

if (-not $notexist ){'Passed 1'} 

логические условия powershell else if not

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

$hs = @('ex1','ex2','ex3')
if (-not ('ex4' -in $hs) ){'Passed 1'} 

У -not есть алиас в виде восклицательного знака ! :

if (!('ex4' -in $hs) ){'Passed 1'}

логические условия powershell else if not

-and

And позволяет связывать несколько значений. Условие будет выполнено только в том случае, если все значения будут True:

$cost = 13
if (($cost -gt 2) -and ($cost -lt 16)){Write-Host 'Выполнено'}

логические условия powershell else if and

Если хотя бы одно из выражений было бы равно 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'}

логические условия powershell else if and

Мы так же можем проверять существование нескольких значений:

$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 'ок'}

логические условия powershell else if or

Вы можете комбинировать несколько операторов для верного выполнения условия, главное помещать их в кавычки:

$a = 4
$b = 7
if (($a -ge 4) -and ($b -eq 7) -or ($b -eq 7)){Write-Host 'ок'}

 

Использование выражений при сравнении в Powershell

Мы можем использовать команды Powershell в сравнениях:

if (Get-NetAdapter){Write-Host "Сетевой адаптер установлен"}

Командой Get-NetAdapte мы получаем список адаптеров. Если бы список был пуст, то он бы вернул $null и выражение бы не выполнилось.

Можно использовать серию скриптов, но главное экранировать в скобки:

if ( (Get-Process -Name *powersh*) -and (Get-Service) ) {'Ok'}

логические условия powershell else if выражения

 

Проверка на $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

логические условия powershell else if переменные

Эти способы весомо ухудшают читаемость кода и я бы не советовал их использовать.

...

Теги: #powershell


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