10. fejezet – parancsfájl-modulokChapter 10 - Script modules

Az egysoros és a PowerShell-parancsfájlok újrafelhasználható eszközökre való bekapcsolása még ennél is fontosabb lesz, ha valami gyakran fog használni.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. A függvények egy parancsfájl-modulban való csomagolása lehetővé teszi, hogy a szakemberek lássák és jobban érezzék magukat, és könnyebben megoszthatják őket.Packaging your functions in a script module makes them look and feel more professional and makes them easier to share.

Pont – beszerzés függvényekDot-Sourcing Functions

Az előző fejezetben nem beszéltünk a pont-beszerzés függvényekről.Something that we didn't talk about in the previous chapter is dot-sourcing functions. Ha egy parancsfájl egyik funkciója nem része egy modulnak, a memóriába való betöltésének egyetlen módja, ha a .PS1 fájlt a fájlba menti.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.

A következő függvény lett mentve: Get-MrPSVersion.ps1 .The following function has been saved as Get-MrPSVersion.ps1.

function Get-MrPSVersion {
    $PSVersionTable
}

A parancsfájl futtatásakor semmi nem történik.When you run the script, nothing happens.

.\Get-MrPSVersion.ps1

Ha megpróbálja meghívni a függvényt, hibaüzenetet hoz létre.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

Megtudhatja, hogy a függvények betöltődik-e a memóriába. Ehhez ellenőrizze, hogy létezik-e a függvény 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

A függvényt tartalmazó parancsfájl meghívásával kapcsolatos probléma az, hogy a függvények betöltődik a parancsfájl hatókörében.The problem with calling the script that contains the function is that the functions are loaded in the Script scope. A szkript befejezésekor a rendszer eltávolítja a hatókört, és eltávolítja a függvényt.When the script completes, that scope is removed and the function is removed with it.

A függvényt be kell tölteni a globális hatókörbe.The function needs to be loaded into the Global scope. Ezt a funkciót tartalmazó szkriptet a pont-beszerzéssel lehet elvégezni.That can be accomplished by dot-sourcing the script that contains the function. A relatív elérési út használható.The relative path can be used.

. .\Get-MrPSVersion.ps1

A teljesen minősített elérési út is használható.The fully qualified path can also be used.

. C:\Demo\Get-MrPSVersion.ps1

Ha az elérési út egy része egy változóban van tárolva, akkor az elérési út hátralévő részével kombinálható.If a portion of the path is stored in a variable, it can be combined with the remainder of the path. Nincs ok arra, hogy karakterlánc-összefűzéssel egyesítse a változót az elérési út hátralévő részével együtt.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

Most, amikor bejelölem a PSDrive függvényt , a Get-MrPSVersion függvény létezik.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

Parancsfájl-modulokScript Modules

A PowerShell parancsfájl-modulja egyszerűen egy olyan fájl, amely egy vagy több olyan függvényt tartalmaz, amely fájl helyett fájlként lett mentve .PSM1 .PS1 .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.

Hogyan hozhat létre parancsfájl-modult?How do you create a script module? Valószínűleg egy hasonló nevű paranccsal találgatás New-Module .You're probably guessing with a command named something like New-Module. A feltételezés helytelen lenne.Your assumption would be wrong. Egy nevű PowerShell-paranccsal a parancs egy New-Module dinamikus modult hoz létre, nem pedig parancsfájl-modult.While there is a command in PowerShell named New-Module, that command creates a dynamic module, not a script module. Mindig olvassa el a parancs súgóját akkor is, ha úgy gondolja, hogy megtalálta a szükséges parancsot.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"

Az előző fejezetben említettem, hogy a függvényeknek jóváhagyott műveleteket kell használniuk, máskülönben figyelmeztető üzenetet hoznak majd a modul importálásakor.In the previous chapter, I mentioned that functions should use approved verbs otherwise they'll generate a warning message when the module is imported. A következő kód a New-Module parancsmag használatával dinamikus modult hoz létre a memóriában.The following code uses the New-Module cmdlet to create a dynamic module in memory. Ez a modul a nem jóváhagyott műveletekre vonatkozó figyelmeztetést mutatja be.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.

