Not if powershell: PowerShell Basics: If -Not Conditional Operator & Logic

Содержание

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

Логические операторы 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 воспринимается как отдельный. Для избежания таких ситуаций есть множество способов решения:

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

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

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, отменит выполнение следующих условий.

 

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

-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 в сравнениях:


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

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

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


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

 

Мы уже писали о сложностях работы с $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

Как работать с исключениями и ошибками в Powershell с Try и Catch на примерах

В Powershell существует несколько уровней ошибок и несколько способов их обработать. Проблемы одного уровня (Non-Terminating Errors) можно решить с помощью привычных для Powershell команд. Другой уровень ошибок (Terminating Errors) решается с помощью исключений (Exceptions) стандартного, для большинства языков, блока в виде Try, Catch и Finally. 

 

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

Автоматические переменные $Error

В Powershell существует множество переменных, которые создаются автоматически. Одна из таких переменных — $Error хранит в себе все ошибки за текущий сеанс PS. Например так я выведу количество ошибок и их сообщение за весь сеанс:


Get-TestTest
$Error
$Error. Count

При отсутствии каких либо ошибок мы бы получили пустой ответ, а счетчик будет равняться 0:

Переменная $Error являет массивом и мы можем по нему пройтись или обратиться по индексу что бы найти нужную ошибку:


$Error[0]

foreach ($item in $Error){$item}

Свойства объекта $Error

Так же как и все что создается в Powershell переменная $Error так же имеет свойства (дополнительную информацию) и методы. Названия свойств и методов можно увидеть через команду Get-Member:


$Error | Get-Member

Например, с помощью свойства InvocationInfo, мы можем вывести более структурный отчет об ошибки:


$Error[0].InvocationInfo

Методы объекта $Error

Например мы можем очистить логи ошибок используя clear:


$Error. clear()

Критические ошибки (Terminating Errors)

Критические (завершающие) ошибки останавливают работу скрипта. Например это может быть ошибка в названии командлета или параметра. В следующем примере команда должна была бы вернуть процессы «svchost» дважды, но из-за использования несуществующего параметра ‘—Error’ не выполнится вообще:


'svchost','svchost' | % {Get-Process -Name $PSItem} --Error 

Не критические ошибки (Non-Terminating Errors)

Не критические (не завершающие) ошибки не остановят работу скрипта полностью, но могут вывести сообщение об этом. Это могут быть ошибки не в самих командлетах Powershell, а в значениях, которые вы используете. На предыдущем примере мы можем допустить опечатку в названии процессов, но команда все равно продолжит работу:


'svchost111','svchost' | % {Get-Process -Name $PSItem}

Как видно у нас появилась информация о проблеме с первым процессом ‘svchost111’, так как его не существует. Обычный процесс ‘svchost’ он у нас вывелся корректно.

Параметр ErrorVariable

Если вы не хотите использовать автоматическую переменную $Error, то сможете определять свою переменную индивидуально для каждой команды. Эта переменная определяется в параметре ErrorVariable:


'svchost111','svchost' | % {Get-Process -Name $PSItem } -ErrorVariable my_err_var
$my_err_var

Переменная будет иметь те же свойства, что и автоматическая:


$my_err_var.InvocationInfo

 

У нас есть два способа определения последующих действий при ‘Non-Terminating Errors’. Это правило можно задать локально и глобально (в рамках сессии). Мы сможем полностью остановить работу скрипта или вообще отменить вывод ошибок.

Приоритет ошибок с $ErrorActionPreference

Еще одна встроенная переменная в Powershell $ErrorActionPreference глобально определяет что должно случится, если у нас появится обычная ошибка. По умолчанию это значение равно ‘Continue’, что значит «вывести информацию об ошибке и продолжить работу»:


$ErrorActionPreference

Если мы поменяем значение этой переменной на ‘Stop’, то поведение скриптов и команд будет аналогично критичным ошибкам. Вы можете убедиться в этом на прошлом скрипте с неверным именем процесса:


$ErrorActionPreference = 'Stop'
'svchost111','svchost' | % {Get-Process -Name $PSItem}

Т.е. скрипт был остановлен в самом начале. Значение переменной будет храниться до момента завершения сессии Powershell. При перезагрузке компьютера, например, вернется значение по умолчанию.

Ниже значение, которые мы можем установить в переменной $ErrorActionPreference:

  • Continue — вывод ошибки и продолжение работы;
  • Inquire — приостановит работу скрипта и спросит о дальнейших действиях;
  • SilentlyContinue — скрипт продолжит свою работу без вывода ошибок;
  • Stop — остановка скрипта при первой ошибке.

Самый частый параметр, который мне приходится использовать — SilentlyContinue:


$ErrorActionPreference = 'SilentlyContinue'
'svchost111','svchost' | % {Get-Process -Name $PSItem}

Использование параметра ErrorAction

Переменная $ErrorActionPreference указывает глобальный приоритет, но мы можем определить такую логику в рамках команды с параметром ErrorAction. Этот параметр имеет больший приоритет чем $ErrorActionPreference. В следующем примере, глобальная переменная определяет полную остановку скрипта, а в параметр ErrorAction говорит «не выводить ошибок и продолжить работу»:


$ErrorActionPreference = 'Stop'
'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'SilentlyContinue'}

Кроме ‘SilentlyContinue’ мы можем указывать те же параметры, что и в переменной $ErrorActionPreference.  

Значение Stop, в обоих случаях, делает ошибку критической.

 

