Привет! Довольно часто в своей работе приходиться пользоваться самостоятельно написанными функциями и таскать куски кода между разными скриптами. На Хабре уже есть довольно хорошая статья про Повторное использование кода от Mroff, но была необходимость пойти немного дальше, задокументировать и как-то описать свои функции. Как оказалось, поиск выдавал довольно сухую информацию в основном по общей структуре функции и не более того. Упорство было вознаграждено, и я решил поделиться полученной информацией. Добро пожаловать под кат, где мы научимся вносить в свои функции информацию для потомков и коллег.

Давайте для начала разберем стандартную структуру функции в PowerShell. Выглядит она следующим образом

Function TestPath ([String]$Path)
        {
                Return(Test-Path $Path)
        }

В общем то ничего сложного, как и в других языках задали имя TestPath, в круглых скобках через запятую скормили переменные $Path, выполнили в теле функции необходимые действия и при необходимости вернули Return() значение. А как быть, когда нужно работать с несколькими переменными? Выходов всегда больше одного – постоянно давать мнемонические коды или делать описание переменной, давайте рассмотрим, как это делается:

Function TestPath
        {
                PARAM (
                [PARAMETER(Mandatory=$True,Position=0,HelpMessage = "Путь до проверяемого ресурса",ParameterSetName='Path')]$Path
                )
                Return(Test-Path $Path)
        }

Сложности никакой нет, но появились дополнительные параметры, которые нам упрощают жизнь:

Mandatory – Принимает два значения True обязательный для заполнения и False необязательный;
HelpMessage – Справка по переменной;
ParameterSetName – Имя переменной к которой относятся данные параметры;
Position – Позиция переменной при вызове функции;

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

((Get-Command TestPath).ParameterSets.Parameters | Where-Object Name -eq Path).HelpMessage

PowerShell ответит нам одной строкой в которой будет написано: Путь до проверяемого ресурса.

В какой-то степени удобно, но если мы привыкли работать с PowerShell, то знаем команду Get-Help которая выводит подробную информацию о функции с примерами ее использования и переменными, которые необходимо передавать.

Немного усложним задачу и подготовим функцию информация о которой по запросу Get-Help будет выводиться в полном объеме:

Function WriteToLog {
    <#
    .SYNOPSIS
        Вывод сообщения в консоль и в файл лога.
    .DESCRIPTION
        Данная функция выводит переданную строку в лог файл и в консоль PowerShell
    .EXAMPLE
        #WriteToLog -Str "Данное сообщение будет выведено в консоль красным цветом и в файл C:\Log\log.txt" -FileName 'C:\Log\log.txt' -Color Red
    .EXAMPLE
        #WriteToLog -Str "Данное сообщение будет выведено в консоль цветом по умолчанию (White) и в файл C:\Log\log.txt" -FileName 'C:\Log\log.txt'
    .PARAMETER Str
        Строка, которую необходимо вывести (обязательный параметр)
    .PARAMETER FileName
        Имя файла лога (обязательный параметр)
    .PARAMETER Color
        Цвет текста сообщения в консоли PowerShell (По умолчанию цвет текста белый (White))
    #>
    param (
        [PARAMETER(Mandatory=$True,Position=0)][String]$Str,
        [PARAMETER(Mandatory=$True,Position=1)][String]$FileName,
        [PARAMETER(Mandatory=$False,Position=2)][String]$Color='White'
        )
        Write-Host $Str -ForegroundColor $Color
        If ((Test-Path $FileName) -eq $True)
            {
                Add-Content -Path $FileName -Value $Str
            }
        Else
            {
                Set-Content -Path $FileName -Value $Str
            }
    }

После выполнения данного кода команда Get-Help 'WriteToLog' -ShowWindow выведет нам следующее окно.


Давайте разберем что же мы такого написали:

<##> – В данном блоке написаны параметры для справки PowerShell.
.SYNOPSIS – блок для краткого описание функции
.DESCRIPTION – блок для полного описание функции
.EXAMPLE – блок для примера использования функции, может быть несколько
.PARAMETR Имя параметра – блок для описания переменной, для каждой переменной свой блок.

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

param () – блок для описания переменных, в котором мы указали их порядок и необходимость передачи параметров при вызове функции. Для переменной $Color мы присвоили значение по умолчанию'White'.

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

Спасибо что дочитали до конца.
Поделиться с друзьями
-->

Комментарии (8)


  1. TimsTims
    12.09.2016 10:42
    -1

    > ((Get-Command TestPath).ParameterSets.Parameters | Where-Object Name -eq Path).HelpMessage
    Оффтоп конечно, но что-то я не могу сказать, что PowerShell выглядит удобным… по крайней мере для получения манов


    1. mayorovp
      12.09.2016 10:52
      +1

      Все в нем в порядке с удобством, это просто автор поста что-то странное написал. Командлет get-help еще никто не отменял.


    1. skazi_premiere
      12.09.2016 10:54

      При правильном описании функции и подключении ее через модули (или "."-include), для вызова справки по функции достаточно выделить ее и нажать F1. Именно поэтому и появилась статья.


  1. mayorovp
    12.09.2016 10:51

    Как же все сложно написано… Да, эти все возможности есть — но, будучи примененными к настолько простым примерам, они только все усложняют.


    1. Зачем в функции TestPath использован Return? Можно же написать просто —


    Test-Path $Path

    и значение, которое вернула эта команда автоматически станет возвращаемым значением функции.


    2. Зачем столько параметров у атрибута?


    [PARAMETER(Mandatory=$True,Position=0,HelpMessage = "Путь до проверяемого ресурса",ParameterSetName='Path')]

    Позицию отдельно указывать не надо. ParameterSetName нужен только если у командлета есть два разных набора параметров. В итоге страшную запись можно сократить до


    [PARAMETER(Mandatory=$True, HelpMessage = "Путь до проверяемого ресурса")]


    1. skazi_premiere
      12.09.2016 11:06

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


      1. mayorovp
        12.09.2016 11:11
        +2

        Тогда почему вы не указали еще 5 свойств?


        1. skazi_premiere
          12.09.2016 11:22

          Цель была описание собственных функций, а не описание параметров переменной. Параметры довольно просто гуглятся.


  1. Slipeer
    12.09.2016 16:36

    Для полноты картины ещё бы про локализацию этой информации написать!
    https://msdn.microsoft.com/en-us/library/dd878343%28v=vs.85%29.aspx