Csak hogy megismételje, bár a New-Module parancsmagot az előző példában használták, ez nem az a parancs, amellyel parancsfájl-modulokat hozhat létre a PowerShellben.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.

Mentse a következő két függvényt egy nevű fájlba MyScriptModule.psm1 .Save the following two functions in a file named MyScriptModule.psm1.

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Próbálkozzon a függvények egyikének meghívásával.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

Hibaüzenet jön létre, amely azt jelzi, hogy a függvény nem található.An error message is generated saying the function can't be found. Azt is megteheti, hogy az előzőekben PSDrive a függvényt , és megtalálhatja, hogy ott sem létezik.You could also check the Function PSDrive just like before and you'll find that it doesn't exist there either.

Manuálisan importálhatja a fájlt a Import-Module parancsmaggal.You could manually import the file with the Import-Module cmdlet.

Import-Module C:\MyScriptModule.psm1

A modul automatikus betöltési funkciója a PowerShell 3-as verziójában lett bevezetve.The module autoloading feature was introduced in PowerShell version 3. A modul automatikus betöltésének kihasználásához a parancsfájl-modult egy olyan mappába kell menteni, amelynek az alapneve megegyezik a fájl nevével, valamint a ben .PSM1 megadott helyen $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\

Az eredmények nehezen olvashatók.The results are difficult to read. Mivel az elérési utak pontosvesszővel vannak elválasztva, az eredményeket feloszthatja, hogy az egyes útvonalakat külön sorban lehessen visszaadni.Since the paths are separated by a semicolon, you can split the results to return each path on a separate line. Így könnyebben olvashatók.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\

A lista első három útvonala az alapértelmezett.The first three paths in the list are the default. SQL Server Management Studio telepítése után az utolsó elérési utat adta hozzá.When SQL Server Management Studio was installed, it added the last path. A modul automatikus betöltésének működéséhez a MyScriptModule.psm1 fájlnak egy, az MyScriptModule elérési utak egyikén belül található mappában kell lennie.For module autoloading to work, the MyScriptModule.psm1 file needs to be located in a folder named MyScriptModule directly inside one of those paths.

Nem olyan gyorsan.Not so fast. Nekem a jelenlegi felhasználói útvonalom nem az első a listában.For me, my current user path isn't the first one in the list. Szinte soha nem használom ezt az elérési utat, mert egy másik felhasználóval jelentkezik be a Windowsba, mint amit a PowerShell futtatásához használok.I almost never use that path since I log into Windows with a different user than the one I use to run PowerShell. Ez azt jelenti, hogy nem a szokásos dokumentumok mappában található.That means it's not located in my normal Documents folder.

A második útvonal a AllUsers elérési útja.The second path is the AllUsers path. Ez az a hely, ahol az összes saját modult tárolom.This is the location where I store all of my modules.

A harmadik útvonal alul van C:\Windows\System32 .The third path is underneath C:\Windows\System32. Csak a Microsoftnak kell tárolnia modulokat az adott helyen, mert az az operációs rendszer mappában található.Only Microsoft should be storing modules in that location since it resides within the operating systems folder.

Ha a .PSM1 fájl a megfelelő elérési úton található, akkor a modul automatikusan betöltődik, ha az egyik parancsát meghívja.Once the .PSM1 file is located in the correct path, the module will load automatically when one of its commands is called.

Modul-jegyzékfájlokModule Manifests