Когда мы ожидаем получить какую-то ошибку и добавить логику нужно использовать Try и Catch. Например, если в вариантах выше мы определяли нужно ли нам отображать ошибку или останавливать скрипт, то теперь сможем изменить выполнение скрипта или команды вообще. Блок Try и Catch работает только с критическими ошибками и в случаях если $ErrorActionPreference или ErrorAction имеют значение Stop.

Например, если с помощью Powershell мы пытаемся подключиться к множеству компьютеров один из них может быть выключен — это приведет к ошибке. Так как эту ситуацию мы можем предвидеть, то мы можем обработать ее. Процесс обработки ошибок называется исключением (Exception).

Синтаксис и логика работы команды следующая:


try {
    # Пытаемся подключиться к компьютеру
}
catch [Имя исключения 1],[Имя исключения 2]{
    # Раз компьютер не доступен, сделать то-то
}
finally {
    # Блок, который выполняется в любом случае последним
}

Блок try мониторит ошибки и если она произойдет, то она добавится в переменную $Error и скрипт перейдет к блоку Catch. Так как ошибки могут быть разные (нет доступа, нет сети, блокирует правило фаервола и т.д.) то мы можем прописывать один блок Try и несколько Catch:


try {
    # Пытаемся подключится
}
catch ['Нет сети']['Блокирует фаервол']{
    # Записываем в файл
}
catch ['Нет прав на подключение']{
    # Подключаемся под другим пользователем
}

Сам блок finally — не обязательный и используется редко. Он выполняется самым последним, после try и catch и не имеет каких-то условий.

Catch для всех типов исключений

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


try {
   'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'Stop'}
}
catch {
   Write-Host "Какая-то неисправность" -ForegroundColor RED
}

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

Мы можем вывести в блоке catch текст ошибки используя $PSItem.Exception:


try {
   'svchost111','svchost' | % {Get-Process -Name $PSItem -ErrorAction 'Stop'}
}
catch {
   Write-Host "Какая-то неисправность" -ForegroundColor RED
   $PSItem.Exception
}

Переменная $PSItem хранит информацию о текущей ошибке, а глобальная переменная $Error будет хранит информацию обо всех ошибках. Так, например, я выведу одну и ту же информацию:


$Error[0].Exception

Создание отдельных исключений

Что бы обработать отдельную ошибку сначала нужно найти ее имя. Это имя можно увидеть при получении свойств и методов у значения переменной $Error:


$Error[0].Exception | Get-Member

Так же сработает и в блоке Catch с $PSItem:

Для вывода только имени можно использовать свойство FullName:


$Error[0]. Exception.GetType().FullName

Далее, это имя, мы вставляем в блок Catch:



Примеры работы с NULL в Powershell сравнение и проверка на неизвестное значение

Powershell NULL так же как и в большинстве языков обозначает пустое или неизвестное значение. Эту переменную используют для избежания ошибок, например когда мы должны быть уверены что делаем операцию с существующим значением. В других языка такое же значение несет None.

В отличие от других языков в Powershell null является переменной, обозначается как $null и хранит ссылку. 

Переменная без объявленного значения будет равна неизвестному:


$null -eq $somevar

Так же как и результат функции, которая возвращает пустое значение:


function Get-None {return (Get-Process '*notexist*')}
$null -eq (Get-None)

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

 

Проверка в строках

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


$val = $null
Write-Output "Print $val val"

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


$val = $null
$date = Get-Date
$error_log = "[$date] ErrorId [$val]"
Write-Output $error_log

 

Проверка при работе с числами

Мы можем использовать NULL и ожидать такое значение при работе с числами и не получать ошибок. В разных случаях результат будет разным:


$null -eq ($null * 7)
$null -eq (7 * $null)
$null * 7
7 * $null

 

 

Работа с массивами и индексами

Если мы объявим такую переменную и попробуем вызвать элемент по индексу, то получим ошибку:


$arr = $null
$arr[1]
  • Не удается индексировать в массив
  • Cannot index into a null array

Но если мы объявим массив и вызовем несуществующий элемент по индексу, то этой ошибки не будет:


$arr = '1','2','3'
$arr[100] -eq $null

 Но в случаях с массивами мы можем проверять вхождение:


$arr = '1','2','3',$null
$null -in $arr

 

При работе с объектами

Аналогично строкам несуществующее свойство объекта тоже будет иметь неизвестное значение:


$path = Get-ChildItem
$null -eq $path. NotExist

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


$null.GetType()
  • Невозможно вызвать метод для выражения со значением NULL
  • You cannot call a method on a null-valued expression

Для избежания таких ситуация нужно делать проверки заранее или использовать try catch.

Единственное свойство, которое можно использовать — это счетчик count:


$val = $null
$val.count
0

Исключением является использование Count в PSCustomObject. В Powershell 5.1 у такого объекта нет свойства count, а начиная с версии 6 оно есть:


$value = [PSCustomObject]@{Name='SoneObject'}
if ( $value.count -eq 1 ) {"PS 6.1"}

 

Проверки на существование значений в условиях

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


$value = @( $null )
if ( $value -eq $null ) {'Значение $null'}
if ( $value -ne $null ) {'Значение не $null'}
if ( $null -ne $value ) {'Значение не $null 2'}

Если бы мы не использовали третье условие, то результат был бы False и возможный скрипт бы не выполнился.

Операторы сравнения сильно зависят от контекста использования. В зависимости от того является ли левое значение скалярным (число или строка), или списком (массив, список и т.д.) у нас будут возвращаться разные значения. Для примера ситуация выше, но уже с числом вернет два True:

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


