Rozdział 10 — moduły skryptówChapter 10 - Script modules

Włączenie tych narzędzi i skryptów w programie PowerShell do narzędzia do wielokrotnego użytku będzie jeszcze ważniejsze, jeśli jest to coś, co jest często używane.Turning your one-liners and scripts in PowerShell into reusable tools becomes even more important if it's something that you're going to use frequently. Pakowanie funkcji w module skryptu sprawia, że wyglądają i są bardziej profesjonalne i ułatwia ich udostępnianie.Packaging your functions in a script module makes them look and feel more professional and makes them easier to share.

Funkcje pozyskania kropekDot-Sourcing Functions

Coś, czego nie udało się w poprzednim rozdziale, jest funkcjami pozyskania punktów.Something that we didn't talk about in the previous chapter is dot-sourcing functions. Gdy funkcja w skrypcie nie jest częścią modułu, jedynym sposobem na załadowanie jej do pamięci jest umieszczenie .PS1 w nim pliku, w którym jest on zapisany.When a function in a script isn't part of a module, the only way to load it into memory is to dot-source the .PS1 file that it's saved in.

Następująca funkcja została zapisana jako Get-MrPSVersion.ps1 .The following function has been saved as Get-MrPSVersion.ps1.

function Get-MrPSVersion {
    $PSVersionTable
}

Po uruchomieniu skryptu nic się nie dzieje.When you run the script, nothing happens.

.\Get-MrPSVersion.ps1

Jeśli spróbujesz wywołać funkcję, generuje komunikat o błędzie.If you try to call the function, it generates an error message.

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żna określić, czy funkcje są ładowane do pamięci przez sprawdzenie, czy istnieją w funkcji PSDrive.You can determine if functions are loaded into memory by checking to see if they exist on the Function PSDrive.

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łaniem skryptu, który zawiera funkcję, jest to, że funkcje są ładowane w zakresie skryptu .The problem with calling the script that contains the function is that the functions are loaded in the Script scope. Po zakończeniu działania skryptu ten zakres jest usuwany, a funkcja jest usuwana.When the script completes, that scope is removed and the function is removed with it.

Funkcja musi zostać załadowana do zakresu globalnego .The function needs to be loaded into the Global scope. Można to osiągnąć za pomocą kropki dla skryptu, który zawiera funkcję.That can be accomplished by dot-sourcing the script that contains the function. Można użyć ścieżki względnej.The relative path can be used.

. .\Get-MrPSVersion.ps1

Można również użyć w pełni kwalifikowanej ścieżki.The fully qualified path can also be used.

. 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.If a portion of the path is stored in a variable, it can be combined with the remainder of the path. Nie istnieje powód, aby użyć łączenia ciągów do łączenia zmiennej ze resztą ścieżki.There's no reason to use string concatenation to combine the variable together with the remainder of the path.

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

Teraz po zaznaczeniu funkcji PSDrive Get-MrPSVersion istnieje funkcja.Now when I check the Function PSDrive, the Get-MrPSVersion function exists.

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

Moduły skryptówScript Modules

Moduł skryptu w programie PowerShell jest po prostu plikiem zawierającym co najmniej jedną funkcję, która jest zapisywana jako .PSM1 plik, a nie .PS1 plik.A script module in PowerShell is simply a file containing one or more functions that's saved as a .PSM1 file instead of a .PS1 file.

Jak utworzyć moduł skryptu?How do you create a script module? Prawdopodobnie nastąpi odpuszczenie przy użyciu polecenia o nazwie podobnej do New-Module .You're probably guessing with a command named something like New-Module. Twoje założenie będzie nieprawidłowe.Your assumption would be wrong. Gdy w programie PowerShell istnieje polecenie o nazwie New-Module , to polecenie tworzy moduł dynamiczny, a nie moduł skryptu.While there is a command in PowerShell named New-Module, that command creates a dynamic module, not a script module. Pamiętaj o tym, aby przeczytać pomoc dotyczącą polecenia, nawet gdy sądzisz, że można znaleźć potrzebne polecenie.Always be sure to read the help for a command even when you think you've found the command you need.

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 podano, że funkcje powinny używać zatwierdzonych czasowników, w przeciwnym razie wygenerują komunikat ostrzegawczy po zaimportowaniu modułu.In the previous chapter, I mentioned that functions should use approved verbs otherwise they'll generate a warning message when the module is imported. Poniższy kod używa New-Module polecenia cmdlet do utworzenia modułu dynamicznego w pamięci.The following code uses the New-Module cmdlet to create a dynamic module in memory. Ten moduł pokazuje ostrzeżenie niezatwierdzonego zlecenia.This module demonstrates the unapproved verb warning.

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.

