Rozdział 10 — Moduły skryptów

Przekształcanie jedno linerów i skryptów w programie PowerShell w narzędzia wielokrotnego użytku staje się jeszcze ważniejsze, jeśli jest to coś, czego będziesz często używać. Pakowanie funkcji w module skryptu sprawia, że wyglądają i są bardziej profesjonalne oraz ułatwiają ich udostępnianie.

Dot-Sourcing Functions

Coś, o czym nie mówiliśmy w poprzednim rozdziale, to funkcje kropkowania. Gdy funkcja w skrypcie nie jest częścią modułu, jedynym sposobem załadowania jej do pamięci jest użycie kropki źródłowej pliku, w którym .PS1 została zapisana.

Następująca funkcja została zapisana jako Get-MrPSVersion.ps1 .

function Get-MrPSVersion {
    $PSVersionTable
}

Po uruchomieniu skryptu nic się nie dzieje.

.\Get-MrPSVersion.ps1

Jeśli spróbujesz wywołać funkcję, zostanie wygenerowany komunikat o błędzie.

Get-MrPSVersion
Get-MrPSVersion : The term 'Get-MrPSVersion' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-MrPSVersion
    + CategoryInfo          : ObjectNotFound: (Get-MrPSVersion:String) [], CommandNotFou
   ndException
    + FullyQualifiedErrorId : CommandNotFoundException

Możesz określić, czy funkcje są ładowane do pamięci, sprawdzając, czy istnieją w aplikacji PSDrive funkcji.

Get-ChildItem -Path Function:\Get-MrPSVersion
Get-ChildItem : Cannot find path 'Get-MrPSVersion' because it does not exist.
At line:1 char:1
+ Get-ChildItem -Path Function:\Get-MrPSVersion
    + CategoryInfo          : ObjectNotFound: (Get-MrPSVersion:String) [Get-ChildItem],
   ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Problem z wywoływaniem skryptu zawierającego funkcję polega na tym, że funkcje są ładowane w zakresie skryptu. Po zakończeniu działania skryptu ten zakres zostanie usunięty, a funkcja zostanie usunięta wraz z nim.

Funkcja musi zostać załadowana do zakresu globalnego. Można to osiągnąć przez źródło kropki dla skryptu zawierającego funkcję. Można użyć ścieżki względnej.

. .\Get-MrPSVersion.ps1

Można również użyć w pełni kwalifikowanej ścieżki.

. C:\Demo\Get-MrPSVersion.ps1

Jeśli część ścieżki jest przechowywana w zmiennej, można ją połączyć z pozostałą częścią ścieżki. Nie ma powodu, aby używać łączenia ciągów w celu połączenia zmiennej z pozostałą część ścieżki.

$Path = 'C:\'
. $Path\Get-MrPSVersion.ps1

Teraz, gdy sprawdzam funkcję PSDrive, Get-MrPSVersion funkcja istnieje.

Get-ChildItem -Path Function:\Get-MrPSVersion
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-MrPSVersion

Moduły skryptów

Moduł skryptu w programie PowerShell to po prostu plik zawierający co najmniej jedną funkcję, która jest zapisywana jako .PSM1 plik, a nie .PS1 plik.

Jak utworzyć moduł skryptu? Prawdopodobnie zgadywasz polecenie o nazwie podobnej do New-Module . Twoje założenie jest błędne. W programie PowerShell istnieje polecenie o nazwie , które New-Module tworzy moduł dynamiczny, a nie moduł skryptu. Zawsze należy przeczytać pomoc dla polecenia, nawet jeśli uważasz, że polecenie jest potrzebne.

help New-Module
NAME
    New-Module

SYNOPSIS
    Creates a new dynamic module that exists only in memory.

SYNTAX
    New-Module [-Name] <String> [-ScriptBlock] <ScriptBlock> [-ArgumentList <Object[]>]
    [-AsCustomObject] [-Cmdlet <String[]>] [-Function <String[]>] [-ReturnResult]
    [<CommonParameters>]