$a = 1
if ($a) {'ok'}

Подобное условие на самом деле выполняет следующие операции:


if ( $null -ne $a -and
     $a -ne 0 -and
     $a -ne '' -and
     $a -ne $false )
    {
        'ok'
    }

В отличие от других языков в Powershell иногда можно преобразовывать $null в другие типы. Если такое преобразование будет в рамках скрипта, то они не будут равны $null:


[int]$int = $null
$int

[string]$str = $null
$str -eq ''

В других случаях у нас могут появиться ошибки:

  • Не удается преобразовать значение «» в тип «System.Boolean».
  • Не удается преобразовать значение в тип «System.DateTime».

[bool]$bool = $null
$bool

[datetime]$date = $null

Для проверки пустой строки можно так же использовать метод .Net IsNullOrEmpty:


$null -eq ''
[string]::IsNullOrEmpty('')
[string]::IsNullOrEmpty('some')

 

Работа с конвейером и циклами

При работе с конвейером, вне зависимости от заданных параметром, всегда будет ошибка:


$null | Get-NetIPAddress
  • Get-NetIPAddress : Не удается проверить аргумент для параметра «AssociatedIPInterface». Аргумент имеет значение NULL. Укажите допусти мое значение аргумента, после чего повторите выполнение команды.
  • Get-NetIPAddress : Cannot validate argument on parameter ‘AssociatedIPInterface’. The argument is null. Provide a valid value for the

Исключения, если мы будем использовать конвейер и цикл:


$null |% {Get-NetIPAddress}

При использовании в цикле c foreach все будет пропущено:


foreach ($node in $null){Write-Output 'ok'}

А с ForEach-Object ошибка:


ForEach-Object ($node -in $null){Write-Output 'ok'}

 

Перенаправление вывода

Аналогично nix системам в Powershell тоже можно перенаправлять вывод в «никуда». Такую команду можно выполнять в стиле Powershell:


New-Item -Type Directory -Path 'C:\Folder' | Out-Null 

 Можно назначить переменную, результат будет таким же:


$null = New-Item -Type Directory -Path 'C:\Folder'

 Или использовать стиль Linux:


New-Item -Type Directory -Path 'C:\Folder' > $null 

Либо так, в случаях с потоками:


* > $null
. ..

Теги: #powershell

Условия в PowerShell « Марк и Марта.Ру. Записки отца-программиста

Условия в PowerShell


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

В отличие от многих языков программирования, в PowerShell отказались от использования символов «>», «<» или «=», заменив их выражениями –gt; -lt; -eq. Сначала идет знак «-», потом псевдокоманда eq – equal, gt – greater than, lt – less then.

Ниже в таблице приведен список базовых операторов сравнения.

Команда Значение на английском Значение на русском
-eq Equal Равно
-ne Not equal Не Равно
-ge Greater than or equal Больше или Равно
-gt Greater than Больше
-lt Less than Меньше
-le Less than or equal Меньше или Равно
-like Wildcard comparison Поиск соответствия символов по заданному образцу, аналог SQL-ного LIKE
-notlike Wildcard comparison Поиска несоответствия символов образцу
-match Regular expression comparison Поиск соответствия образцу с использованием регулярных выражений
-notmatch Regular expression comparison Поиск несоответствия образцу с использованием регулярных выражений
-replace Replace operator Заменяет часть или все значение слева от оператора. Очень своеобразный оператор
-contains Containment operator Определение, содержит ли значение слева от оператора значение справа. Возвращает $true или $false
-notcontains Containment operator Определение того, что значение слева от оператора не содержит значение справа. Возвращает $true или $false

 

$myvar = "This is an old string"
$myvar | ForEach-Object {$_ -replace "old", "new"} | Set-Content $myvar

Write-Host "Результат: " + $myvar

В результате будет выдано:

Результат:  + This is an old string

Для сравнения с учетом регистра к команде подставляется префикс «c». Для примера, оператор -eq с зависимостью от регистра изменяется на «-ceq».

Для явно заданного независящего от регистра сравнения к команде подставляется префикс «i». Пример: оператор -replace без зависимости от регистра будет -ireplace

 

Типы

-is Является типом
-isnot Не является типом
-as Как тип, без ошибки если возникает неудача преобразования

 

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

-and Оба условия должны быть истины, чтобы выражение было истинно
-or Одно или оба условия должны быть истины, чтобы выражение было истинно
-xor Одно условие должно быть истинно, а второе должно иметь значение «ложь», чтобы выражение было истинно
-not Указанные условия должны иметь значение «ложь», чтобы выражение было истинно
! Указанное условие должно иметь значение «ложь», чтобы выражение было истинно

Заметки для себя: Windows Powershell Возможности переменных

Windows Powershell Возможности переменных
Дон Джонс (Don Jones)

Если вы работаете с языками сценариев на основе Windows, такими как VBScript или KiXtart, вы знаете, что переменная это просто удобное «приспособление» для хранения данных. В языке Windows PowerShell тоже есть переменные, но они, в отличие от переменных в более старых языках сценариев, предоставляют разработчикам куда больше возможностей.

Переменные PowerShell фактически сопоставимы с основными классами платформы Microsoft® .NET Framework. А в .NET Framework переменные являются объектами, а это значит, что с данными, хранящимися в переменных, можно производить различные операции. Именно благодаря огромным функциональным возможностям переменных, в языке сценариев Windows PowerShell™ отсутствуют встроенные функции обработки данных; в них не нужды — необходимая функциональность обеспечивается самими переменными.


Объявление переменных