Tylko do ponownej iteracji, chociaż polecenie New-Module cmdlet zostało użyte w poprzednim przykładzie, to nie jest poleceniem do tworzenia modułów skryptów w programie PowerShell.Just to reiterate, although the New-Module cmdlet was used in the previous example, that's not the command for creating script modules in PowerShell.

Zapisz poniższe dwie funkcje w pliku o nazwie MyScriptModule.psm1 .Save the following two functions in a file named MyScriptModule.psm1.

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Spróbuj wywołać jedną z funkcji.Try to call one of the functions.

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

Generowany jest komunikat o błędzie z informacją o tym, że nie można znaleźć funkcji.An error message is generated saying the function can't be found. Możesz również sprawdzić funkcję PSDrive, tak jak wcześniej, i sprawdzić, czy jeszcze nie istnieje.You could also check the Function PSDrive just like before and you'll find that it doesn't exist there either.

Plik można ręcznie zaimportować przy użyciu Import-Module polecenia cmdlet.You could manually import the file with the Import-Module cmdlet.

Import-Module C:\MyScriptModule.psm1

Funkcja autoładowania modułu została wprowadzona w programie PowerShell w wersji 3.The module autoloading feature was introduced in PowerShell version 3. Aby skorzystać z funkcji autoładowania modułu, moduł skryptu musi być zapisany w folderze o tej samej nazwie podstawowej co .PSM1 plik i w lokalizacji określonej w $env:PSModulePath .To take advantage of module autoloading, a script module needs to be saved in a folder with the same base name as the .PSM1 file and in a location specified in $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.The results are difficult to read. Ponieważ ścieżki są rozdzielone średnikami, można podzielić wyniki, aby zwrócić każdą ścieżkę w osobnym wierszu.Since the paths are separated by a semicolon, you can split the results to return each path on a separate line. Ułatwia to odczytywanie.This makes them easier to read.

$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.The first three paths in the list are the default. Po zainstalowaniu SQL Server Management Studio została dodana Ostatnia ścieżka.When SQL Server Management Studio was installed, it added the last path. Aby ładowanie modułu działało, plik musi znajdować się MyScriptModule.psm1 w folderze o nazwie MyScriptModule bezpośrednio w jednej z tych ścieżek.For module autoloading to work, the MyScriptModule.psm1 file needs to be located in a folder named MyScriptModule directly inside one of those paths.

Nie tak szybko.Not so fast. Dla mnie bieżąca ścieżka użytkownika nie jest pierwszą listą.For me, my current user path isn't the first one in the list. Prawie nigdy nie korzystam z tej ścieżki, ponieważ loguję się do systemu Windows przy użyciu innego użytkownika niż używany do uruchamiania programu PowerShell.I almost never use that path since I log into Windows with a different user than the one I use to run PowerShell. Oznacza to, że nie znajduje się w folderze Moje dokumenty normalne.That means it's not located in my normal Documents folder.

Druga ścieżka jest ścieżką ALLUSERS .The second path is the AllUsers path. Jest to lokalizacja, w której są przechowywane wszystkie moje moduły.This is the location where I store all of my modules.

Trzecia ścieżka jest poniżej C:\Windows\System32 .The third path is underneath C:\Windows\System32. Tylko firma Microsoft powinna przechowywać moduły w tej lokalizacji, ponieważ znajdują się w folderze systemy operacyjne.Only Microsoft should be storing modules in that location since it resides within the operating systems folder.

Gdy plik znajduje się .PSM1 w poprawnej ścieżce, moduł zostanie załadowany automatycznie po wywołaniu jednego z jego poleceń.Once the .PSM1 file is located in the correct path, the module will load automatically when one of its commands is called.

Manifesty modułówModule Manifests

