Bab 10 - Modul Skrip

Mengubah satu liner dan skrip Anda di PowerShell menjadi alat yang dapat digunakan kembali menjadi lebih penting jika itu adalah sesuatu yang sering Anda gunakan. Mengemas fungsi Anda dalam modul skrip membuatnya terlihat dan terasa lebih profesional dan membuatnya lebih mudah dibagikan.

Fungsi Dot-Sourcing

Sesuatu yang tidak kita bicarakan di bab sebelumnya adalah fungsi sumber titik. Ketika fungsi dalam skrip bukan bagian dari modul, satu-satunya cara untuk memuatnya ke dalam memori adalah dengan sumber .PS1 titik file tempat file disimpan.

Fungsi berikut telah disimpan sebagai Get-MrPSVersion.ps1.

function Get-MrPSVersion {
    $PSVersionTable
}

Saat Anda menjalankan skrip, tidak ada yang terjadi.

.\Get-MrPSVersion.ps1

Jika Anda mencoba memanggil fungsi, fungsi tersebut akan menghasilkan pesan kesalahan.

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

Anda dapat menentukan apakah fungsi dimuat ke dalam memori dengan memeriksa untuk melihat apakah fungsi tersebut ada di Fungsi 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

Masalah dengan memanggil skrip yang berisi fungsi adalah bahwa fungsi dimuat dalam cakupan Skrip . Ketika skrip selesai, cakupan tersebut dihapus dan fungsi dihapus dengannya.

Fungsi ini perlu dimuat ke dalam cakupan Global . Itu dapat dicapai dengan dot-sourcing skrip yang berisi fungsi . Jalur relatif dapat digunakan.

. .\Get-MrPSVersion.ps1

Jalur yang sepenuhnya memenuhi syarat juga dapat digunakan.

. C:\Demo\Get-MrPSVersion.ps1

Jika sebagian jalur disimpan dalam variabel, itu dapat dikombinasikan dengan sisa jalur. Tidak ada alasan untuk menggunakan penggabungan string untuk menggabungkan variabel bersama dengan sisa jalur.

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

Sekarang ketika saya memeriksa Fungsi PSDrive, Get-MrPSVersion fungsi ada.

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

Modul Skrip

Modul skrip di PowerShell hanyalah file yang berisi satu atau beberapa fungsi yang disimpan sebagai .PSM1 file, bukan .PS1 file.

Bagaimana Anda membuat modul skrip? Anda mungkin menebak dengan perintah bernama sesuatu seperti New-Module. Asumsimu salah. Meskipun ada perintah di PowerShell bernama New-Module, perintah tersebut membuat modul dinamis, bukan modul skrip. Selalu pastikan untuk membaca bantuan untuk perintah bahkan ketika Anda berpikir Anda telah menemukan perintah yang Anda butuhkan.

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"

Di bab sebelumnya, saya menyebutkan bahwa fungsi harus menggunakan kata kerja yang disetujui jika tidak, fungsi tersebut akan menghasilkan pesan peringatan saat modul diimpor. Kode berikut menggunakan New-Module cmdlet untuk membuat modul dinamis dalam memori. Modul ini menunjukkan peringatan kata kerja yang tidak disetujui.

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.

Hanya untuk menegaskan kembali, meskipun New-Module cmdlet digunakan dalam contoh sebelumnya, itu bukan perintah untuk membuat modul skrip di PowerShell.

Simpan dua fungsi berikut dalam file bernama MyScriptModule.psm1.

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Cobalah untuk memanggil salah satu fungsi.

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

Pesan kesalahan dihasilkan yang mengatakan fungsi tidak dapat ditemukan. Anda juga dapat memeriksa Fungsi PSDrive seperti sebelumnya dan Anda akan menemukan bahwa itu juga tidak ada di sana.

Anda dapat mengimpor file secara manual dengan Import-Module cmdlet.

Import-Module C:\MyScriptModule.psm1

Fitur autoloading modul diperkenalkan di PowerShell versi 3. Untuk memanfaatkan beban otomatis modul, modul skrip perlu disimpan dalam folder dengan nama .PSM1 dasar yang sama dengan file dan di lokasi yang ditentukan di $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\

Hasilnya sulit dibaca. Karena jalur dipisahkan oleh titik koma, Anda dapat membagi hasil untuk mengembalikan setiap jalur pada baris terpisah. Ini membuatnya lebih mudah dibaca.

$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\

Tiga jalur pertama dalam daftar adalah default. Ketika SQL Server Management Studio diinstal, SQL Server Management Studio menambahkan jalur terakhir. Agar beban otomatis modul berfungsi, MyScriptModule.psm1 file harus terletak di folder bernama MyScriptModule langsung di dalam salah satu jalur tersebut.