Для объявления переменной и присвоения ей значения можно использовать командлет New-Variable, но можно поступить проще — создать переменную и присвоить ей значение:

Имена переменных в PowerShell всегда начинаются со знака доллара ($) и могут содержать цифры, буквы, символы и даже пробелы (при использовании пробелов необходимо заключить переменную в фигурные скобки таким образом: ${My Variable} = «Hello»). В этом примере мы создали переменную с именем $var и присвоили ей значение «Hello». Поскольку в данном случае значение переменной это строка, состоящая из символов, PowerShell присвоит переменной тип String (Строковый). В терминах .NET Framework это класс System.String, обладающий, возможно, из всех типов переменных наибольшим количеством встроенных функций. Допустим, мы хотим, чтобы значение переменной $var выводилось только символами в нижнем регистре. Это можно сделать следующим образом:
PS C:\> $var.ToLower()
hello
PS C:\>
Метод ToLower встроен в класс System.String class и результатом его применения будет представление значения строковой переменной символами в нижнем регистре. При этом значение переменной $var остается неизменным. Чтобы увидеть полный список возможностей класса System.String, передайте строковую переменную командлету Get-Member:

На рис. 1 показан результат этой операции — пара десятков методов для обработки строковых переменных. Практически все возможности функций обработки строковых данных VBScript присутствуют в методах строковых переменных Windows PowerShell.

Figure 1 A look at the System.String class output (Щелкните изображение, чтобы увеличить его)


При администрировании многие возможности строковых переменных оказываются более полезными, нежели функции обработки строк в языках типа VBScript. Предположим, вы написали сценарий, считывающий из файла пути с универсальными именами (UNC) и производящий над ними какие-либо действия. Прежде чем использовать считанный путь для своих целей, необходимо убедиться, что каждый он действительно имеет универсальное имя. Метод StartsWith позволяет убедиться, что строка начинается с двойной обратной косой черты, являющейся необходимым атрибутом стандарта UNC:
PS C:\> $path = "\\Server\Share"
PS C:\> $path.StartsWith("\\")
True
PS C:\>
Поскольку метод StartsWith возвращает значения True («Истина») или False («Ложь»), он применяется в логических построениях:
if ($path. StartsWith("\\")) {
 # code goes here
}
В Windows PowerShell имеется функция автозаполнения в методах переменных, что позволяет сэкономить время, затрачиваемое на ввод с клавиатуры. Если переменная $var имеет строковое значение, введите следующее:

и затем нажмите клавишу Tab. Появится первое имя метода переменной $var. При повторном нажатии клавиши Tab появится следующий метод, а при нажатии клавиш Shift+Tab — предыдущий. Таким образом можно просмотреть все доступные методы и выбрать нужный.

Путаница

В примерах, приведенных выше, тип переменных определялся автоматически. Присваивание переменной строкового значения приводит к тому, что переменная будет принадлежать к классу System.String. Присваивание переменной численного значения, как правило, приводит к тому, что переменная будет принадлежать к классу Integer (Цело число), а точнее — Int32, классу с определенным диапазоном значений. Рассмотрим следующий пример:
PS C:\> $int = 5
PS C:\> $int | get-member

  TypeName: System. Int32

Одинокая строка на выходе — результат того, что Windows PowerShell воспринимает переменную $int как переменную класса Int32, который имеет собственный набор методов и свойств, которых, кстати, значительно меньше, чем у типа String.

Переменной $int стала переменной класса Int32, поскольку ее значение не было заключено в кавычки и состояло только из цифр. Если бы значение было заключено в кавычки, переменная была бы воспринята как переменная класса System.String.

Автоматическое определение типа переменных не всегда приводит к желаемым результатам. Допустим, вы при считывании значений из файла необходимо, чтобы они обрабатывались как строковые данные. Но некоторые значения могут состоять только из цифр, а это значит, что Windows PowerShell может обрабатывать их как переменные типа Int32 или другого численного типа. Это может привести к нежелательным последствиям, а именно: если PowerShell не распознает значение переменной как строковое, методы класса System. String недоступны (соответственно в сценарии будет использоваться один из недоступных методов).

Чтобы избежать этого, можно объявить тип переменной при ее создании. В этом случае Windows PowerShell будет обрабатывать ее как переменную объявленного типа. Приведем пример:

Переменная $var была бы переменной типа Int32, если бы мы не объявили ее переменной типа String, что позволяет применять к ней все методы класса System.String. Кроме того, объявление типа переменной придает сценарию большую наглядность, поскольку теперь у нас не возникает сомнений относительно типа данных, хранящихся в переменной $var. Я вообще взял за правило самостоятельно объявлять тип каждой переменной, отобрав право выбора у Windows PowerShell. Благодаря этому поведение моих сценариев более предсказуемо. Кроме того, я несколько раз сэкономил время при отладке

Как вы догадываетесь, принудительное объявление переменных влечет за собой различные последствия, причем не всегда плачевные. Рассмотрим пример, в котором тип переменной не объявляется:
PS C:\> $me = 5
PS C:\> $me = "Don"

Сначала переменная $me была переменной типа Int32, но Windows PowerShell изменил ее тип на String, когда было присвоено значение «Don». Windows PowerShell может изменять тип переменной по мере необходимости, в случае если тип переменной не был предварительно объявлен.

В следующем примере мы объявляем переменную $me переменной типа Int32 с помощью имени типа [int]:
PS C:\> [int]$me = 5
PS C:\> $me = "Don"
Cannot convert value "Don" to type 
"System.Int32". Error: "Input string 
was not in a correct format."
At line:1 char:4
+ $me <<<< = "Don"