DESCRIPTION
    The New-Module cmdlet creates a dynamic module from a script block. The members of
    the dynamic module, such as functions and variables, are immediately available in
    the session and remain available until you close the session.

    Like static modules, by default, the cmdlets and functions in a dynamic module are
    exported and the variables and aliases are not. However, you can use the
    Export-ModuleMember cmdlet and the parameters of New-Module to override the defaults.

    You can also use the AsCustomObject parameter of New-Module to return the dynamic
    module as a custom object. The members of the modules, such as functions, are
    implemented as script methods of the custom object instead of being imported into
    the session.

    Dynamic modules exist only in memory, not on disk. Like all modules, the members of
    dynamic modules run in a private module scope that is a child of the global scope.
    Get-Module cannot get a dynamic module, but Get-Command can get the exported members.

    To make a dynamic module available to Get-Module , pipe a New-Module command to
    Import-Module, or pipe the module object that New-Module returns to Import-Module .
    This action adds the dynamic module to the Get-Module list, but it does not save the
    module to disk or make it persistent.

RELATED LINKS
    Online Version: http://go.microsoft.com/fwlink/?LinkId=821495
    Export-ModuleMember
    Get-Module
    Import-Module
    Remove-Module

REMARKS
    To see the examples, type: "get-help New-Module -examples".
    For more information, type: "get-help New-Module -detailed".
    For technical information, type: "get-help New-Module -full".
    For online help, type: "get-help New-Module -online"

W poprzednim rozdziale wspomnieliśmy, że funkcje powinny używać zatwierdzonych czasowników. W przeciwnym razie wygenerują komunikat ostrzegawczy podczas importowania modułu. Poniższy kod używa polecenia New-Module cmdlet do utworzenia dynamicznego modułu w pamięci. W tym module pokazano niezatwierdzone ostrzeżenie czasownika.

New-Module -Name MyModule -ScriptBlock {

    function Return-MrOsVersion {
        Get-CimInstance -ClassName Win32_OperatingSystem |
        Select-Object -Property @{label='OperatingSystem';expression={$_.Caption}}
    }

    Export-ModuleMember -Function Return-MrOsVersion

} | Import-Module
WARNING: The names of some imported commands from the module 'MyModule' include
unapproved verbs that might make them less discoverable. To find the commands with
unapproved verbs, run the Import-Module command again with the Verbose parameter. For a
list of approved verbs, type Get-Verb.

Chociaż polecenie cmdlet zostało użyte w poprzednim przykładzie, nie jest to polecenie do tworzenia modułów skryptów New-Module w programie PowerShell.

Zapisz następujące dwie funkcje w pliku o nazwie MyScriptModule.psm1 .

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Spróbuj wywołać jedną z funkcji.

Get-MrComputerName
Get-MrComputerName : The term 'Get-MrComputerName' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-MrComputerName
    + CategoryInfo          : ObjectNotFound: (Get-MrComputerName:String) [], CommandNot
   FoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Zostanie wygenerowany komunikat o błędzie z informacją, że nie można odnaleźć funkcji. Możesz również sprawdzić funkcję PSDrive, tak jak wcześniej, i przekonasz się, że nie istnieje.

Plik można zaimportować ręcznie za pomocą Import-Module polecenia cmdlet .

Import-Module C:\MyScriptModule.psm1

Funkcja automatycznego ładowania modułów została wprowadzona w programie PowerShell w wersji 3. Aby skorzystać z automatycznego ładowania modułu, moduł skryptu musi zostać zapisany w folderze o takiej samej nazwie podstawowej jak plik i w lokalizacji .PSM1 określonej w pliku $env:PSModulePath .

$env:PSModulePath
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\
Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules;C:\Program Files (x86)\Microsof
t SQL Server\130\Tools\PowerShell\Modules\

Wyniki są trudne do odczytania. Ponieważ ścieżki są oddzielone średnikami, można podzielić wyniki, aby zwrócić każdą ścieżkę w osobnym wierszu. Dzięki temu są łatwiejsze do odczytania.

$env:PSModulePath -split ';'
C:\Users\mike-ladm\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\Windows\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\

Pierwsze trzy ścieżki na liście są domyślne. Podczas SQL Server Management Studio dodano ostatnią ścieżkę. Aby automatyczne ładowanie modułu działało, plik musi się znaleźć w MyScriptModule.psm1 folderze o nazwie MyScriptModule bezpośrednio wewnątrz jednej z tych ścieżek.

Nie tak szybko. Dla mnie moja bieżąca ścieżka użytkownika nie jest pierwszą na liście. Prawie nigdy nie używam tej ścieżki, ponieważ loguje się Windows z innym użytkownikiem niż ten, za pomocą który uruchamiam program PowerShell. Oznacza to, że nie znajduje się on w normalnym folderze Documents.

