如何撰寫 PowerShell 指令碼模組

腳本模組是儲存在擴充功能中的任何 .psm1 有效 PowerShell 腳本。 此延伸模組可讓 PowerShell 引擎在您的檔案上使用規則和模組 Cmdlet。 其中大部分的功能可協助您在其他系統上安裝程式碼,以及管理範圍。 您也可以使用模組資訊清單檔,其描述更複雜的安裝和解決方案。

撰寫 PowerShell 腳本模組

若要建立腳本模組,請將有效的 PowerShell 腳本儲存至 .psm1 檔案。 腳本及其儲存所在的目錄必須使用相同的名稱。 例如,名為 MyPsScript.psm1 的腳本會儲存在名為 的 MyPsScript 目錄中。

模組的目錄必須位於 中指定的路徑中 $env:PSModulePath 。 模組的目錄可以包含執行腳本所需的任何資源,以及描述您模組運作方式的模組資訊清單檔。

建立基本 PowerShell 模組

下列步驟說明如何建立 PowerShell 模組。

  1. 使用擴充功能 .psm1 儲存 PowerShell 腳本。 針對腳本和儲存腳本的目錄使用相同的名稱。

    使用擴充功能 .psm1 儲存腳本表示您可以使用模組 Cmdlet,例如 Import-Module。 模組 Cmdlet 主要存在,因此您可以將程式碼匯入並匯出至其他使用者的系統。 替代解決方案是將程式碼載入其他系統上,然後將程式碼點來源載入至作用中記憶體,這不是可調整的解決方案。 如需詳細資訊,請參閱瞭解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

    Cmdlet 會將 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 。 此函式會顯示行事曆的視覺標記法。 此範例包含 Synopsis、描述、參數值和程式碼的 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