Создание функций PowerShell, поддерживающих общие параметры

Опубликовано: 15 Марта, 2023
Создание функций PowerShell, поддерживающих общие параметры

Подавляющее большинство собственных командлетов Windows PowerShell включают поддержку общих параметров. Например, если вы посмотрите на рисунок ниже, вы увидите, что синтаксис командлета Get-Service перечисляет CommonParameters среди поддерживаемых параметров командлета.

Изображение 4309
Для тех, кто может быть не знаком с общими параметрами, они включают в себя такие вещи, как:

• Отладка
• Действие по ошибке
• Переменная ошибки
• ИнформацияДействие
• Информационная переменная
• Исходящая переменная
• Внешний буфер
• PipelineVariable
• Подробный
• ПредупреждениеДействие
• Предупреждающая переменная
• Что если
• Подтверждать

Не каждый командлет поддерживает все общие параметры, но в PowerShell эти общие параметры широко поддерживаются. Например, вы можете добавить -WhatIf к командлету, чтобы узнать, что произойдет, если командлет будет запущен «по-настоящему», или вы можете добавить -параметр Verbose к командлету, чтобы просмотреть подробный вывод.

Создание функций, действующих как командлеты

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

Позвольте мне привести вам очень простой пример. PowerShell включает встроенный командлет Get-Service, который отображает имена всех системных служб. Давайте представим на мгновение, что по какой-то причине вы хотели создать аналогичный командлет с именем List-Services, в котором перечислялось бы имя каждой службы и независимо от того, запущена ли служба. Маловероятно, что вы сделали бы это в реальной жизни, потому что желаемого результата можно добиться с помощью командлета Get-Service, я использую этот сценарий просто для иллюстрации. Во всяком случае, вы можете достичь этой цели, используя функцию. Вот как может выглядеть код:

Службы списка функций { Get-Service | Select-Object Name, Status }

Теперь каждый раз, когда вы включаете команду List Services в этот сценарий, сценарий будет отображать список всех имен служб и их статусов. Другими словами, имя функции (List Services) по сути рассматривается как команда. В отличие от собственных командлетов, функции обычно не поддерживают использование общих параметров. Тем не менее, относительно легко расширить поддержку общих параметров для функций, тем самым делая функцию более похожей на собственный командлет PowerShell.

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

Мой личный фаворит — параметр Verbose. Параметр Verbose позволяет указать вашей функции, что вы хотите отобразить более подробный (подробный) вывод. Конечно, вы должны сообщить своей функции, как различать обычный вывод и подробный вывод.

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

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

[привязка команд()] Параметр()

После того, как эти две строки будут на месте, вы можете вставить командлет Write-Verbose в любое место, где вы хотите отобразить подробный текст. Вот как может выглядеть функция:

Function List-Services { [cmdletbinding()] Param() Write-Verbose "Это системные службы:" get-Service | Select-Object Name, Status }

Если вы посмотрите на рисунок ниже, то увидите, что я создал короткий скрипт, который вызывает функцию, используя параметр -Verbose. Вы также можете увидеть в выводе, что в результате отображается подробный текст. Если бы я запускал функцию без параметра Verbose, эта строка текста не отображалась бы.

Изображение 4310 Поддержка Что Если

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

Function List-Services { [cmdletbinding()] Param($Name) Get-Service $Name Start-Service $Name Get-Service $Name } cls List-Services VSS

Как видите, я передаю имя службы (VSS) функции в качестве параметра ($Name). Затем функция отображает службу, запускает службу, а затем отображает службу еще раз, чтобы подтвердить, что она запущена. Вот как выглядит результат:

Изображение 4311
Запуск службы VSS безвреден, но давайте на мгновение представим, что эта функция может нанести ущерб при неправильном использовании. Если бы это было так, то, возможно, имело бы смысл добавить поддержку WhatIf, чтобы администратор мог оценить поведение функции, прежде чем совершить потенциально разрушительное действие. Вот как выглядит скрипт:

Function List-Services { [cmdletbinding(SupportsShouldProcess)] Param($Name) If ($PSCmdlet.ShouldProcess("Запуск системной службы с именем: " + $Name)) { Get-Service $Name Start-Service $Name Get-Service $Name } } cls List-Services VSS -WhatIf

Глядя на приведенный выше сценарий, вы заметите, что я добавил SupportsShouldProcess в привязку командлета. Это то, что добавляет поддержку WhatIf. Он также создал команду «если», которая начинается с If ($PSCmdlet.ShouldProcess. Эта команда определяет поведение сценария в зависимости от того, использовался ли параметр -WhatIf. круглые скобки отображаются. В противном случае выполняются команды в блоке команд ниже. Вот вывод скрипта с параметром -WhatIf в использовании. Между прочим, если параметр -WhatIf удален, то вывод соответствует тому, что вы видели в предыдущем снимке экрана.

Изображение 4312
Переход на собственные функции с помощью функций PowerShell

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