Затем мы присваиваем ей строковое значение, в результате чего появляется сообщение об ошибке. Поскольку тип переменной $me был принудительно задан (Int32), Windows PowerShell попытался преобразовать строку «Don» в целое число. Это не удалось; также не удалось поменять тип переменной $me на String.

Типы переменных

В Windows PowerShell существует множество типов переменных. Более того, допустимо использование всех типов .NET Framework (количество таких типов исчисляется сотнями). Тем не менее, в Windows PowerShell имеются сокращенные имена для наиболее распространенных типов данных. На Рис. 2 приведен неполный список из 10-ти наиболее часто используемых сокращенных имен типов переменных. Полный список приведен в документации Windows PowerShell.

 Figure 2 Сокращенные имена типов переменных
Сокращенное имя Тип данных
[datetime] Время или дата
[string] Строка символов
[char] Один символ
[double] Число с плавающей запятой двойной точности
[single] Число с плавающей запятой одинарной точности
[int] Целое число, 32 бита
[wmi] Экземпляр или коллекция WMI
[adsi] объект служб Active Directory
[wmiclass] класс WMI
[Boolean] значения «Истина» или «Ложь»
Кроме того, вы можете объявлять тип переменных, используя полное имя класса . NET Framework, например:

Такой метод позволяет использовать типы .NET Framework, не имеющие сокращенных имен в Windows PowerShell.

Расширение типов

Расширение функций типов переменных — возможно, самая потрясающая особенность Windows PowerShell. В папке установки Windows PowerShell (как правило, расположенной в %systemroot\system32\windowspowershell\v1.0, но 64-битных системах ее расположение будет несколько иным) находится файл types.ps1xml. Этот файл можно редактировать в Блокноте или в XML-редакторе, например в PrimalScript. По умолчанию класса System.String в файле нет, несмотря на присутствие множества других типов переменных. Тем не менее, мы можем добавить новую функцию типу System.String, внеся его в файл types.ps1xml.

Чтобы изменения вступили в силу, необходимо закрыть и заново открыть Windows PowerShell. Также необходимо убедиться, что локальная политика выполнения сценариев допускает выполнение сценариев без подписи, поскольку мы не подписали файл types. ps1xml:
Set-executionpolicy remotesigned
Теперь, перезапустив Windows PowerShell, мы можем воспользоваться новыми функциями, например:
PS C:\> [string]$comp = "localhost"
PS C:\> $comp.canping
True
PS C:\>

Как видите, мы добавили свойство CanPing в класс System.String. На выходе мы получим True («Истина») или False («Ложь»), т.е. может ли локальный компьютер установить связь по адресу, содержащемуся в строке. На Рис. 3 мы видим, что в запросе WMI используется специальная переменная $this. В этой переменной содержится текущее значение строки и способ передачи содержимого строки в запрос WMI.

 Figure 3 Расширение типа System.String
<Type>
  <Name>System.String</Name>
  <Members>
    <ScriptProperty>
      <Name>CanPing</Name>
      <GetScriptBlock>
      $wmi = get-wmiobject -query "SELECT *
FROM Win32_PingStatus WHERE Address = '$this'"
      if ($wmi. StatusCode -eq 0) {
        $true
      } else {
        $false
      }
      </GetScriptBlock>
    </ScriptProperty>
  </Members>
</Type>

Заключение

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

Как с помощью PowerShell завершать процессы в Windows 10

Завершить в принудительном режиме зависший или ненужный процесс в Windows можно несколькими способами — с помощью Диспетчера задач, командной строки, сторонних утилит вроде Process Explorer. Также это можно сделать с помощью оболочки PowerShell — более совершенного аналога командной строки CMD, которая в будущем должна будет заменить собою последнюю.

Для завершения процессов в PowerShell предусмотрен отдельный командлет Stop-Process, позволяющий «убивать» один или несколько процессов сразу. Способов завершения процесса в PowerShell два — через идентификатор процесса и через его имя, используйте какой вам удобнее. Относящийся к первому способу командлет имеет такой синтаксис:

Stop-Process id_process

Где id_process — идентификатор процесса.

Для получения списка ID активных процессов используется командлет Get-Process. Допустим, вы хотите завершить зависший браузер Edge. Выполните в PowerShell команду Get-Process и посмотрите, какой ID имеет процесс MicrosoftEdge.

В данном примере это 2196. Следовательно, команда завершения будет такой:

Stop-Process 2196

Выполните её и работа Edge будет немедленно завершена.

Вместо идентификатора можно использовать имя процесса, только в этом случае потребуется указать ключ –processname. Вот так:

Stop-Process -processname MicrosoftEdge

Результат будет точно таким же.

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

Stop-Process -processname MicrosoftEdge, regedit

Вышеприведённая команда завершит работу сразу двух программ — браузера Edge и редактора реестра.

Тут, пожалуй, стоит сказать о некоторой особенности командлета Stop-Process. Если с его помощью вы попробуете завершить работу Проводника, то последний будет перезапущен, а не закрыт.

И последнее.

Завершать зависшие или неправильно работающие процессы лучше в PowerShell, запущенном от имени администратора, так как некоторые процессы требуют повышенных привилегий.

PowerShell Basics: If -Not Conditional Operator & Logic

Введение в If-Not Logic в Windows PowerShell

После того, как вы освоите базовый оператор If, вам просто нужно научиться расширять логику, чтобы охватить Синтаксис PowerShell «Если не равно».

Темы для PowerShell. Условный оператор If в PowerShell