Tidak begitu cepat. Bagi saya, jalur pengguna saya saat ini bukan yang pertama dalam daftar. Saya hampir tidak pernah menggunakan jalur itu karena saya masuk ke Windows dengan pengguna yang berbeda dari yang saya gunakan untuk menjalankan PowerShell. Itu berarti tidak terletak di folder Dokumen normal saya.

Jalur kedua adalah jalur AllUsers . Ini adalah lokasi di mana saya menyimpan semua modul saya.

Jalur ketiga berada di bawah .C:\Windows\System32 Hanya Microsoft yang harus menyimpan modul di lokasi tersebut karena berada dalam folder sistem operasi.

.PSM1 Setelah file terletak di jalur yang benar, modul akan dimuat secara otomatis ketika salah satu perintahnya dipanggil.

Manifes Modul

Semua modul harus memiliki manifes modul. Manifes modul berisi metadata tentang modul Anda. Ekstensi file untuk file manifes modul adalah .PSD1. Tidak semua file dengan .PSD1 ekstensi adalah manifes modul. Mereka juga dapat digunakan untuk hal-hal seperti menyimpan bagian lingkungan dari konfigurasi DSC. New-ModuleManifest digunakan untuk membuat manifes modul. Jalur adalah satu-satunya nilai yang diperlukan. Namun, modul tidak akan berfungsi jika RootModule tidak ditentukan. Sebaiknya tentukan Penulis dan Deskripsi jika Anda memutuskan untuk mengunggah modul Anda ke repositori NuGet dengan PowerShellGet karena nilai tersebut diperlukan dalam skenario tersebut.

Versi modul tanpa manifes adalah 0.0. Ini adalah hadiah mati bahwa modul tidak memiliki manifes.

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

Manifes modul dapat dibuat dengan semua informasi yang direkomendasikan.

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

Jika salah satu informasi ini terlewatkan selama pembuatan awal manifes modul, informasi ini dapat ditambahkan atau diperbarui nanti menggunakan Update-ModuleManifest. Jangan buat ulang manifes menggunakan New-ModuleManifest setelah dibuat karena GUID akan berubah.

Menentukan Fungsi Publik dan Privat

Anda mungkin memiliki fungsi pembantu yang mungkin ingin Anda jadikan privat dan hanya dapat diakses oleh fungsi lain dalam modul. Mereka tidak dimaksudkan untuk dapat diakses oleh pengguna modul Anda. Ada beberapa cara berbeda untuk mencapai hal ini.

Jika Anda tidak mengikuti praktik terbaik dan hanya memiliki .PSM1 file, maka satu-satunya opsi Anda adalah menggunakan Export-ModuleMember cmdlet.

function Get-MrPSVersion {
    $PSVersionTable
}

function Get-MrComputerName {
    $env:COMPUTERNAME
}

Export-ModuleMember -Function Get-MrPSVersion

Dalam contoh sebelumnya, hanya Get-MrPSVersion fungsi yang tersedia untuk pengguna modul Anda, tetapi Get-MrComputerName fungsi tersedia untuk fungsi lain dalam modul itu sendiri.

Get-Command -Module MyScriptModule
CommandType     Name                                            Version    Source
-----------     ----                                            -------    ------
Function        Get-MrPSVersion                                 1.0        MyScriptModule

Jika Anda telah menambahkan manifes modul ke modul Anda (dan Anda harus), maka saya sarankan menentukan fungsi individual yang ingin Anda ekspor di bagian FunctionsToExport dari manifes modul.

FunctionsToExport = 'Get-MrPSVersion'

Tidak perlu menggunakan baik di .PSM1 file maupun Export-ModuleMember bagian FunctionsToExport dari manifes modul. Satu atau yang lain sudah cukup.

Ringkasan

Dalam bab ini Anda telah mempelajari cara mengubah fungsi Anda menjadi modul skrip di PowerShell. Anda juga telah mempelajari beberapa praktik terbaik untuk membuat modul skrip seperti membuat manifes modul untuk modul skrip Anda.

Tinjauan

  1. Bagaimana Anda membuat modul skrip di PowerShell?
  2. Mengapa penting bagi fungsi Anda untuk menggunakan kata kerja yang disetujui?
  3. Bagaimana Anda membuat manifes modul di PowerShell?
  4. Apa dua opsi untuk mengekspor hanya fungsi tertentu dari modul Anda?
  5. Apa yang diperlukan agar modul Anda dimuat secara otomatis saat perintah dipanggil?