Как написать модуль сценария PowerShell

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

Написание модуля скрипта PowerShell

Чтобы создать модуль скрипта, сохраните допустимый сценарий PowerShell в .psm1 файл. Скрипт и каталог, в котором он хранится, должны использовать то же имя. Например, скрипт с именем MyPsScript.psm1 хранится в каталоге с именем MyPsScript.

Каталог модуля должен находиться в пути, указанном в $env:PSModulePath. Каталог модуля может содержать все ресурсы, необходимые для запуска скрипта, и файл манифеста модуля, описывающий работу модуля в PowerShell.

Создание базового модуля PowerShell

Ниже описано, как создать модуль PowerShell.

  1. Сохраните скрипт PowerShell с расширением .psm1 . Используйте то же имя для скрипта и каталога, в котором сохраняется скрипт.

    Сохранение скрипта с расширением .psm1 означает, что можно использовать командлеты модуля, такие как Import-Module. Командлеты модуля существуют в первую очередь, чтобы можно было импортировать и экспортировать код в другие системы пользователя. Альтернативным решением будет загрузка кода в другие системы, а затем точка-источник в активную память, которая не является масштабируемым решением. Дополнительные сведения см. в разделе "Основные сведения о модуле Windows PowerShell". По умолчанию при импорте .psm1 файла все функции в скрипте доступны, но переменные не являются.

    Пример скрипта PowerShell, который имеет право Show-Calendar, доступен в конце этой статьи.

    function Show-Calendar {
    param(
        [DateTime] $start = [DateTime]::Today,
        [DateTime] $end = $start,
        $firstDayOfWeek,
        [int[]] $highlightDay,
        [string[]] $highlightDate = [DateTime]::Today.ToString('yyyy-MM-dd')
        )
    
        #actual code for the function goes here see the end of the topic for the complete code sample
    }
    
  2. Чтобы управлять доступом пользователей к определенным функциям или переменным, вызовите Export-ModuleMember в конце скрипта.

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

    function Show-Calendar {
          }
    Export-ModuleMember -Function Show-Calendar
    

    Вы можете ограничить импортированные данные с помощью манифеста модуля. Дополнительные сведения см. в статье "Импорт модуля PowerShell " и "Создание манифеста модуля PowerShell".

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

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

    Import-Module GenericModule
    
  4. Чтобы описать модуль в системе справки PowerShell, можно использовать стандартные комментарии справки в файле или создать дополнительный файл справки.

    В примере кода в нижней части этой статьи содержатся справочные сведения в комментариях. Кроме того, можно написать расширенные XML-файлы, содержащие дополнительное содержимое справки. Дополнительные сведения см. в статье "Написание справки для Windows PowerShell модулей".

  5. Если у вас есть дополнительные модули, XML-файлы или другое содержимое, которое вы хотите упаковать с помощью модуля, можно использовать манифест модуля.

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

  6. Чтобы установить и запустить модуль, сохраните модуль в одном из соответствующих путей PowerShell и используйте Import-Moduleего.

    Пути, в которых можно установить модуль, находятся в глобальной переменной $env:PSModulePath . Например, общим путем сохранения модуля в системе будет %SystemRoot%/users/<user>/Documents/PowerShell/Modules/<moduleName>. Обязательно создайте каталог для модуля, который использует то же имя, что и модуль скрипта, даже если это только один .psm1 файл. Если вы не сохранили модуль в одном из этих путей, необходимо указать расположение модуля в команде Import-Module . В противном случае PowerShell не сможет найти модуль.

    Примечание

    Начиная с PowerShell 3.0, если модуль помещен в один из путей модуля PowerShell, его не нужно импортировать явным образом. Модуль автоматически загружается при вызове функции пользователем. Дополнительные сведения о пути модуля см. в статье "Импорт модуля PowerShell " и about_PSModulePath.

  7. Чтобы удалить модуль из активной службы в текущем сеансе PowerShell, используйте Remove-Module.

    Примечание

    Remove-Module Удаляет модуль из текущего сеанса PowerShell, но не удаляет модуль или не удаляет файлы модуля.

пример кода Show-Calendar

В следующем примере показан модуль скрипта, содержащий одну функцию с именем Show-Calendar. Эта функция отображает визуальное представление календаря. Пример содержит строки справки PowerShell для синапсиса, описания, значений параметров и кода. При импорте модуля команда гарантирует экспорт Export-ModuleMember Show-Calendar функции в качестве члена модуля.