Построение оператора PowerShell «If»

Давайте начнем с изучения логики «If» PowerShell.Секрет состоит в том, чтобы идентифицировать две части конструкции: (условие проверки) и {команду блока}.

Это помогает следить за различными типами скоб PowerShell. (Стиль круглых скобок используется для первой части, а именно для условия), в то время как {фигурные скобки обозначают полезную нагрузку команды блока}.

 
Если (условие) {Блокировать команду}
  

Вот альтернативное объяснение того же управления потоком «Если»:

 
Если (тест) {выполнить, когда истина}
  

Описание: PowerShell «If» условно выполняет оператор блока, при условии, что тестовое выражение истинно.

Пример 1: Базовый оператор «Если»

Думайте об этом сценарии как о преамбуле, которая проверяет, установлена ​​ли на вашем компьютере служба предупреждений, и вводит базовый оператор «Если». Здесь нет -Not сравнения, как в примере 2.

 
# Сценарий PowerShell для проверки, установлена ​​ли служба
$ SrvName = "Оповещатель"
$ Service = Get-Service -display $ SrvName -ErrorAction SilentlyContinue
Если ($ Service) {$ SrvName + "установлен на этом компьютере."}
Иначе {"Служба No Alerter указывает на Windows 7 или Server 2008"}
  

Очки обучения

Примечание 1: Если (тест) просто так: может Get-Service найти $ SrvName.Попробуйте изменить «Оповещение» на «Диспетчер очереди печати».

Примечание 2: Избегайте чрезмерных размышлений; в инструкции «If» PowerShell нет «Then». Кроме того, в PowerShell нет endif, как в VBScript.

Пример 2: PowerShell If — не условный оператор

Целью этого сценария является проверка службы предупреждений, причина в том, что компьютеры Windows 7 больше не устанавливают службу предупреждений.

Обратите внимание, как -Not меняет логику «Если» на противоположную по сравнению с Примером 1.

 
# Сценарий PowerShell для проверки того, что служба НЕ установлена
$ SrvName = "Оповещатель"
$ Service = Get-Service -display $ SrvName -ErrorAction SilentlyContinue
Если ( -Не  $ Service) {$ SrvName + "не установлен на этом компьютере"}
Иначе {"Вероятно, у вас есть $ SrvName, значит машина Vista или W2K3"}
  

Примечание 3: Условный оператор -Not имеет псевдоним! Это всего лишь пример псевдонима для оператора PowerShell.

Гай рекомендует: бесплатный WMI Monitor для PowerShell (БЕСПЛАТНЫЙ ИНСТРУМЕНТ)

Windows Management Ins

Основы PowerShell: если — не условный оператор и логика

Введение в PowerShell’s If -Or Logic

Самый простой Чтобы понять конструкцию «Если -ИЛИ» в PowerShell, нужно освоить базовую конструкцию «Если» и добавить в тест «-ИЛИ» вторую часть логики.

Темы для условного оператора If -Or в PowerShell

Базовое заявление PowerShell «If»

Давайте начнем с освоения конструкции «If» в PowerShell. Сосредоточьтесь на двух частях конструкции: (тест) и {команда блока}.

Это помогает следить за различными типами скоб PowerShell. (Стиль круглых скобок используется для первой части, а именно для условия), а {фигурные скобки — для полезной нагрузки команды блока}.

 If (условие) {Do stuff} 

Вот другое объяснение того же управления потоком «If»:

 If (test) {execute when true}
 

Описание: PowerShell «If» условно выполняет оператор блока, при условии, что тестовое выражение истинно.

PowerShell Заявление «If -or»

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

 If (test1  -Or  test2) {выполнить, когда истина}
 

Пример 1. Базовый синтаксис «If» PowerShell

Целью этого сценария является проверка базовой команды «If». Часовой транспорт — это начальное значение для службы диспетчера очереди печати. Если установлено значение «Вручную», сценарий изменяет его на «Автоматически».

 # Сценарий PowerShell для изменения запуска на автоматический
Clear-Host
$ NameSrv = 'Спулер'
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
  Если  ($ Service.Startmode -eq "Manual") {
Set-Service $ NameSrv -startuptype Автоматический}
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
$ Сервис | Имя Ft, режим запуска -AutoSize
 

Очки обучения

Примечание 1: В основе этого примера лежит тест ($ Service.Startmode -eq «Manual») и команда блока {Set-Service $ NameSrv -startuptype Automatic}

Примечание 2 : Протестируйте сценарий, изменив тип запуска диспетчера очереди печати на «Вручную».Либо вручную из Services. msc, либо с помощью этой команды PowerShell:

 Set-Service Spooler -startupType manual
 

Гай рекомендует: бесплатный монитор WMI для PowerShell (БЕСПЛАТНЫЙ ИНСТРУМЕНТ)

Инструментарий управления Windows (WMI) — одно из скрытых сокровищ операционных систем Microsoft. К счастью, компания SolarWinds создала бесплатный монитор WMI для PowerShell , чтобы вы могли обнаружить эти жемчужины информации о производительности и, таким образом, улучшить свои сценарии PowerShell.

Не гадайте, какие счетчики WMI использовать при написании сценариев для операционной системы, Active Directory или Exchange Server. Попробуйте этот монитор WMI — это бесплатно.

SolarWinds WMI Monitor Загрузить 100% бесплатный инструмент

Пример 2: PowerShell If -Or Conitional Operator

