Режим аргументов
При анализе PowerShell сначала интерпретирует входные данные как выражение. Но при обнаружении вызова команды синтаксический анализ продолжается в режиме аргументов.
Если у вас есть аргументы, содержащие пробелы, например пути, эти значения аргументов необходимо заключить в кавычки.
Режим аргументов предназначен для анализа аргументов и параметров для команд в среде оболочки. Все входные данные рассматриваются как расширяемая строка, если в ней не используется один из следующих синтаксисов:
-
Знак доллара (), за которым следует имя переменной, начинает ссылку на переменную, в противном случае она интерпретируется как часть расширяемой строки. Ссылка на переменную может включать доступ к членам или индексирование.
- Дополнительные символы, следующие за простыми ссылками на переменные, например , считаются частью одного и того же аргумента. Заключите имя переменной в фигурные скобки (), чтобы отделить его от последующих символов. Например, .
- Если ссылка на переменную включает доступ к члену, первый из дополнительных символов считается началом нового аргумента. Например, приводит к двум аргументам: значение и строковый литерал .
-
Кавычки ( и ) начинают строки
-
Фигурные скобки () начинают новые блоки скрипта
-
Запятые () представляют списки, передаваемые в виде массивов, за исключением случаев, когда вызываемая команда является собственным приложением. В этом случае они интерпретируются как часть расширяемой строки. Начальные, последовательные или конечные запятые не поддерживаются.
-
Круглые скобки () начинают новое выражение
-
Оператор subexpression () начинает внедренное выражение
-
Начальный при знаке () начинает синтаксис выражений, например splatting (), массивы () и литералы хэш-таблицы ().
-
, и в начале маркера создают новый контекст анализа, который может содержать выражения или вложенные команды.
- Если за ними следуют дополнительные символы, первый дополнительный символ считается началом нового отдельного аргумента.
- Если перед ним неквалированный литерал работает как расширяемая строка, начинается новый аргумент, который является выражением, и принимается как литерал с началом нового аргумента, являющегося выражением.
-
Все остальное обрабатывается как расширяемая строка, за исключением метасимвы, которые по-прежнему нуждаются в экранировании.
Метасимвосимы режима аргументов (символы со специальным синтаксическим значением ‘ » ` , ; ( ) { } | & @ #): . Из них @ # являются специальными только в начале маркера.
-
Маркер остановки анализа () изменяет интерпретацию всех оставшихся аргументов. Дополнительные сведения см. в разделе ниже.
Примеры
В следующей таблице приведено несколько примеров маркеров, обработанных в режиме выражения и режиме аргументов, а также приведена оценка этих маркеров. В этих примерах значение переменной равно .
Пример | Режим | Результат |
---|---|---|
Выражение | 2 (целое число) | |
Expression | «2» (команда) | |
Expression | 2 (целое число) | |
Expression | 4 (целое число) | |
Аргумент | «2+2» (строка) | |
Expression | 4 (целое число) | |
Expression | 4 (целое число) | |
Expression | 4 (целое число) | |
Expression | 6 (целое число) | |
Аргумент | «4+2» (строка) | |
Аргумент | «$-» (команда) | |
Аргумент | «$-» (строка) | |
Expression | «a$a» (команда) | |
Аргумент | «a4» (строка) | |
Expression | «a$a» (команда) | |
Аргумент | «a$a» (строка) | |
Expression | «a$a» (команда) | |
Аргумент | «a4» (строка) | |
Expression | «a$(2)» (команда) | |
Аргумент | «a2» (строка) |
Каждый токен можно интерпретировать как тип объекта, например Boolean или String. PowerShell пытается определить тип объекта из выражения. Тип объекта зависит от типа параметра, ожидаемого командой, и от того, знает ли PowerShell, как преобразовать аргумент в правильный тип. В следующей таблице показано несколько примеров типов, назначенных значениям, возвращаемым выражениями.
Пример | Режим | Результат |
---|---|---|
— аргумент | «!1» (строка) | |
expression | False (логическое значение) | |
expression | 2 (целое число) | |
— аргумент | «A», «B» (массив) | |
— аргумент | «A,B» (строка) | |
expression | «A B» (массив) | |
— аргумент | «:A B» (строка) |
Операторы сравнения
Когда нам нужно проверить не только существование значения, но и эквивалентность или упоминание, нам нужно использовать операторы сравнения.
-eq проверка эквивалентности
С помощью оператора -eq можно проверить полное соответствие между значениями. Для примера это может быть строка или число:
Если бы значения не совпадали, то результат был бы False и условие было бы не выполненным. Проведем пример со всеми условиями:
Powershell, по умолчанию, не является зависимым от регистра. Это значит, что «Строка» и «строка» будут эквивалентны друг другу. Что бы проверить равенство с учетом регистра нужно использовать -ceq:
Самые первые примеры, которые были показаны выше, являются сокращенным вариантом написания с оператором -eq:
Важно понять работу следующего примера:
Так как проверка на эквивалентность $false правдива, результат работы условия будет True.
-ne или не соответствие
Когда нужно проверить отсутствие конкретного значения используется команда -ne:
Как уже писалось выше, если первое условие возвращает True второе выполняться не будет:
Так же как и в предыдущем случае если оператор учета регистра -cne.
Для примера так мы запустим сервис, если он не равен Running:
-gt -ge -lt -le проверка на большее и меньшее значение
Аналогично предыдущим примерам мы можем включать проверку на большее и меньшее значение, для примера выполним такое условие:
Дословно операторы выше переводятся как Less than (меньше чем) и Gt (больше чем) и именно поэтому выполняется условие else. Другие операторы, включающие букву ‘e’ вместо ‘t’ выполняют так же проверку на равенство, например ge — Greater or equal (больше или равно). Таких операторов достаточно много:
- gt — больше чем;
- cgt — больше чем, но с учетом регистра;
- ge — больше или равно;
- cge — больше или равно с учетом регистра;
- lt — меньше чем;
- clt — меньше чем, но с учетом регистра;
- le — меньше чем или равно;
- cle — меньше чем или равно с учетом регистра.
Не совсем ясно зачем делать учет регистра в определении количества, но такая возможность тоже есть.
-like проверка вхождений
В Powershell есть возможность проверки вхождений используя -like и определенный синтаксис:
- ? — обозначение единственного пропущенного символа;
- * — обозначение любого количества пропущенных символов.
Выше мы проверяли начинается ли строка с символов AD. Если бы мы искали конец строки нужно было указывать символ * до последнего элемента:
Варианты использования:
- like — поиск вхождения, не чувствителен к регистру;
- clike — поиск вхождения, чувствителен к регистру;
- notlike — проверка на отсутствие вхождения, не чувствителен к регистру;
- cnotlike — проверка на отсутствие вхождения, чувствителен к регистру.
-match использование регулярных выражений
Для проверки с использованием регулярных выражений есть свой оператор -match. Конечно, синтаксис в использовании регулярных выражений и -like отличается:
Если не указывать маску/шаблон, то match будет искать по полному совпадению:
Так же есть несколько вариантов использования регулярных выражений:
- match — регулярные выражения не чувствительные к регистру:
- cmatch — чувствительные к регистру;
- notmatch — поиск не совпадающих, не чувствительных к регистру значений;
- cnotmatch — поиск не совпадающих, чувствительных к регистру значений.
-is проверка типов
Часто бывает необходимость проверить тип данных перед дальнейшем использованием. Использование сложения со строкой и числом приводит к разным последствиям. Для избежания этих проблем нужно проверять типы. На примере ниже я проверяю является ли значение числом:
Таких типов данных в Powershell около 13:
- — строка;
- — 16-битовая строка Unicode;
- — 8 битовый символ;
- — целое 32 битовое число;
- — целое 64 битовое число;
- — булево значение True/False;
- — 128 битовое число с плавающей точкой;
- — 32 битовое число с плавающей точкой;
- — 64 битовое число с плавающей точкой;
- — тип данных даты и времени;
- — объект xml;
- — массив;
- — хэш таблица.
Так же можно использовать ключ -isnot, который выполняет противоположные действия.
Escape (‘e)
Примечание
Этот специальный символ был добавлен в PowerShell 6.0.
Escape-символ () чаще всего используется для указания последовательности виртуальных терминалов (escape-последовательность ANSI), которая изменяет цвет текста и других текстовых атрибутов, таких как полужирное и подчеркивание. Эти последовательности также можно использовать для позиционирования курсора и прокрутки. Узел PowerShell должен поддерживать последовательности виртуальных терминалов. Логическое значение можно проверить, поддерживаются ли эти последовательности ANSI.
Дополнительные сведения о escape-последовательностях ANSI см. в ANSI_escape_code.
В следующем примере выводится текст с зеленым цветом переднего плана.
Проверка позиций и зависимостей
Если нужно найти слово рядом с другим, то мы можем это сделать с помощью специальных символов:
- (?=Слово) — поиск слова слева;
- (?<=Слово) — поиск слова справа;
- (?!Слово) — не совпадает со словом слева;
- (?<!Слово) — не совпадает со словом слева.
Для примера мы знаем, что после слова ‘зарплату’ будут идти числа и мы хотим узнать их:
Шаблон выше обозначает:
- (?<=зарплата) — поиск слова справа от ‘зарплата’;
- \s — затем содержится символ пробела;
- \w+ — содержится число или буква один или множество раз;
- \b — слово закачивается.
Аналогичное можно сделать и со словом ‘руб’:
В этом шаблоне:
- \d+ — говорит, что у нас есть число повторяющееся один или более раз;
- \s — после числа следует пробел;
- (?=руб) — после пробела находится слово ‘руб’.
Остальные варианты нужны, когда вам нужно исключить совпадения по определенному значению.
Интерпретация расширяемых строк
Развернутые строки не обязательно выглядят так же, как выходные данные по умолчанию, отображаемые в консоли.
Коллекции, включая массивы, преобразуются в строки путем размещения одного пробела между строковыми представлениями элементов. Другой разделитель можно указать, задав переменную предпочтения. Дополнительные сведения см. в .
Экземпляры любого другого типа преобразуются в строки путем вызова метода, который не может дать понятное представление. Пример:
Чтобы получить те же выходные данные, что и в консоли, используйте подэкспрессию, в которой выполняется передача данных. Примените метод, если вы хотите удалить все начальные и конечные пустые строки.
Условия в массивах
Когда мы работаем с коллекциями, массивами или листами проверка вхождений работает немного иначе чем в предыдущих примерах
Тут важно учитывать не только порядок, но и логику:
Этот пример так же будет работать с логическими операторами:
Обратите внимание, что в случае с -ne, который ищет неравенство, результат будет True если хотя бы одно число и строка не совпадает с указанной:
Когда используются операторы типа ge, lt и другие, результат будет True если хотя бы одно из значений будет больше:
Для поиска вхождений в массивах обычно используются операторы описанные далее.
-contains
При использовании contains у нас возвращаются булевы значения True и False и является более логичным для проверки массивов:
Другие варианты использования:
- contains — без учета регистра;
- ccontains — с учетом регистра;
- notcontains — отсутствие значения без учета регистра;
- cnotcontains — отсутствие значение с учетом регистра.
-in
Этот оператор создан для удобства людей, которые пишут на других языках. Он отличается от contains порядком проверяемых значений. В этом случае массив должен находиться справа:
Доступные варианты:
- in — регистр не имеет значения;
- cin — регистр имеет значение;
- notin — отсутствие вхождения, регистр не имеет значения;
- cnotin — отсутствие вхождения, регистр имеет значения.
Больше примеров можно увидеть в статье Работа с массивом в Powershell и листами на примерах.
Как экранировать содержимое динамической переменной в PowerShell?
ТЛ; др
-
Ваша команда должна работать — кроме случаев, когда содержит символы «.
Напротив, $ chars. Не должно быть проблемой.
-
Ваш метод , т. Е. Явные встроенные двойные кавычки, также правильно обрабатывает значения со встроенными пробелами , в отличие от метода (также), предложенного в полезном ответе Билла Стюарта .
Вы можете упростить команду, опуская внешнюю кавычку «…» , как это также предлагается в ответе Билла: /pass:`»$password`»
-
Что касается поддержки chars. В значениях: даже -экранирование их не всегда работает, а именно, когда также используются пробелы — см. Подробности ниже.
Ваша команда передает любые символы встроенные в значение в целевую программу как есть.
Поэтому, если есть проблема, подразумевается, что ваша целевая программа — — интерпретирует символы , но обратите внимание, что документы не упоминают об этом. Однако, если это действительно так, вам придется экранировать символы как того требует целевая программа , чтобы передать их буквально
Предостережение: есть фундаментальное ограничение , однако:
Команды обычно ломаются, если значение аргумента содержит пробелы И встроенные символы , независимо от того, правильно ли они экранированы для целевой программы или нет.
Как правило, вы бы избегали value-internal as чтобы не разрывать заключенную в кавычки значение:
Замечания:* Выход из встроенного как не является стандартом как таковым, но он признается большинством внешних программ;единственные заметные исключения — командные файлы — подробности смотрите в этом ответе .* Возможно, PowerShell должен обрабатывать это экранирование автоматически — подробности смотрите в этом выпуске GitHub .
Если Windows PowerShell считает, что она не может передать полученный токен как есть в качестве одного аргумента целевой программе, она слепо применяет двойные кавычки вокруг всего токена , что в сочетании с экранированным символом может привести к неверному синтаксису :
Например, если буквально содержит , PowerShell заканчивает тем, что пропускает следующее за кулисами, используя команду выше:
То есть результирующий буквенный токен, который видел PowerShell — — был слепо заключен в двойные кавычки , в целом , даже если большинство целевых программ будет правильно анализировать как -является. В результате явно предоставленная двойная кавычка становится недействительной (так как для этого потребуется другой уровень экранирования) — и если не использовать , символ остановки анализа, который затем ограничивает вас литералами (или -стильные ссылки на переменные окружения), пути к этому нет.
Если целевая программа распознает аргумент, если он заключен в двойные кавычки в целом (например, вместо ), вы можете опустить явные двойные кавычки вокруг значения аргумента
Однако обратите внимание, что некоторые целевые программы, включая , не распознают аргумент, если он заключен в двойные кавычки в целом
С буквально содержащим , PowerShell затем проходит за кулисы:
Это синтаксически допустимо — для целевых программ, которые распознают как экранированный , что является нормой — но, как уже говорилось, тот факт, что весь аргумент заключен в «» … «, а не только значение, может не поддерживаться целевой программой.
Windows PowerShell игнорирует все -экранирование в результирующем токене и считает, что все встроенные имеют синтаксическую функцию: с этой точки зрения, если токен не состоит из какого-либо соединения строк, соединенных в кавычки и заключенных в двойные кавычки, включая двойные Цитирование применяется вслепую — что может нарушить команду.Такое поведение не только неясно, оно предотвращает надежную и предсказуемую передачу параметров.Ядро PowerShell теперь распознает как экранированные; однако цитаты, которые не экранированы как прежнему приводят к неправильным кавычкам;например, передается как , которые целевые программы анализируют как 2 аргумента, и (после удаления кавычек).
Условия
Самих условий может быть несколько. Каждый будет разобран дальше.
If
Этот оператор работает самый первый из блока условий и является обязательным в случае любых условий. Когда мы хотим проверить само существование значение достаточно указать переменную:
Результат любого сравнение приравнивается к 2 булевым значениям — это True (правда, существует) и False (ложь, не существует, $None). Если вы передаете переменную в условие без каких либо дополнительных операторов, то само существование значения у переменной позволяет выполнить следующую часть и написать «Условие выполнено». Та часть, которая экранируется в фигурные скобки называется ScriptBlock.
На следующем примере, в первом случае у нас вернется True, так как значение у переменной существует. Во втором случае мы проверяем переменную, которая не хранит никаких значений (она не была объявлена), а значит соответствует $null и вернет False:
Else
Этот оператор не является обязательным. Else используется когда результаты предыдущих проверок равен Fasle:
Обратите внимание, что я использую 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. Переписав предыдущий пример, но с новым оператором, условие будет выглядеть так:
В отличие от других операторов elseif может использоваться множество раз. Тот оператор, который первый вернет True, отменит выполнение следующих условий.
Вам так же будет интересно:
Строки с двойными кавычками
Строка, заключенная в двойные кавычки, является расширяемой строкой. Имена переменных, предшествующих знаку доллара (), заменяются значением переменной до того, как строка передается команде для обработки.
Пример:
Выходные данные этой команды:
Кроме того, в строке с двойными кавычками вычисляются выражения, а результат вставляется в строку. Пример:
Выходные данные этой команды:
В расширяемую строку можно напрямую внедрить только простые ссылки на переменные. Ссылки на переменные, использующие индексирование массивов или доступ к членам, должны быть заключены в вложенное выражение. Пример:
Чтобы отделить имя переменной от последующих символов в строке, заключите ее в фигурные скобки ()
Это особенно важно, если за именем переменной следует двоеточие (). PowerShell считает все, что между описательом области и описательом области обычно приводит к сбою интерпретации.
Например, вызывает ошибку, но работает должным образом
Чтобы предотвратить подстановку значения переменной в строке с двойными кавычками, используйте символ обратной кавычки (), который является escape-символом PowerShell.
В следующем примере символ обратного ввода, предшествующий первой переменной, не позволяет PowerShell заменить имя переменной своим значением.
Пример:
Выходные данные этой команды:
Создание
Переменная — это ссылка на значение, которое хранится в памяти. Каждая переменная в Powershell начинается со знака доллара «$» и может хранить числа, буквы и нижние подчеркивания. Присваивание значений осуществляется через знак равно «=». На примере ниже мы создали переменную variable со значением 8:
Что бы вывести переменную в консоли ее нужно повторно написать:
Мы можем проводить арифметические операции с разными переменными:
Такие операции можно проводить и со строками. На примере ниже мы выполняем сложение:
Если выполнять сложение числа и строки, то число автоматически преобразуется в строку:
Такое поведение одинаково не во всех языках и таких ситуаций лучше избегать.
Перезаписать значение переменной можно так:
Переменные живут в рамках текущего сеанса. Если вы работаете через консоль — после ее закрытия они удаляться, если это работающий скрипт — до закрытия программы. Исключения только с системными переменными и импортируемыми модулями. Одна из таких переменных, которая создается каждый сеанс $PSVersionTable, хранящая версию Powershell и ее не получится изменить или создать заново.
Строки здесь
Правила кавычек для строк здесь немного отличаются.
Строка здесь — это строка, заключенная в одинарные кавычки или двойные кавычки, окруженная знаками (). Кавычки в строке здесь интерпретируются буквально.
Строка ниже:
- охватывает несколько строк
- начинается с открывающей метки, за которой следует новая строка
- заканчивается новой строкой, за которой следует закрывающий знак
- включает каждую строку между открывающей и закрывающей знаками в составе одной строки.
Как и обычные строки, переменные заменяются их значениями в двойных кавычках здесь-строк. В одноцитарных строках переменные не заменяются их значениями.
Здесь строки можно использовать для любого текста, но они особенно полезны для следующих типов текста:
- Текст, содержащий литеральные кавычки
- Несколько строк текста, таких как текст в блоке HTML или XML
- Текст справки для документа скрипта или функции
Строка здесь может иметь любой из следующих форматов, где представляет канал строк или скрытый символ новой строки, добавляемый при нажатии клавиши ВВОД .
Двойные кавычки:
Одинарные кавычки:
Примечание
Последний символ новой строки является частью закрывающего знака. Он не добавляется в приведенную здесь строку.
Строка здесь содержит весь текст между открывающим и закрывающим знаками. В приведенной здесь строке все кавычки интерпретируются буквально. Пример:
Выходные данные этой команды:
Использование этой строки может упростить использование строки в команде. Пример:
Выходные данные этой команды:
В одноцитарных строках переменные интерпретируются буквально и воспроизводится точно. Пример:
Выходные данные этой команды:
В двойных кавычках здесь-строки переменные заменяются их значениями. Пример:
Выходные данные этой команды:
Здесь строки обычно используются для назначения переменной нескольких строк. Например, следующая строка здесь назначает страницу XML переменной $page.
Здесь строки также являются удобным форматом для ввода в командлет, который преобразует строки здесь в хэш-таблицы.
Для получения дополнительной информации см. .
Примечание
PowerShell позволяет двух- или одноцитарным строкам охватывать несколько строк без использования синтаксиса приведенных здесь строк. Однако полный синтаксис строки является предпочтительным вариантом использования.
Встроенные переменные
Встроенные переменные обычно не меняют, а используют для просмотра какой-то информации о системе. Сейчас рассмотрим некоторые из встроенных переменных PowerShell.
$null
Эта переменная ничего не возвращает. Может использоваться для создания переменной, без присвоения ей значения:
> $b = $null > Get-Variable -Name b Name Value ---- ----- b > Get-Variable -Name null Name Value ---- ----- null
$lastexitcode
Когда внешнее приложение, например ping.exe, завершает работу, оно заканчивается с кодом выхода. Этот код выхода приложения заносится в переменную $lastexitcode. Если код выхода равен нулю, значит программа выполнилась успешно, в противном случае код завершения может быть другим. Вот пример с утилитой ping:
> ping ya.ru Обмен пакетами с ya.ru с 32 байтами данных: Ответ от 87.250.250.242: число байт=32 время=15мс TTL=55 Ответ от 87.250.250.242: число байт=32 время=15мс TTL=55 Ответ от 87.250.250.242: число байт=32 время=15мс TTL=55 Ответ от 87.250.250.242: число байт=32 время=15мс TTL=55 Статистика Ping для 87.250.250.242: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь) Приблизительное время приема-передачи в мс: Минимальное = 15мсек, Максимальное = 15 мсек, Среднее = 15 мсек > $LASTEXITCODE 0 > ping qwerasdf.opt При проверке связи не удалось обнаружить узел qwerasdf.opt. Проверьте имя узла и повторите попытку. > $LASTEXITCODE 1
В переменную $lastexitcode записывается код выхода последнего приложения. Поэтому при завершении другого приложения её значение может измениться.
$true и $false
Переменная $true всегда содержит значение true логического типа данных. Тоже самое относится и к переменной $false – содержит false логического типа.
$MaximumHistoryCount
В переменной $MaximumHistoryCount содержится максимальное число строк для хранения истории команд. Значение этой переменной можно менять, а по умолчанию оно равно 4096.
> $MaximumHistoryCount 4096 > $MaximumHistoryCount = 200 > $MaximumHistoryCount 200
$^
В переменной $^ хранится имя последней команды, например:
> ping -n 1 8.8.8.8 Обмен пакетами с 8.8.8.8 по с 32 байтами данных: Ответ от 8.8.8.8: число байт=32 время=23мс TTL=110 Статистика Ping для 8.8.8.8: Пакетов: отправлено = 1, получено = 1, потеряно = 0 (0% потерь) Приблизительное время приема-передачи в мс: Минимальное = 23мсек, Максимальное = 23 мсек, Среднее = 23 мсек > $^ ping