<#
 .Synopsis
  Displays a visual representation of a calendar.

 .Description
  Displays a visual representation of a calendar. This function supports multiple months
  and lets you highlight specific date ranges or days.

 .Parameter Start
  The first month to display.

 .Parameter End
  The last month to display.

 .Parameter FirstDayOfWeek
  The day of the month on which the week begins.

 .Parameter HighlightDay
  Specific days (numbered) to highlight. Used for date ranges like (25..31).
  Date ranges are specified by the Windows PowerShell range syntax. These dates are
  enclosed in square brackets.

 .Parameter HighlightDate
  Specific days (named) to highlight. These dates are surrounded by asterisks.

 .Example
   # Show a default display of this month.
   Show-Calendar

 .Example
   # Display a date range.
   Show-Calendar -Start "March, 2010" -End "May, 2010"

 .Example
   # Highlight a range of days.
   Show-Calendar -HighlightDay (1..10 + 22) -HighlightDate "2008-12-25"
#>
function Show-Calendar {
param(
    [DateTime] $start = [DateTime]::Today,
    [DateTime] $end = $start,
    $firstDayOfWeek,
    [int[]] $highlightDay,
    [string[]] $highlightDate = [DateTime]::Today.ToString('yyyy-MM-dd')
    )

## Determine the first day of the start and end months.
$start = New-Object DateTime $start.Year,$start.Month,1
$end = New-Object DateTime $end.Year,$end.Month,1

## Convert the highlighted dates into real dates.
[DateTime[]] $highlightDate = [DateTime[]] $highlightDate

## Retrieve the DateTimeFormat information so that the
## calendar can be manipulated.
$dateTimeFormat  = (Get-Culture).DateTimeFormat
if($firstDayOfWeek)
{
    $dateTimeFormat.FirstDayOfWeek = $firstDayOfWeek
}

$currentDay = $start

## Process the requested months.
while($start -le $end)
{
    ## Return to an earlier point in the function if the first day of the month
    ## is in the middle of the week.
    while($currentDay.DayOfWeek -ne $dateTimeFormat.FirstDayOfWeek)
    {
        $currentDay = $currentDay.AddDays(-1)
    }

    ## Prepare to store information about this date range.
    $currentWeek = New-Object PsObject
    $dayNames = @()
    $weeks = @()

    ## Continue processing dates until the function reaches the end of the month.
    ## The function continues until the week is completed with
    ## days from the next month.
    while(($currentDay -lt $start.AddMonths(1)) -or
        ($currentDay.DayOfWeek -ne $dateTimeFormat.FirstDayOfWeek))
    {
        ## Determine the day names to use to label the columns.
        $dayName = "{0:ddd}" -f $currentDay
        if($dayNames -notcontains $dayName)
        {
            $dayNames += $dayName
        }

        ## Pad the day number for display, highlighting if necessary.
        $displayDay = " {0,2} " -f $currentDay.Day

        ## Determine whether to highlight a specific date.
        if($highlightDate)
        {
            $compareDate = New-Object DateTime $currentDay.Year,
                $currentDay.Month,$currentDay.Day
            if($highlightDate -contains $compareDate)
            {
                $displayDay = "*" + ("{0,2}" -f $currentDay.Day) + "*"
            }
        }

        ## Otherwise, highlight as part of a date range.
        if($highlightDay -and ($highlightDay[0] -eq $currentDay.Day))
        {
            $displayDay = "[" + ("{0,2}" -f $currentDay.Day) + "]"
            $null,$highlightDay = $highlightDay
        }

        ## Add the day of the week and the day of the month as note properties.
        $currentWeek | Add-Member NoteProperty $dayName $displayDay

        ## Move to the next day of the month.
        $currentDay = $currentDay.AddDays(1)

        ## If the function reaches the next week, store the current week
        ## in the week list and continue.
        if($currentDay.DayOfWeek -eq $dateTimeFormat.FirstDayOfWeek)
        {
            $weeks += $currentWeek
            $currentWeek = New-Object PsObject
        }
    }

    ## Format the weeks as a table.
    $calendar = $weeks | Format-Table $dayNames -AutoSize | Out-String

    ## Add a centered header.
    $width = ($calendar.Split("`n") | Measure-Object -Maximum Length).Maximum
    $header = "{0:MMMM yyyy}" -f $start
    $padding = " " * (($width - $header.Length) / 2)
    $displayCalendar = " `n" + $padding + $header + "`n " + $calendar
    $displayCalendar.TrimEnd()

    ## Move to the next month.
    $start = $start.AddMonths(1)

}
}
Export-ModuleMember -Function Show-Calendar