Bagikan melalui


11. Modul

Catatan editorial

Penting

Windows PowerShell Language Specification 3.0 diterbitkan pada Desember 2012 dan didasarkan pada Windows PowerShell 3.0. Spesifikasi ini tidak mencerminkan status PowerShell saat ini. Tidak ada rencana untuk memperbarui dokumentasi ini untuk mencerminkan status saat ini. Dokumentasi ini disajikan di sini untuk referensi historis.

Dokumen spesifikasi tersedia sebagai dokumen Microsoft Word dari Pusat Unduhan Microsoft di: https://www.microsoft.com/download/details.aspx?id=36389 Dokumen Word telah dikonversi untuk presentasi di sini di Microsoft Learn. Selama konversi, beberapa perubahan editorial telah dilakukan untuk mengakomodasi pemformatan untuk platform Dokumen. Beberapa kesalahan ketik dan kesalahan kecil telah dikoreksi.

11.1 Pengantar

Seperti yang dinyatakan dalam §3.14, modul adalah unit yang dapat digunakan kembali mandiri yang memungkinkan kode PowerShell dipartisi, diatur, dan diabstraksi. Modul dapat berisi satu atau beberapa anggota modul , yang merupakan perintah (seperti cmdlet dan fungsi) dan item (seperti variabel dan alias). Nama-nama anggota ini dapat dirahasiakan ke modul atau mereka mungkin diekspor ke sesi tempat modul diimpor.

Ada tiga jenis modul yang berbeda: manifes, skrip, dan biner. Modul manifes adalah file yang berisi informasi tentang modul, dan mengontrol aspek tertentu dari penggunaan modul tersebut. Modul skrip adalah file skrip PowerShell dengan ekstensi file .psm1 alih-alih .ps1. Modul biner berisi jenis kelas yang menentukan cmdlet dan penyedia. Tidak seperti modul skrip, modul biner ditulis dalam bahasa yang dikompilasi. Modul biner tidak tercakup dalam spesifikasi ini.

Modul biner adalah rakitan .NET (yaitu DLL) yang dikompilasi terhadap pustaka PowerShell.

Modul dapat bersarang; itu artinya, satu modul dapat mengimpor modul lain. Modul yang memiliki modul berlapis terkait adalah modul akar .

Saat sesi PowerShell dibuat, secara default, tidak ada modul yang diimpor.

Ketika modul diimpor, jalur pencarian yang digunakan untuk menemukannya ditentukan oleh variabel lingkungan PSModulePath.

Cmdlet berikut menangani modul:

  • Get-Module: Mengidentifikasi modul yang telah, atau dapat diimpor
  • Import-Module : Menambahkan satu atau beberapa modul ke sesi saat ini (lihat §11,4)
  • Export-ModuleMember: Mengidentifikasi anggota modul yang akan diekspor
  • Remove-Module : Menghapus satu atau beberapa modul dari sesi saat ini (lihat §11,5)
  • Modul Baru : Membuat modul dinamis (lihat §11,7)

11.2 Menulis modul skrip

Modul skrip adalah file skrip. Pertimbangkan modul skrip berikut:

function Convert-CentigradeToFahrenheit ([double]$tempC) {
    return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit

function Convert-FahrenheitToCentigrade ([double]$tempF) {
    return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade

Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c

Modul ini berisi dua fungsi, yang masing-masing memiliki alias. Secara default, semua nama fungsi, dan hanya nama fungsi yang diekspor. Namun, setelah cmdlet Export-ModuleMember digunakan untuk mengekspor apa pun, maka hanya hal-hal yang diekspor secara eksplisit yang akan diekspor. Serangkaian perintah dan item dapat diekspor dalam satu panggilan atau sejumlah panggilan ke cmdlet ini; panggilan tersebut bersifat kumulatif untuk sesi saat ini.

11.3 Menginstal modul skrip

Modul skrip didefinisikan dalam file skrip, dan modul dapat disimpan di direktori apa pun. Variabel lingkungan PSModulePath menunjuk ke sekumpulan direktori yang akan dicari ketika cmdlet terkait modul mencari modul yang namanya tidak menyertakan jalur yang sepenuhnya memenuhi syarat. Jalur pencarian tambahan dapat disediakan; misalnya

$Env:PSModulePath = $Env:PSModulePath + ";<additional-path>"

Jalur tambahan apa pun yang ditambahkan hanya memengaruhi sesi saat ini.

Atau, jalur yang sepenuhnya memenuhi syarat dapat ditentukan saat modul diimpor.

11.4 Mengimpor modul skrip

Sebelum sumber daya dalam modul dapat digunakan, modul tersebut harus diimpor ke sesi saat ini, menggunakan cmdlet Import-Module. Import-Module dapat membatasi sumber daya yang sebenarnya diimpor.

Saat modul diimpor, file skripnya dijalankan. Proses tersebut dapat dikonfigurasi dengan menentukan satu atau beberapa parameter dalam file skrip, dan meneruskan argumen yang sesuai melalui parameter ArgumentList Import-Module.

Pertimbangkan skrip berikut yang menggunakan fungsi dan alias ini yang ditentukan dalam §11,2:

Import-Module -Verbose "E:\Scripts\Modules\PSTest_Temperature"

"0 degrees C is " + (Convert-CentigradeToFahrenheit 0) + " degrees F"
"100 degrees C is " + (c2f 100) + " degrees F"
"32 degrees F is " + (Convert-FahrenheitToCentigrade 32) + " degrees C"
"212 degrees F is " + (f2c 212) + " degrees C"

Mengimpor modul menyebabkan konflik nama ketika perintah atau item dalam modul memiliki nama yang sama dengan perintah atau item dalam sesi. Konflik nama menghasilkan nama yang disembunyikan atau diganti. Parameter Prefiks Import-Module dapat digunakan untuk menghindari konflik penamaan. Selain itu, parameter Alias, Cmdlet, Function, dan Variabel dapat membatasi pemilihan perintah yang akan diimpor, sehingga mengurangi kemungkinan konflik nama.

Bahkan jika perintah disembunyikan, perintah dapat dijalankan dengan memenuhi syarat namanya dengan nama modul tempat perintah berasal. Misalnya, & M\F 100 memanggil fungsi F dalam modul M, dan meneruskannya argumen 100.

Ketika sesi menyertakan perintah dengan jenis yang sama dengan nama yang sama, seperti dua cmdlet dengan nama yang sama, secara default menjalankan perintah yang terakhir ditambahkan.

Lihat §3.5.6 untuk diskusi cakupan karena berkaitan dengan modul.

11.5 Menghapus modul skrip

Satu atau beberapa modul dapat dihapus dari sesi melalui cmdlet Remove-Module.

Menghapus modul tidak menghapus instalan modul.

Dalam modul skrip, dimungkinkan untuk menentukan kode yang akan dijalankan sebelum penghapusan modul tersebut, sebagai berikut:

$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { *on-removal-code* }

11.6 Beberapa Manifes modul

Seperti yang dinyatakan dalam §11.1, modul manifes adalah file yang berisi informasi tentang modul, dan mengontrol aspek tertentu dari penggunaan modul tersebut.

Modul tidak perlu memiliki manifes yang sesuai, tetapi jika ya, manifes tersebut memiliki nama yang sama dengan modul yang dijelaskannya, tetapi dengan ekstensi file .psd1.

Manifes berisi subset terbatas skrip PowerShell, yang mengembalikan Hashtable yang berisi sekumpulan kunci. Kunci ini dan nilainya menentukan elemen manifes untuk modul tersebut. Artinya, mereka menjelaskan konten dan atribut modul, menentukan prasyarat apa pun, dan menentukan bagaimana komponen diproses.

Pada dasarnya, manifes adalah file data; namun, ini dapat berisi referensi ke jenis data, pernyataan if, dan operator aritmatika dan perbandingan. (Penugasan, definisi fungsi, dan perulangan tidak diizinkan.) Manifes juga memiliki akses baca ke variabel lingkungan dan dapat berisi panggilan ke cmdlet Join-Path, sehingga jalur dapat dibangun.

Nota

Catatan Editor: Dokumen asli berisi daftar kunci yang diizinkan dalam file manifes modul. Daftar tersebut sudah kedaluarsa dan tidak lengkap. Untuk daftar lengkap kunci dalam manifes modul, lihat New-ModuleManifest.

Satu-satunya kunci yang diperlukan adalah ModuleVersion.

Berikut adalah contoh manifes sederhana:

@{
ModuleVersion = '1.0'
Author = 'John Doe'
RequiredModules = @()
FunctionsToExport = 'Set*','Get*','Process*'
}

Kunci GUID memiliki nilai string. Ini menentukan GUID (Pengidentifikasi Unik Global) untuk modul. GUID dapat digunakan untuk membedakan modul-modul yang memiliki nama yang sama. Untuk membuat GUID baru, panggil metode [guid]::NewGuid().

11.7 Modul dinamis

Modul dinamis adalah modul yang dibuat dalam memori saat runtime oleh cmdlet New-Module; tidak dimuat dari disk. Pertimbangkan contoh berikut:

$sb = {
    function Convert-CentigradeToFahrenheit ([double]$tempC) {
        return ($tempC * (9.0 / 5.0)) + 32.0
    }

    New-Alias c2f Convert-CentigradeToFahrenheit

    function Convert-FahrenheitToCentigrade ([double]$tempF) {
        return ($tempF - 32.0) * (5.0 / 9.0)
    }

    New-Alias f2c Convert-FahrenheitToCentigrade

    Export-ModuleMember -Function Convert-CentigradeToFahrenheit
    Export-ModuleMember -Function Convert-FahrenheitToCentigrade
    Export-ModuleMember -Alias c2f, f2c
}

New-Module -Name MyDynMod -ScriptBlock $sb
Convert-CentigradeToFahrenheit 100
c2f 100

Blok skrip $sb mendefinisikan konten modul, dalam hal ini, dua fungsi dan dua alias untuk fungsi tersebut. Seperti modul dalam disk, secara default hanya fungsi yang diekspor, sehingga Export-ModuleMember cmdlets digunakan untuk mengekspor baik fungsi maupun alias.

Setelah New-Module berjalan, empat nama yang diekspor tersedia untuk digunakan dalam sesi, seperti yang ditunjukkan oleh panggilan ke Convert-CentigradeToFahrenheit dan c2f.

Seperti semua modul, anggota modul dinamis berjalan dalam cakupan modul privat yang merupakan anak dari cakupan global. Get-Module tidak bisa mendapatkan modul dinamis, tetapi Get-Command bisa mendapatkan anggota yang diekspor.

Untuk membuat modul dinamis tersedia untuk Get-Module, kirimkan perintah New-Module ke Import-Module, atau kirimkan objek modul yang dikembalikan New-Module, ke Import-Module. Tindakan ini menambahkan modul dinamis ke daftar Get-Module, tetapi tidak menyimpan modul ke disk atau membuatnya persisten.

11.8 Penutupan

Modul dinamis dapat digunakan untuk membuat penutupan, fungsi yang memiliki data terlampir. Pertimbangkan contoh berikut:

function Get-NextID ([int]$StartValue = 1) {
    $nextID = $StartValue
    {
        ($Script:nextID++)
    }.GetNewClosure()
}

$v1 = Get-NextID      # get a scriptblock with $StartValue of 0
& $v1                 # invoke Get-NextID getting back 1
& $v1                 # invoke Get-NextID getting back 2

$v2 = Get-NextID 100  # get a scriptblock with $StartValue of 100
& $v2                 # invoke Get-NextID getting back 100
& $v2                 # invoke Get-NextID getting back 101

Niat di sini adalah bahwa Get-NextID mengembalikan ID berikutnya secara berurutan yang nilai awalnya dapat ditentukan. Namun, beberapa urutan harus didukung, masing-masing dengan konteks $StartValue dan $nextID-nya sendiri. Ini dicapai dengan panggilan ke metode [scriptblock]::GetNewClosure (§4.3.7).

Setiap kali penutupan baru dibuat oleh GetNewClosure, modul dinamis baru dibuat, dan variabel dalam cakupan pemanggil (dalam hal ini, blok skrip yang berisi kenaikan) disalin ke dalam modul baru ini. Untuk memastikan bahwa nextId yang ditentukan di dalam fungsi induk (tetapi di luar blok skrip) bertahap, Skrip eksplisit: awalan cakupan diperlukan.

Tentu saja, blok skrip tidak perlu menjadi fungsi bernama; misalnya:

$v3 = & {      # get a scriptblock with $StartValue of 200
    param ([int]$StartValue = 1)
    $nextID = $StartValue
    {
        ($Script:nextID++)
    }.GetNewClosure()
} 200

& $v3          # invoke script getting back 200
& $v3          # invoke script getting back 201