Druga ścieżka to ścieżka AllUsers. Jest to lokalizacja, w której przechowuję wszystkie moje moduły.

Trzecia ścieżka znajduje się C:\Windows\System32 poniżej . Tylko firma Microsoft powinna przechowywać moduły w tej lokalizacji, ponieważ znajdują się w folderze systemów operacyjnych.

Gdy plik znajduje się w prawidłowej ścieżce, moduł zostanie załadowany automatycznie .PSM1 po wywołaniu jednego z jego poleceń.

Manifesty modułów

Wszystkie moduły powinny mieć manifest modułu. Manifest modułu zawiera metadane dotyczące modułu. Rozszerzenie pliku manifestu modułu to .PSD1 . Nie wszystkie pliki z .PSD1 rozszerzeniem są manifestami modułu. Mogą być również używane do takich czynności, jak przechowywanie części środowiska konfiguracji DSC. New-ModuleManifest Służy do tworzenia manifestu modułu. Ścieżka jest jedyną wymaganą wartością. Jednak moduł nie będzie działać, jeśli nie określono modułu RootModule. Jeśli zdecydujesz się przekazać moduł do repozytorium usługi NuGet przy użyciu modułu PowerShellGet, warto określić wartości Author i Description, ponieważ te wartości są wymagane w tym scenariuszu.

Wersja modułu bez manifestu to 0.0. Jest to nieumarły prezent, że moduł nie ma manifestu.

Get-Module -Name MyScriptModule
ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     0.0        myscriptmodule                      {Get-MrComputerName, Get-MrP...

Manifest modułu można utworzyć ze wszystkimi zalecanymi informacjami.

New-ModuleManifest -Path $env:ProgramFiles\WindowsPowerShell\Modules\MyScriptModule\MyScriptModule.psd1 -RootModule MyScriptModule -Author 'Mike F Robbins' -Description 'MyScriptModule' -CompanyName 'mikefrobbins.com'

Jeśli którakolwiek z tych informacji zostanie pominięta podczas początkowego tworzenia manifestu modułu, można je dodać lub zaktualizować później przy użyciu narzędzia Update-ModuleManifest . Nie należy ponownie tworzyć manifestu przy użyciu funkcji po New-ModuleManifest jego utworzeniu, ponieważ identyfikator GUID zmieni się.

Definiowanie funkcji publicznych i prywatnych

Możesz mieć funkcje pomocnika, które mogą być prywatne i dostępne tylko dla innych funkcji w module. Nie są one przeznaczone do dostępu dla użytkowników modułu. Istnieje kilka różnych sposobów osiągnięcia tego celu.

Jeśli nie korzystasz z najlepszych rozwiązań i masz tylko plik, jedyną opcją jest użycie .PSM1 Export-ModuleMember polecenia cmdlet .

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Export-ModuleMember -Function Get-MrPSVersion

W poprzednim przykładzie tylko funkcja jest dostępna dla użytkowników modułu, ale ta funkcja jest dostępna dla innych funkcji Get-MrPSVersion Get-MrComputerName w samym module.

Get-Command -Module MyScriptModule

CommandType     Name                        Version    Source
-----------     ----                        -------    ------
Function        Get-MrPSVersion             1.0        MyScript...

Jeśli do modułu dodano manifest modułu (i należy), zalecamy określenie poszczególnych funkcji, które chcesz wyeksportować, w sekcji FunctionsToExport manifestu modułu.

FunctionsToExport = 'Get-MrPSVersion'

Nie trzeba używać zarówno w pliku, jak i w sekcji Export-ModuleMember .PSM1 FunctionsToExport manifestu modułu. Wystarczy jedno lub drugie.

Podsumowanie

W tym rozdziale opisano, jak przekształcić funkcje w moduł skryptu w programie PowerShell. Poznaliśmy również niektóre najlepsze rozwiązania dotyczące tworzenia modułów skryptów, takie jak tworzenie manifestu modułu dla modułu skryptu.

Przegląd

  1. Jak utworzyć moduł skryptu w programie PowerShell?
  2. Dlaczego ważne jest, aby funkcje używały zatwierdzonego zlecenia?
  3. Jak utworzyć manifest modułu w programie PowerShell?
  4. Jakie są dwie opcje eksportowania tylko niektórych funkcji z modułu?
  5. Co jest wymagane, aby moduły ładowały się automatycznie po wywołaniu polecenia?