Проблема с написанием сценария возникает, когда вы учитываете вполне реальную возможность, что служба установлена ​​на «Вручную», или на » Инвалид’. Вы можете решить эту проблему в PowerShell с помощью ElseIf, в качестве альтернативы, как в этом примере ниже, вы можете использовать -Or.

 Clear-Host
$ NameSrv = 'Спулер'
If ($ Service.Startmode -eq "Manual"  -Or  $ Service.Startmode -eq "Disabled") {
Set-Service $ NameSrv -startuptype Автоматический}
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
$ Сервис | Имя Ft, режим запуска -AutoSize
 

Примечание 3: Проверьте логику каждой строки. -eq — это способ PowerShell говорить о равенстве; узнайте, когда использовать -eq, а когда использовать знак (=).

Примечание 4: Преимущество использования -Or, а не ElseIf заключается в написании более жесткого кода.Эта реализация побудит вас поместить -Или в круглые скобки (тест), а не создавать дополнительную строку с новым логическим условием.

Пример 3: PowerShell -Или рабочий пример

Хотя этот сценарий разработан для проверки крошечного синтаксиса «-Или», в нем много постороннего кода, который меняет значение startupType на manual. Единственная цель этого запутанного макета состоит в том, чтобы вы могли изменять биты для двойной проверки логики и понимать, как -Or работает в PowerShell.

 Clear-Host
$ NameSrv = 'Спулер'
Set-Service $ NameSrv -startupType руководство
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
$ Сервис | Имя Ft, режим запуска
if ($ Service.Startmode -eq "Manual"  -Or  $ Service.Startmode -eq "Disabled") {
Set-Service $ NameSrv -startuptype Автоматический}
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
$ Сервис | Имя Ft, режим запуска
 

Рабочий сценарий:

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

 $ Service = Get-WmiObject win32_service -filter "NAME = 'Spooler'"
if ($ Service.Startmode -eq "Manual"  -Or  $ Service.Startmode -eq "Disabled") {
Set-Service 'Spooler' -startuptype Автоматический}
  Start-Service "Спулер" 
 

Примечание 5: Всегда трудно найти баланс между примерами сценариев, которые иллюстрируют точку, и теми, которые выполняют полезную работу.

Guy рекомендует: Network Performance Monitor (БЕСПЛАТНЫЙ ПРОБНЫЙ ПЕРИОД)

SolarWinds Network Performance Monitor ( NPM) поможет вам узнать, что происходит в вашей сети.Эта утилита также поможет вам в устранении неполадок; на приборной панели будет указано, является ли основная причина неисправной ссылкой, неисправным оборудованием или перегрузкой ресурсов.

Что мне больше всего нравится, так это то, как NPM предлагает решения сетевых проблем. Он также имеет возможность отслеживать состояние отдельных виртуальных машин VMware. Если вы заинтересованы в устранении неполадок и создании сетевых карт, я рекомендую вам попробовать NPM в 30-дневной бесплатной пробной версии.

SolarWinds Network Performance Monitor Загрузить 30-дневную БЕСПЛАТНУЮ пробную версию

Несколько PowerShell -Или условий

Если управление потоком работает с одним -Или, относительно просто добавить несколько -или условий. Просто помните, что вам нужен только один набор (скобок).

Пример 4: PowerShell If -And Script

PowerShell -И следует той же логике и построению, что и -Or

Цель этого сценария — просто проверить разные даты и сравнить их с сегодняшней датой, которая хранится в переменной $ Календарь.

 Clear-Host
$ Calendar = Get-Date
If ($ Calendar.day -eq '24'  -And  $ Calendar.Month -eq '12') {"Рождество"}
ElseIf ($ Calendar.day -eq '4'  -And  $ Calendar.Month -eq '7') {"4 июля"}
Else {"Сегодня не Рождество и не 4 июля"}
 

Примечание 4: Обратите особое внимание на (первую скобку). В частности, найдите два теста .day -eq ’24’, а также .Month -eq ’12. Мое первое замечание: они разделены -И. Мое второе замечание: существует только один набор (скобок условий).

Примечание 5: Я включил несколько ElseIfs и последний оператор Else, чтобы дать сценарию немного больше контекста и дать вам идеи для ваших сценариев.

Пример 5: PowerShell ElseIf

Хотя решение PowerShell -или более элегантно, вместо него можно использовать ElseIf.

 Clear-Host
$ NameSrv = 'Спулер'
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
if ($ Service.Startmode -eq "Manual") {Set-Service $ NameSrv -startuptype Automatic}
  ElseIf  ($ Service.Startmode -eq "Disabled") {Set-Service $ NameSrv -startuptype Automatic}
$ Service = Get-WmiObject win32_service -filter "NAME = '$ NameSrv'"
$ Сервис | Имя Ft, Startmode -auto
 

Researching PowerShell’s Else If Logic

Дополнительные сведения см. Во встроенном в PowerShell файле About_IF

 Get-Help About_If
 

Дополнительная справка по файлам About_ PowerShell »

Сводка по конструкции If -Or в PowerShell

После того, как вы освоили базовый оператор If, вы можете расширить его возможности с помощью If -Or.Это конструкция, альтернативная «ElseIf». Секрет понимания реализации If -Or в PowerShell заключается в том, чтобы уделять пристальное внимание скобкам. (test1 -or test2), затем {фигурные скобки для блока сценария}.

Основы PowerShell: операторы If -And & If -Or

Введение в Windows PowerShell Заявление If -And

Одним из лучших операторов для фильтрации данных является предложение «If». Для скриптов, требующих точного управления потоком, вы можете включить PowerShell -И, преимущество в том, что ваш тест теперь может включать несколько условий.

