powershell передача параметров в скрипт
Передача параметров в PowerShell
Иногда создаваемый вами сценарий или функция должна принять какое либо входное значение — имя компьютера, путь к папке, название сервиса и т.п. В PowerShell есть несколько способов передать данные в сценарий из командной строки, сделав их ввод более простым и эффективным.
Этот скрипт должен вывести состояние заданного сервиса\сервисов для одного или нескольких компьютеров. Имя сервиса и компьютера передаются в скрипт в качестве аргументов.
Теперь выполним его, указав в качестве аргументов сервис печати (spooler) и имя компьютера SRV1:
.\service.ps1 spooler SRV1
Более эффективным способом передачи параметров является использование в сценарии блока param. Для примера возьмем наш сценарий и изменим его:
Param (
[string]$service,
[string]$computer
)
Разбивать сценарий на строки необязательно, вполне возможно записать все в одну строку. Если блок param имеется в сценарии или функции, PowerShell сам считывает его и разделяет знаками табуляции. Поскольку имена параметров явно указаны, то их можно вводить в любом порядке, например так:
Чтобы вводить меньше текста, имена параметров можно сократить, например так:
.\service.ps1 spooler SRV1
Есть в PowerShell и более сложный способ передачи параметров, позволяющий задавать параметры как обязательные, указывать для каждого позицию и многое другое. Для примера изменим сценарий следующим образом:
Param (
[Parameter (Mandatory=$true, Position=1)]
[string]$service,
[Parameter (Mandatory=$true, Position=2)]
[string]$computer
)
Здесь оба параметра указаны как обязательные (Mandatory=$true) и для каждого задана своя позиция. Это значит, что оба параметра обязательно должны быть указаны и должны идти строго в определенном порядке. Теперь если не указать один из параметров, то PowerShell автоматически напомнит об этом и предложит ввести недостающую информацию.
Использование расширенного синтаксиса позволяет задавать различные ограничения для вводимых параметров. Еще раз изменим сценарий, указав в нем для имени компьютера ограничение в 3 символа (ValidateLength(1,3):
Param (
[Parameter (Mandatory=$true)]
[string]$service,
[Parameter (Mandatory=$true)]
[ValidateLength(1,3)]
[string]$computer
)
И теперь, если введенные значения не подходят под заданные ограничения, то сценарий не отработает. В нашем случае вот такая команда выдаст ошибку
А такая отработает нормально:
about_Parameters
Краткое описание
Описание работы с параметрами команд в PowerShell.
Подробное описание
Большинство команд PowerShell, таких как командлеты, функции и скрипты, зависят от параметров, позволяющих пользователям выбирать параметры или предоставлять входные данные. Параметры соответствуют имени команды и имеют следующую форму:
Тип параметров и требования к этим параметрам различаются. Чтобы найти сведения о параметрах команды, используйте Get-Help командлет. Например, чтобы найти сведения о параметрах Get-ChildItem командлета, введите:
Чтобы найти сведения о параметрах скрипта, используйте полный путь к файлу скрипта. Пример:
Get-Help Командлет возвращает различные сведения о команде, включая описание, синтаксис команды, сведения о параметрах и примеры, демонстрирующие использование параметров в команде.
Можно также использовать параметр параметра Get-Help командлета для поиска сведений о конкретном параметре. Также можно использовать параметр Parameter с подстановочным знаком ( * ), чтобы найти сведения обо всех параметрах команды. Например, следующая команда получает сведения обо всех параметрах Get-Member командлета:
Значения параметров по умолчанию
Необязательные параметры имеют значение по умолчанию, которое является значением, которое используется или предполагается, если параметр не указан в команде.
Чтобы найти значение параметра по умолчанию, см. раздел справки для командлета. Описание параметра должно включать значение по умолчанию.
Можно также задать пользовательское значение по умолчанию для любого параметра командлета или расширенной функции. Дополнительные сведения о настройке пользовательских значений по умолчанию см. в разделе about_Parameters_Default_Values.
Таблица атрибутов параметра
При использовании полных параметров, параметров или сетевого параметра Get-Help командлета Get-Help отображает таблицу атрибутов параметров с подробными сведениями о параметре.
Эти сведения включают сведения, необходимые для использования параметра. Например, раздел справки для Get-ChildItem командлета содержит следующие сведения о параметре пути:
Сведения о параметрах включают в себя синтаксис параметров, описание параметра и атрибуты параметров. В следующих разделах описываются атрибуты параметров.
Требуется параметр
Этот параметр указывает, является ли параметр обязательным, то есть должны ли все команды, использующие этот командлет, включать этот параметр. Если значение равно true и в команде отсутствует параметр, PowerShell запрашивает значение для параметра.
Расположение параметра
Если Position для параметра задано неотрицательное целое число, имя параметра не требуется. Этот тип параметра называется параметром позиционирования, а число указывает на расположение, в котором параметр должен располагаться относительно других параметров позиционирования. Именованный параметр может быть указан в любом месте после имени командлета. Если вы включили имя параметра для позиционированного параметра, то параметр может быть указан в любом месте после имени командлета.
Например, Get-ChildItem командлет содержит параметры Path и Exclude. Position Параметр path имеет значение 0, что означает, что он является позиционированным параметром. Position Параметр Exclude имеет имя.
Это означает, что путь не требует имени параметра, но его значение должно быть первым или единственным неименованным значением параметра в команде. Однако, поскольку параметр Exclude является именованным параметром, его можно поместить в любую позицию в команде.
В результате Position настройки этих двух параметров можно использовать любую из следующих команд:
Если бы вы включали другой параметр с указанием параметра, не указывая имя параметра, этот параметр должен быть помещен в порядок, заданный Position параметром.
Тип параметра
Значение по умолчанию
Этот параметр определяет значение, которое будет считаться параметром, если другое значение не указано. Например, значение параметра Path по умолчанию часто является текущим каталогом. Обязательные параметры никогда не имеют значения по умолчанию. Для многих необязательных параметров значение по умолчанию отсутствует, так как параметр не действует, если он не используется.
Принимает несколько значений
Этот параметр указывает, принимает ли параметр несколько значений параметров. Если параметр принимает несколько значений, можно ввести разделенный запятыми список в качестве значения параметра в команде или сохранить список с разделителями-запятыми (массив) в переменной, а затем указать переменную в качестве значения параметра.
Например, параметр Name Get-Service командлета принимает несколько значений. Допустимы следующие команды:
Принимает входные данные конвейера
Этот параметр указывает, можно ли использовать оператор конвейера ( | ) для отправки значения в параметр.
Если параметр имеет значение true (по значению)), PowerShell пытается связать все переданные значения с этим параметром перед тем, как попытается обработать команду другими методами.
Например, можно передать значение в параметр Name только в том случае, если у значения есть свойство с именем Name.
Типизированный параметр, который принимает входные данные конвейера ( by Value ) или ( by PropertyName ), позволяет использовать блоки скриптов с отложенной привязкой для параметра.
Сведения о блоках скриптов с отложенной привязкой можно узнать здесь about_Script_Blocks. md
Принимает подстановочные знаки
Этот параметр указывает, может ли значение параметра содержать подстановочные знаки, чтобы значение параметра можно было сопоставить более чем с одним существующим элементом в целевом контейнере.
Общие параметры
Общие параметры — это параметры, которые можно использовать с любым командлетом. Дополнительные сведения об общих параметрах см. в разделе about_CommonParameters.
Jump Start в PowerShell (часть I)
Только автоматизация. Только PowerShell.
Предисловие
В качестве хобби и при наличии времени преподаю студентам в УКИТ (бывший Московский государственный колледж информационных технологий). На данный момент у меня мало времени, чтобы уделить его группе студентов, зато вполне достаточно, чтобы подготовить пост здесь, на Хабре.
Я работаю системным администратором в крупной не ИТ-компании с большой завязкой на ИТ ресурсы. По роду деятельности представляется решать большое количество однотипных задач по обслуживанию пользователей.
С языком PowerShell познакомился около двух лет назад, но вплотную занялся им лишь спустя год, не осознав поначалу его огромных возможностей. В статье, прежде всего, я буду ориентироваться на тех, кто хочет начать работать с PowerShell, но пока не доверяет ему или не знает, с какой стороны подступиться к этому чуду.
Внимание: PowerShell вызывает привыкание.
Введение
Windows PowerShell — расширяемое средство автоматизации от Microsoft, состоящее из оболочки с интерфейсом командной строки и сопутствующего языка сценариев.
Выглядеть среда PowerShell может так, как командная строка:
powershell.exe
Или в виде приложения:
powershell_ise.exe
Powershell_ise.exe называется интегрированной средой сценариев — Windows PowerShell ISE. Позволяет работать с языком в удобной среде с подсветкой синтаксиса, конструктором команд, автозаполнением команд по нажатию TAB и прочими прелестями. Идеальна для создания и тестирования сценариев.
Для запуска среды powershell.exe или powershell_ise.exe достаточно набрать аналогичное название в строке выполнить.
Файл сценария PowerShell имеет расширение .ps1.
Сценарий не получится запустить двойным ЛКМ. Это сделано специально для того, чтобы не нанести вред системе случайно запущенным скриптом.
Для запуска, по клику ПКМ следует выбрать «Выполнить с помощью PowerShell»:
Помимо того, что существует ограничение по запуску сценариев ЛКМ, по умолчанию выполнение сценариев в системе запрещено, опять же, по описанной выше причине — не нанести вред системе. Для проверки текущей политики выполнения выполним команду:
Мы получим одно из следующих ниже значений. С большой вероятностью, если это был первый запуск, мы получим Restricted.
Для выполнения и тестирования понизим политику до RemoteSigned выполнив команду:
Приступаем к работе
Командлет
Например, для получения текущих процессов, мы выполним команду:
И получим результат:
Попробуйте самостоятельно выполнить:
Не обязательно знать наизусть все командлеты. Get-Help спасёт ситуацию.
Информацию о всех доступных командлетах можно получить, введя следующую команду:
Если мы используем PowerShell ISE, мы облегчаем процесс разработки.
Достаточно ввести знак тире «—» после того, как ввели командлет, и мы получим все возможные варианты параметров и их типы:
Если, всё же, мы забудем какие свойства есть у того или иного командлета, прогоним его через Get-Member:
Недостаточно информации? Обратимся к справке с параметром -Examples:
Получаем описание Get-Process, да ещё и с примерами использования:
Что аналогично записи:
А теперь остановим процесс:
Немногим ранее мы сказали, что командлеты именуются по правилу Глагол-Существительное. Уточню, что глагол не обязательно должен быть Get. Помимо того, что мы можем получать, мы можем задавать Set (помните, Set-ExecutionPolicy), запускать Start, останавливать Stop, выводить Out, создавать New и многие другие. Название командлета ни чем не ограничивается и, когда мы будем с вами создавать свой собственный, сможем назвать его так, как душе угодно.
Попробуем выполнить вывод в файл:
Кстати, аналогично можно записать так:
Комментарии
Мы все знаем, использовать комментарии является хорошим тоном.
Комментарии в PowerShell бывают строчные — # и блочные — :
Обратим внимание, на код из примера:
Для тех, кто знаком с WMI, кто делает это на старом добром VBScript, помните, сколько кода надо написать?
Конвейер
Конвейер (|) — передаёт выходные данные одной команды во входные данные на обработку другой команде. Мы использовали конвейер ранее, получая все свойства объекта или, в предыдущем примере, выбирая из набора данных только поле Caption.
Чтобы понять принцип конвейера, давайте выполним код:
Что произойдёт: получаем все службы (Get-Service), передаём все полученные службы на сортировку в командлет Sort-Object и указываем, что хотим отсортировать их по параметру Status. На выводе мы получим сначала все службы со статусом Stop, а потом все службы со статусом Running.
В примере ниже мы сначала получим все запущенные службы. После первого конвейера проходимся по каждому элементу, выбираем только те службы, у которых статус Running и на втором конвейере выбираем, что хотим на выводе увидеть только displayname служб:
В примере мы используем $_. Данная запись означает текущий элемент в конвейере.
Послесловие
В этой части мы научились запускать PowerShell, разобрались с политикой выполнения сценариев. Поняли, что такое командлеты, знаем, как передавать их по конвейеру и как получить их свойства. Если мы что-то забудем, обязательно Get-Help.
Все это знания нужные для того, чтобы сделать первый прыжок в язык. Поверьте, ещё много интересного!
Используем параметры в функциях Powershell с param и Parameter
При создании функции Powershell мы можем передать в нее разные параметры использую атрибут Parameters() и блок param(). Эти параметры могут быть использованы при работе в конвейере, валидации типов данных, определении обязательности их использования, значений по умолчанию и многого другого. В этой статье мы разберем как использовать Powershell Parameters() и param() на примерах.
Навигация по посту
Где и как использовать param и Parameters
Ситуация меняется, например, когда вам нужно пинговать разные хосты. Самым плохим вариантом будет дублирование предыдущего кода:
Для соблюдения принципа DRY есть несколько вариантов.
Переменная args
В Powershell, так же как и во многих других языках, существует переменная ‘args’. Смысл в этой переменной хранить все переданные значения в коллекции (так же называются списки, листы или просто массив).
Эта переменная создается автоматически при вызове команды:
Что бы получать доступ к каждому значение мы должны обращаться к нему по индексу:
Одна из проблем, которая появляется при использовании ‘$args’, неочевидность использования. Спустя время вы, или другой человек, можете не вспомнить про порядок передаваемых значений, их типы данных и т.д. Нужно будет открывать код и читать его что бы разобраться в этом.
Именованные параметры
Использование ключей выглядит так:
Вряд ли у вас возникнут сомнения в том, что должно находится в параметре «ComputerName» или «Hops». Это нельзя гарантировать при использовании «$args».
Что бы реализовать параметры в вашей функции существует 2 подхода.
Первый способ похож на реализацию параметров в большинстве языков, мы просто помещаем их в круглые скобки:
Второй способ реализуется через блок param() в котором мы объявляем параметры:
Блок ‘param’ более предпочтительный способ. Он принят сообществом как стандарт передачи параметров. Кроме этого он позволяет использовать расширенный функционал.
Расширенные функции с CmdletBinding и Parameter
В Powershell есть понятие расширенных функций. Эти функции создаются при наличии одного или двух атрибутов: ‘CmdletBinding ‘ и ‘Parameter’. Благодаря им у вашей команды автоматически появляется следующий список ключей (указан ключ и алиас):
Атрибут ‘Parameter’ используется внутри ‘param’. Он используется для проверки (валидации) определенных параметров. Эти проверки могут быть разными: может ли ключ принимать данные с конвейера, какова его максимальна длина, является ли он обязательным и т.д. Блок ‘Parameter’ можно дублировать.
Пример использования (только для демонстрации синтаксиса):
Так как я сам легко путаюсь в понятии параметр, аргумент и атрибут, ниже скриншот с небольшим объяснением:
Использование param в файлах
Эта статья рассматривает использования ‘param()’ в функциях т.к. это наиболее популярный способ использования. Тем не менее вы можете поместить этот блок в файл:
Далее мы можем вызвать этот файл и передать в него значения:
Если до блока ‘param()’ будет какой-то код (кроме комментариев), произойдет ошибка:
Обязательные Mandatory аргументы
Работая с другими командами Powershell вы замечали, что какие-то параметры являются обязательными к заполнению, а какие-то нет. По умолчанию все параметры опциональны. Что бы сделать их обязательными к заполнению используется аргумент ‘Mandatory’. Обязательность использования параметра указывается в ‘Parameter()’:
Если вы не используете параметр явно, то он у вас будет запрошен. Это правило, в случае выше, касается только одного параметра так как он является обязательным.
Обратите внимание, что объявление ‘Mandatory’ не снимает с вас обязанности проверки на корректность переданных данных. Это дает лишь возможность остановить работу функции еще на первоначальном этапе.
Проверка типов и значение по умолчанию
Эта проверка выполняется до объявления переменной.
У некоторых типов вы можете добавить скобки ‘[]’. Такой прием говорит, что вы ожидаете получить массив определенных типов. В случае строк ‘[string]’ массив строк будет выглядеть ‘[string[]]’ (ниже пример на числах):
Объявить значение по умолчанию мы можем только у аргумента, который не является ‘Mandatory’. Это делается следующим образом:
switch
Аналогичным образом мы можем объявить переменную типа switch. Если параметр будет указан, то такая переменна будет иметь значение ‘True’:
Такой подход уменьшает риск ошибок и сокращает время на написание команды. Использование switch похоже на bool, но у них есть разница. В случае ‘[bool]’ нужно будет указывать значение параметра.
Разделение параметров на группы с ParameterSetName
В ситуациях, когда в функцию нужно передать разный набор обязательных параметров, мы можем использовать атрибут ParameterSetName. Для примера можно посмотреть на описание синтаксиса команды ‘Get-EventLog’:
У нас выводится 2 возможных варианта использования команды. Для каждого из варианта использования команды могут быть определены свои индивидуальные ключи. Именно для этого используется ParameterSetName.
Создадим команду с 2-умя группами. Первая группа ‘Group1’ работает с именами пользователей, а ‘Group2’ только с идентификаторами и требует дополнительно параметра:
Группу, которую вы планируете использовать по умолчанию, можно определить в ‘CmdletBinding’ используя атрибут ‘DefaultParameterSetName’:
Один ключ может находится в нескольких группах. Для этого, группу, нужно указать в разных ‘Parameter()’. Каждый аргумент, указанный в Parameter, будет действовать для определенной группы. Так, в случае ниже, в одной группе «$Message» является обязательным, а в другой опциональным параметром:
Позиционные параметры с Position
При создании команды каждый параметр имеет свою позицию. Эти позиции соответствуют порядку их объявления внутри функции:
Такой подход часто используется в обычных командах Powershell. Параметры типа ‘Name’ или ‘ComputerName’ могут работать позиционно, а остальные нет.
Параметры конвейера
Для использования конвейера можно определить несколько аргументов:
Создадим функцию, которая будет принимать оба параметра:
Единственный момент, который не оговорен в той статье, ‘ValueFromPipeline’ можно использовать несколько раз, но в определенном случае. Если у вы используете группировку (разделяете параметры на группы) и указываете один из параметров явно:
Включаем значения вне параметров с ValueFromRemainingArguments
У вас может быть ситуация, когда вы не можете предусмотреть параметр для конкретного значения. Это так же может быть проблема с ограничением Powershell на 32 параметра. В этом случае вы можете использовать ‘ValueFromRemainingArguments’, который включает все значения не привязанных к каким-то параметрам.
Атрибут ‘ValueFromRemainingArguments’ объявляется следующим образом:
Обратите внимание, что порядок в этом случае не важен.
Атрибуты валидации параметров
Значения у параметров могут проходить разные проверки. Для этих проверок существуют разные атрибуты:
Рассмотрим некоторые из этих атрибутов.
Ошибки при этом могут быть разными:
‘AllowNull()’ работает для типов ‘[array]’ и других типов данных, кроме строк и коллекций. Для них нужно использовать ‘[AllowEmptyString()]’ и ‘[AllowEmptyCollection()]’.
Перед указанием таких атрибутов стоит проверить во что будет преобразован ваш тип данных, например:
Подсчет значений
Проверка по скрипту
Вы можете создать свою проверку параметров с помощью «ValidateScript». Так вы создадите параметр, который запретит указывать прошедшие даты:
Ошибка происходит из-за того, что команда отправляет данные, допустим в 11.1 секунд, а валидация в 11.2. Во втором примере мы добавляем 1 секунду что бы ошибки не было.
Вместо «$PSItem» можно использовать «$_».
Проверка по шаблонам регулярных выражений
Мы можем привязать к параметру проверку на простые регулярные выражения (SupportsWildcards) и расширенные (ValidatePattern). Так мы убедимся, что в параметр передают валидный IP адрес:
Ограничение выбора значений с ValidateSet
В некоторых командах есть возможность выбора значений у параметров. Такой выбор осуществляется через кнопку ‘tab’. Вы можете проверить это нажав ‘tab’ в следующей команде:
У вас будет выполняться переключение между значениями: Continue, Ignore, Inquire и т.д.
Подобный выбор задается в атрибуте ValidateSet:
Если вы укажете значение не прописанное в ‘ValidateSet’, то получите ошибку:
Передача ключей и значений в одной переменной (Splatting)
Обычный вызов команды выглядит следующим образом:
Мы можем взять все ключи и значения из этой команды, поместить в hashtable и передать в команду как набор параметров:
Что бы Powershell понял, что мы передаем не одну переменную, а набор ключей и значений, мы должны ее пометить знаком ‘@’:
Такой подход называется ‘Splatting’ (брызги) и немного повышает читаемость кода.
Если в hashtable будет находиться дополнительный параметр, который не реализован в команде, то выйдет ошибка:
Обычные массивы так тоже можно передавать, но вы должны знать позиции под которыми должны располагаться значения:
Используя splatting, в Powershell 7+, вы можете перезаписывать значения из метода splatting:
Алиасы
К параметрам можно привязать алиасы (короткие имена/псевдонимы). Это делается через атрибут ‘Alias()’. Ограничений в количестве атрибутов нет: