PowerShell/04core11 min

Funkcje, moduły i ponowne użycie

Gdy probe'y ZEUS rosną, kopiowanie tych samych funkcji między skryptami staje się problemem. Rozwiązaniem są moduły — pakiety funkcji z jasno zdefiniowanym publicznym API. Ta lekcja pokazuje, jak je budujemy.

Od skryptu do funkcji

Powtarzalny kawałek logiki wydzielamy do funkcji Verb-Noun z [CmdletBinding()].

function ConvertTo-LsnResult {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] $Data,
        [switch]$AsJson
    )
    if ($AsJson) {
        $Data | ConvertTo-Json -Depth 6 -Compress
    } else {
        $Data
    }
}

Moduł skryptowy (.psm1)

Powiązane funkcje grupujemy w pliku modułu .psm1. Moduł importuje się raz, a jego funkcje są dostępne jak wbudowane cmdlety.

LsnProbe/
├── LsnProbe.psd1        # manifest (metadane, wersja, eksporty)
├── LsnProbe.psm1        # implementacja
├── Public/              # funkcje eksportowane
│   ├── Get-LsnForest.ps1
│   ├── Get-LsnInventory.ps1
│   └── Get-LsnPerf.ps1
└── Private/             # funkcje pomocnicze (nieeksportowane)
    └── Invoke-LsnLdapPaged.ps1

W .psm1 ładujemy pliki i jawnie eksportujemy tylko publiczne funkcje:

# LsnProbe.psm1
$public  = Get-ChildItem "$PSScriptRoot/Public/*.ps1"
$private = Get-ChildItem "$PSScriptRoot/Private/*.ps1"

foreach ($file in @($public + $private)) {
    . $file.FullName
}

Export-ModuleMember -Function $public.BaseName

Standard ProfessNet: dzielimy moduł na Public/ (API zewnętrzne) i Private/ (helpery). Eksportujemy tylko funkcje publiczne przez Export-ModuleMember. Helpery jak Invoke-LsnLdapPaged zostają wewnętrzne.

Manifest (.psd1)

Manifest opisuje moduł: wersję, zależności, jakie funkcje eksportuje.

@{
    RootModule        = 'LsnProbe.psm1'
    ModuleVersion     = '1.4.0'
    PowerShellVersion = '5.1'
    FunctionsToExport = @('Get-LsnForest', 'Get-LsnInventory', 'Get-LsnPerf')
    PrivateData       = @{ PSData = @{ Tags = @('ZEUS', 'AD', 'inventory') } }
}

Standard ProfessNet: FunctionsToExport wyliczamy jawnie (nie '*') — to przyspiesza ładowanie i dokumentuje publiczne API. Wersję modułu podbijamy zgodnie z SemVer.

Comment-based help

Funkcje publiczne dokumentujemy komentarzem, który zasila Get-Help.

function Get-LsnInventory {
    <#
    .SYNOPSIS
        Zbiera inwentaryzację hostów z forestu AD.
    .PARAMETER Forest
        Nazwa forestu, np. corp.local.
    .EXAMPLE
        Get-LsnInventory -Forest corp.local -AsJson
    #>
    [CmdletBinding()]
    param([Parameter(Mandatory)][string]$Forest, [switch]$AsJson)
    # ...
}
PlikZawiera
*.psd1 (manifest)metadane, wersja, lista eksportów
*.psm1 (moduł)ładowanie plików, Export-ModuleMember
Public/*.ps1funkcje API
Private/*.ps1helpery, nieeksportowane

Wskazówka: testuj moduł z Pester (framework testowy PowerShell). Importuj moduł w testach przez Import-Module ./LsnProbe -Force i sprawdzaj funkcje publiczne.


Funkcje Verb-Noun, podział Public/Private, manifest z jawnym eksportem i comment-based help — tak budujemy reużywalne moduły probe'ów. Jeden moduł zamiast dziesięciu kopii tej samej logiki.