Темы для PowerShell If -And Заявление

Введение в PowerShell «If» и утверждение

Ключевым моментом является то, что вам нужен только один «If».

 
If (condition1  -And  condition2) {Что делать}
# Альтернативное объяснение было бы

Если (test1  -And  test2) {
выполнить команду блока, когда истина
}
  

Описание: PowerShell «If» условно выполняет операторы, в зависимости от истинности тестового выражения.

Пример 1: базовый тест «If»

Если вы новичок в реализации оператора If в PowerShell, то перед добавлением -And. Стоит начать с простого элемента управления потоком «If».

 
$ Calendar = Get-Date
If ($ Calendar.Month -eq '5') {"В этом месяце май"}
Else {"Not May"}
  

Очки обучения

Примечание 1: Проследите конструкцию и разделите ее на два компонента: if (тест) и {что делать}.

Примечание 2: Избегайте чрезмерного обдумывания; в инструкции «If» PowerShell нет «Then».Мой совет: вместо того, чтобы беспокоиться о «Тогда», обратите особое внимание на два типа скобок. Кроме того, в PowerShell нет endif, как в VBScript.

Примечание 3: Чтобы еще раз проверить свое понимание, попробуйте изменить $ Calendar.Month -eq ‘5’ на другое число, например ’12’. Как только вы это сделаете, измените: Else {что-то другое}.

Пример 2: PowerShell If -And Script

Цель этого сценария — просто проверить разные даты и сравнить их с сегодняшней датой, которая содержится в переменной $ Calendar.

 
# PowerShell Простой пример инструкции If AND
Clear-Host
$ Calendar = Get-Date
If ($ Calendar. Day -eq '25'  -And  $ Calendar.Month -eq '12') {
"Рождество"
}
Else {
«Еще не Рождество!» + $ Calendar.Month + "/" + $ Calendar.Day
}
  

Множественные -И условия

Как только ваш контроль потока работает с одним -И, просто (если немного неуклюже) добавить больше -И условий. Избегайте чрезмерного обдумывания, вам нужен только один набор (скобок).

Вот дополнительный пример с еще несколькими операторами, содержащими -And

 
Clear-Host
$ Calendar = Get-Date
If ($ Calendar.day -eq '25'  -And  $ Calendar.Month -eq '12') {"Рождество"}
ElseIf ($ Calendar.day -eq '4'  -And  $ Calendar.Month -eq '7') {"4 июля"}
ElseIf ($ Calendar.day -eq '1'  -And  $ Calendar.Month -eq '5') {"Первомайский день"}
Else {"Сегодня не Рождество!"}
  

Примечание 4: Обратите особое внимание на (первую скобку).В частности, найдите два теста: «.day -eq’ 25 ’«, а также «.Month -eq’ 12 ’». Мое первое замечание: они разделены -И. Мое второе замечание: существует только один набор (скобок условий).

Примечание 5: Я включил несколько ElseIf и последний оператор Else, чтобы получить

PowerShell, если нет | Блог Ричарда Сиддэуэя

Когда вы используете оператор if, вы обычно проверяете положительный результат, так как же сделать PowerShell, если не

Есть несколько сценариев.Самый простой — если вы тестируете логическое значение:

PS> $ x = $ true

if ($ x) {‘Yes’} else {‘No’}
Да

В операторе if тест ($ x) оценивается и должен дать верный или ложный ответ. Если верно, то да, иначе нет

Давайте превратим тест в не тест. Ты можешь использовать ! или –не как вы предпочитаете

PS> $ x = $ true

if (! $ X) {«Да»} else {«Нет»}
if (-not $ x) {«Да»} else {«Нет»}
Нет
Нет

Если значение уже ложно

PS> $ x = $ ложь

if (! $ X) {«Да»} else {«Нет»}
if (-not $ x) {«Да»} else {«Нет»}
Да
Да

Будьте осторожны, так как вы попадаете в зону двойного отрицания, что всегда является головной болью, когда вы приходите пересматривать код в какой-то момент в будущем.

Если вы имеете дело с числовыми значениями

PS> $ x = 5

if ($ x -ne 5) {‘Да’} else {‘Нет’}
if ($ x -lt 5) {‘Да’} else {‘Нет’}
if ($ x -gt 5) { «Да»} else {«Нет»}
Нет
Нет
Нет

Будьте осторожны с первым, так как вы получите «Да», только если $ x –ne 5. Вернитесь к двойному негативному мышлению.

Обратите внимание, что это невозможно

if ($ x -not -lt 5) {‘Yes’} else {‘No’}

Двойные операторы не работают. Вы получаете ошибку около

В строке: 1 символ: 8
+ if ($ x -not -lt 5) {‘Yes’} else {‘No’}
+ ~~~~
Неожиданный токен ‘-not’ в выражении или инструкции.
В строке: 1 символ: 8

между прочим.

Нули могут быть хитрыми

PS> $ x = $ null

if ($ x) {«Да»} else {«Нет»}
if (! $ x) {«Да»} else {«Нет»}

Нет
Да

Нулевое значение будет оцениваться как ложное, если только вы — не это — другая двойная отрицательная ситуация.

Использование if not относительно просто. Просто убедитесь, что у вас есть продуманная логика, чтобы правильно справляться с двойным негативом.

Нравится:

Нравится Загрузка…

Связанные

Эта запись была размещена в Powershell. Добавьте в закладки постоянную ссылку.

Powershell, если еще ИЛИ Условная логика

Учебное пособие по Poweshell в Интернете