Wszystkie moduły powinny mieć manifest modułu.All modules should have a module manifest. Manifest modułu zawiera metadane dotyczące modułu.A module manifest contains metadata about your module. Rozszerzenie pliku manifestu modułu to .PSD1 .The file extension for a module manifest file is .PSD1. Nie wszystkie pliki z .PSD1 rozszerzeniem są manifestami modułu.Not all files with a .PSD1 extension are module manifests. Mogą one być również używane w przypadku elementów, takich jak przechowywanie części środowiska konfiguracji DSC.They can also be used for things such as storing the environmental portion of a DSC configuration. New-ModuleManifestsłuży do tworzenia manifestu modułu.New-ModuleManifest is used to create a module manifest. Ścieżka jest jedyną wymaganą wartością.Path is the only value that's required. Jednak moduł nie będzie działał, jeśli RootModule nie zostanie określony.However, the module won't work if RootModule isn't specified. Dobrym pomysłem jest określenie autora i opisu w przypadku, gdy użytkownik zdecyduje się na przekazanie modułu do repozytorium NuGet za pomocą PowerShellGet, ponieważ te wartości są wymagane w tym scenariuszu.It's a good idea to specify Author and Description in case you decide to upload your module to a NuGet repository with PowerShellGet since those values are required in that scenario.

Wersja modułu bez manifestu to 0,0.The version of a module without a manifest is 0.0. To jest martwa Giveaway, że moduł nie ma manifestu.This is a dead giveaway that the module doesn't have a manifest.

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.The module manifest can be created with all of the recommended information.

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

Jeśli którekolwiek z tych informacji zostanie pominięte podczas początkowego tworzenia manifestu modułu, można je dodać lub zaktualizować później przy użyciu Update-ModuleManifest .If any of this information is missed during the initial creation of the module manifest, it can be added or updated later using Update-ModuleManifest. Nie twórz ponownie manifestu, używając New-ModuleManifest już utworzonego elementu, ponieważ identyfikator GUID zmieni się.Don't recreate the manifest using New-ModuleManifest once it's already created because the GUID will change.

Definiowanie funkcji publicznych i prywatnychDefining Public and Private Functions

Mogą być dostępne funkcje pomocnika, które mogą być prywatne i dostępne tylko przez inne funkcje w module.You may have helper functions that you may want to be private and only accessible by other functions within the module. Nie są one przeznaczone do dostępności dla użytkowników modułu.They are not intended to be accessible to users of your module. Istnieje kilka różnych sposobów osiągnięcia tego celu.There are a couple of different ways to accomplish this.

Jeśli nie korzystasz z najlepszych rozwiązań i masz tylko .PSM1 plik, jedyną opcją jest użycie Export-ModuleMember polecenia cmdlet.If you're not following the best practices and only have a .PSM1 file, then your only option is to use the Export-ModuleMember cmdlet.

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Export-ModuleMember -Function Get-MrPSVersion

W poprzednim przykładzie tylko Get-MrPSVersion Funkcja jest dostępna dla użytkowników modułu, ale Get-MrComputerName Funkcja jest dostępna dla innych funkcji w ramach modułu.In the previous example, only the Get-MrPSVersion function is available to the users of your module, but the Get-MrComputerName function is available to other functions within the module itself.

Get-Command -Module MyScriptModule

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

Jeśli dodano manifest modułu do modułu (i należy), zalecamy określenie poszczególnych funkcji, które mają zostać wyeksportowane, w sekcji FunctionsToExport manifestu modułu.If you've added a module manifest to your module (and you should), then I recommend specifying the individual functions you want to export in the FunctionsToExport section of the module manifest.

FunctionsToExport = 'Get-MrPSVersion'

Nie jest konieczne używanie obu elementów Export-ModuleMember w .PSM1 pliku i sekcji FunctionsToExport manifestu modułu.It's not necessary to use both Export-ModuleMember in the .PSM1 file and the FunctionsToExport section of the module manifest. Jeden lub drugi jest wystarczający.One or the other is sufficient.

PodsumowanieSummary

W tym rozdziale przedstawiono sposób przekształcania funkcji w moduł skryptu w programie PowerShell.In this chapter you've learned how to turn your functions into a script module in PowerShell. Przedstawiono także niektóre najlepsze rozwiązania dotyczące tworzenia modułów skryptów, takich jak tworzenie manifestu modułu dla modułu skryptu.You've also leaned some of the best practices for creating script modules such as creating a module manifest for your script module.

PrzeglądReview

  1. Jak utworzyć moduł skryptu w programie PowerShell?How do you create a script module in PowerShell?
  2. Dlaczego ważne jest, aby funkcje korzystały z zatwierdzonego zlecenia?Why is it important for your functions to use an approved verb?
  3. Jak utworzyć manifest modułu w programie PowerShell?How do you create a module manifest in PowerShell?
  4. Jakie są dwie opcje eksportowania tylko niektórych funkcji z modułu?What are the two options for exporting only certain functions from your module?
  5. Co jest wymagane, aby moduły były ładowane automatycznie po wywołaniu polecenia?What is required for your modules to load automatically when a command is called?