Minden modulnak rendelkeznie kell egy modul-jegyzékfájlval.All modules should have a module manifest. A modul jegyzékfájlja a modulhoz tartozó metaadatokat tartalmaz.A module manifest contains metadata about your module. A modul jegyzékfájljának fájl kiterjesztése a következő: .PSD1 .The file extension for a module manifest file is .PSD1. Nem minden .PSD1 kiterjesztéssel rendelkező fájl modul-jegyzékfájl.Not all files with a .PSD1 extension are module manifests. Olyan dolgokhoz is felhasználhatók, mint például a DSC-konfiguráció környezeti részének tárolása.They can also be used for things such as storing the environmental portion of a DSC configuration. New-ModuleManifestmodul-jegyzékfájl létrehozásához használatos.New-ModuleManifest is used to create a module manifest. Az elérési út az egyetlen szükséges érték.Path is the only value that's required. A modul azonban nem fog működni, ha nincs megadva a RootModule .However, the module won't work if RootModule isn't specified. Érdemes megadnia a szerzőt és a leírást arra az esetre, ha úgy dönt, hogy feltölti a modult egy NuGet adattárba a PowerShellGet, mivel ezek az értékek szükségesek ebben az esetben.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.

A modul jegyzékfájl nélküli verziója 0,0.The version of a module without a manifest is 0.0. Ez egy elhalt Giveaway, amely szerint a modulnak nincs jegyzékfájlja.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...

A modul jegyzékfájlja az összes javasolt információval létrehozható.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'

Ha bármelyik információ kimarad a modul jegyzékfájljának kezdeti létrehozásakor, azt később is hozzáadhatja vagy frissítheti a használatával 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. Ne hozza létre újra a jegyzékfájlt a már létrehozott példányok használatával New-ModuleManifest , mert a GUID megváltoztatja.Don't recreate the manifest using New-ModuleManifest once it's already created because the GUID will change.

Nyilvános és privát függvények definiálásaDefining Public and Private Functions

Lehet, hogy olyan segítő függvények is lehetnek, amelyeknek privátnek kell lenniük, és csak a modulban lévő más függvények férhetnek hozzá.You may have helper functions that you may want to be private and only accessible by other functions within the module. Nem a modul felhasználói számára készültek.They are not intended to be accessible to users of your module. Ezt többféleképpen is elvégezheti.There are a couple of different ways to accomplish this.

Ha nem követi az ajánlott eljárásokat, és csak egy fájllal rendelkezik .PSM1 , akkor az egyetlen lehetőség a Export-ModuleMember parancsmag használata.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

Az előző példában csak a Get-MrPSVersion függvény érhető el a modul felhasználói számára, de a Get-MrComputerName függvény a modulban lévő más függvények számára is elérhető.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...

Ha hozzáadta a modul jegyzékfájlját a modulhoz (és Ön), akkor azt javasoljuk, hogy adja meg az exportálni kívánt egyes függvényeket a modul jegyzékfájljának FunctionsToExport szakaszában.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'

Export-ModuleMember .PSM1 A modul jegyzékfájljának fájl és FunctionsToExport szakaszában nem szükséges mindkettőt használni.It's not necessary to use both Export-ModuleMember in the .PSM1 file and the FunctionsToExport section of the module manifest. Az egyik vagy a másik elegendő.One or the other is sufficient.

ÖsszefoglalásSummary

Ebben a fejezetben megtanulta, hogyan kapcsolhatja be a függvényeit egy parancsfájl-modulba a PowerShellben.In this chapter you've learned how to turn your functions into a script module in PowerShell. Emellett a parancsfájl-modulok létrehozásával kapcsolatos ajánlott eljárásokat is felhasználta, például egy modul jegyzékfájljának létrehozását a parancsfájl-modulhoz.You've also leaned some of the best practices for creating script modules such as creating a module manifest for your script module.

ÁttekintésReview

  1. Hogyan hozhat létre parancsfájl-modult a PowerShellben?How do you create a script module in PowerShell?
  2. Miért fontos, hogy a függvények jóváhagyott műveletet használjanak?Why is it important for your functions to use an approved verb?
  3. Hogyan hozhat létre modul-jegyzékfájlt a PowerShellben?How do you create a module manifest in PowerShell?
  4. Milyen két lehetőség van a modulból csak bizonyos függvények exportálására?What are the two options for exporting only certain functions from your module?
  5. Mi szükséges ahhoz, hogy a modulok automatikusan betöltsenek egy parancs meghívásakor?What is required for your modules to load automatically when a command is called?