Apa itu Windows PowerShell dan apa yang dimakannya? Bagian 3: meneruskan parameter ke skrip dan fungsi, membuat cmdlet



Bagian kedua dari seri ini membahas dasar-dasar bahasa pemrograman PowerShell, tetapi sekarang bermanfaat untuk mengetahui cara menggunakan kode yang ditulis di atasnya untuk tugas administratif. Cara paling jelas untuk melakukan ini adalah dengan menjalankan skrip. Selain itu, dimungkinkan untuk membuat cmdlet Anda sendiri.

Daftar Isi:


Parameter posisi Parameter
() blok
Atribut parameter tambahan
Melewati parameter melalui pipa
Struktur tubuh fungsi
Atribut [CmdletBinding ()] dan fungsi lanjutan
Modul skrip dan pembuatan cmdlet

Parameter posisi


Dalam skrip dan fungsi, Anda bisa mengirimkan parameter posisi (argumen) yang nilainya ditulis ke variabel bawaan $ args. Array satu dimensi ini tidak memerlukan deklarasi sebelumnya, dan cakupannya terbatas pada skrip atau fungsi. Misalnya, jalankan skrip paling sederhana:

Write-Host " :" $args.count
Write-Host ":" $args


gambar

Dalam fungsi, parameter posisi digunakan dengan cara yang sama:

function Print-Args {
    Write-Host " :" $args.count
    Write-Host " 0:" $args[0]
    Write-Host " 1:" $args[1] 
}

Print-Args β€œZero” β€œOne”

Harap dicatat bahwa saat memanggil Print-Args kita tidak meletakkan koma di antara parameter: itu bukan array yang diteruskan ke fungsi, tetapi nilai-nilai individual yang ditulis ke array satu dimensi $ args - cakupannya dibatasi oleh badan fungsi.

gambar

Metode yang dijelaskan di atas memungkinkan Anda untuk mengirimkan sejumlah parameter ke skrip atau fungsi, tetapi saat memanggil Anda harus mengikuti urutan urutannya, dan Anda dapat mengaksesnya hanya dengan indeks array - ini tidak selalu nyaman.

Blok param ()


Dalam skrip dan fungsi, jauh lebih mudah untuk menggunakan parameter bernama. Dalam artikel sebelumnya, kami berbicara tentang satu cara untuk menggambarkannya:

function test ($arg0, ..., $argN)
{
       
}

Sintaksis yang sama akrab bagi pengembang, tetapi ketika suatu fungsi dipanggil, parameter (jika ada) dipisahkan oleh spasi, dan tidak tertutup dalam tanda kurung - disonansi tertentu muncul. Ini adalah kekhasan bahasa shell: untuk bekerja dengan shell dalam mode interaktif, ruang antar nilai jauh lebih nyaman. The test ($ value0) panggilan juga benar, tetapi parameter dalam hal ini adalah seluruh ekspresi dalam kurung, yaitu ($ value0) bukannya $ value0 . Melewati cara ini beberapa parameter tidak akan berfungsi. Sebagai hasil dari tes panggilan ($ value0, $ value1), fungsi hanya akan menerima satu - array dari dua elemen dengan nilai $ value0 dan $ value1 .

Microsoft Corporation merekomendasikan penggunaan blok Param () - sintaks ini lebih universal dan memungkinkan Anda menentukan tidak hanya argumen fungsi, tetapi juga parameter skrip:

param (
    $arg0, $arg1
)

Write-Host $arg0 $arg1


gambar

Dalam tubuh fungsi, tampilannya seperti ini:

function test {
     param (
           $arg0, $arg1
     )
}

Jika daftar argumen fungsi kecil, blok Param () hanya akan mengacaukan desain, tetapi dalam banyak kasus itu membuat kode lebih mudah dibaca dan, antara lain, merupakan elemen dari gaya pemrograman yang baik.

Atribut parameter tambahan


Saat menjelaskan argumen fungsi atau parameter skrip, atribut tambahannya dapat diatur. Contoh paling sederhana adalah pemasangan paksa tipe:

param([int]$arg0)

atau

function test ([int]$arg0) {
}

Selain mengetikkan casting, Anda dapat menggunakan atribut [parameter ()]:

param(
    [parameter(Argument1=value1, Argument2=value2)]
    $ParameterName
)

Dengan bantuannya mudah untuk membuat parameter wajib. Perhatikan penggunaan simultan beberapa atribut - dalam hal ini mereka saling mengikuti:

param([parameter(Mandatory=$true)][int]$arg0)

atau

function test ([parameter(Mandatory=$true)][int]$arg0) { 
}

atau

function test {
          parameter([parameter(Mandatory=$true)][int]$arg0)
}


gambar

Posisi memungkinkan Anda menentukan urutan parameter (secara default, sesuai dengan urutan deklarasi):

param(
                    [parameter(Mandatory=$true, Position=0)]
                    [int]
                    $arg0,

                    [parameter(Position=1)]
                    [string]
                    $arg1,

                    [parameter(Position=2)]
                    [array]
                    $arg2
)

Atribut [Parameter ()] memiliki argumen lain, daftar lengkap yang tersedia di situs web Microsoft. Atribut lain dijelaskan di sana, dengan bantuan Anda dapat memvalidasi nilai yang diteruskan, memeriksanya menggunakan ekspresi reguler, dll. Berikut ini beberapa:

[Alias ​​()] menetapkan alias untuk parameter:

param(
    [parameter(Mandatory=$true)]
    [alias("ARG","ArgumentName")]
    [string[]]
    $arg0
)

Operator cor [string []] berarti bahwa nilai parameter adalah array string.

[AllowNull ()] memungkinkan $ null sebagai parameter yang diperlukan:

param(
    [parameter(Mandatory=$true)]
    [AllowNull()]
    [string]
    $arg0
)

[AllowEmptyString ()] memungkinkan string kosong sebagai parameter yang diperlukan:

param(
    [parameter(Mandatory=$true)]
    [AllowEmptyString()]
    [string]
    $arg0
)

[AllowEmptyCollection ()] memungkinkan array kosong sebagai parameter yang diperlukan:

param(
    [parameter(Mandatory=$true)]
    [AllowEmptyCollection()]
    [string[]]
    $arg0
)

Validasi [ValidatePattern ()] menggunakan ekspresi reguler:

param(
    [parameter(Mandatory=$true)]
    [ValidatePattern("[0-9][0-9][0-9][0-9]")]
    [string[]]
    $arg0
)

[ValidateLength ()] memeriksa panjang parameter string:

param(
    [parameter(Mandatory=$true)]
    [ValidateLength(1,10)]
    [string]
    $arg0
)

Melewati parameter melalui pipa


Pada artikel pertama dalam seri, kami berbicara tentang kemungkinan mentransfer data ke cmdlet melalui pipa. Di PowerShell, cmdlet dan fungsi mengembalikan objek atau array objek (hasil pernyataan), dan juga menerimanya pada input. Untuk melihat ini, kami menyiapkan salah satu cmdlet menggunakan Dapatkan-Bantuan:

Get-Help Stop-Process -Parameter Name


gambar

Melalui pipa, Anda dapat menerima nilai parameter yang atribut terkait ditetapkan (ByValue dan / atau ByPropertyName). Dalam kasus pertama, parameter akan dicocokkan dengan objek yang diterima melalui pipa, asalkan jenisnya sesuai dengan yang diharapkan. Pada nilai parameter kedua akan menjadi properti dari objek yang masuk yang namanya sesuai dengan nama atau alias dari parameter ini. Untuk mengatur atribut, gunakan [parameter ()] dengan argumen boolean ValueFromPipeline dan ValueFromPipelineByPropertyName, yang nilai defaultnya adalah $ false:

param(
    [parameter(Mandatory=$true,
    ValueFromPipeline=$true)]
    [string[]]
    $Name
)

atau

param(
    [parameter(Mandatory=$true,
    ValueFromPipelineByPropertyName=$true)]
    [string[]]
    $Name
)

ValueFromPipelineByPropertyName biasanya digunakan jika perlu untuk melewati beberapa parameter sehingga tidak ada kebingungan, dan argumen dapat digunakan secara bersamaan dengan ValueFromPipeline:

param(
    [parameter(Mandatory=$true,
    ValueFromPipeline=$true,
    ValueFromPipelineByPropertyName=$true)]
    [string[]]
    $Name
)

Write-Host $Name


gambar

Seperti yang Anda lihat, skrip juga dapat menerima parameter melalui pipeline, namun demikian, aplikasi praktis dari atribut yang dijelaskan di atas lebih mungkin untuk fungsi lanjutan , yang akan dibahas di bawah ini.

Fungsi struktur tubuh


Di PowerShell, suatu fungsi dapat menyertakan tiga blok kode opsional yang terlampir dalam tanda kurung pernyataan - Mulai, Proses, dan Akhir. Itu terlihat seperti ini:

function test
{
   param()
   begin {}
   process {}
   end {}
}

Blok Begin adalah yang pertama kali dieksekusi sekali, dan jika parameter dilewatkan ke fungsi melalui pipa, kode akan berjalan sebelum objek pertama tiba untuk diproses. Variabel $ _ dan $ PSItem di blok Begin dalam hal ini tidak akan mengandung nilai. Jika fungsi dipanggil menggunakan parameter yang ditentukan secara eksplisit, mereka akan tersedia di blok Begin, karena tidak perlu menunggu objek yang akan diterima dari pipa. Selanjutnya, blok Proses dijalankan: jika parameter dilewatkan melalui pipa, itu akan diluncurkan satu per satu untuk setiap objek. Dalam kasus parameter yang ditentukan secara eksplisit, blok Proses dimulai hanya sekali. Fungsi berakhir dengan mengeksekusi blok End sekali. Jelas, penggunaan konstruksi ini dibenarkan hanya jika fungsi tersebut dapat menerima objek dari pipa:

function test
{

    param(
        [Parameter(ValueFromPipeline)]
        [string[]]
        $Param1,

        [string]$Param2
    )

    begin
    {
        Write-Host " Begin"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }

    process {
        Write-Host " Process"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }

    end
    {
        Write-Host " End"
        Write-Host "       ( pipeline):" $Param1
        Write-Host "       ( ):" $Param2
    }
}

'satu', 'dua', 'tiga' | test -Param2 'empat'

gambar

[CmdletBinding ()] Atribut dan Fungsi Lanjut


Untuk membuat fungsi "lanjutan" (dan skrip berbicara dengan jelas), Anda dapat menggunakan atribut [ CmdletBinding () ]. Secara khusus, ini memungkinkan Anda untuk mendefinisikan fungsi-fungsi tingkat lanjut dengan kemampuan cmdlet biner yang dikompilasi dalam Visual Studio, yang merupakan kelas-kelas .NET Core Karena atribut ini digunakan terutama dalam fungsi, kami akan berhenti pada mereka:

function <Name>
{
    [CmdletBinding(ConfirmImpact=<String>,
    DefaultParameterSetName=<String>,
    HelpURI=<URI>,
    SupportsPaging=<Boolean>,
    SupportsShouldProcess=<Boolean>,
    PositionalBinding=<Boolean>)]

    Param ()

    Begin{}
    Process{}
    End{}
}

Bahkan, [CmdletBinding ()] menginisialisasi instance baru dari kelas CmdletBindingAttribute dengan memanggil konstruktor, yang argumen opsional dapat diteruskan. Deskripsi terperinci mereka ada di situs web Microsoft. Atribut CmdletBinding memungkinkan Anda untuk mengontrol fitur tambahan dari fungsi lanjutan: menambahkan dukungan untuk -Confirm dan -WhatIf (melalui SupportsShouldProcess), -Force, -Verbose dan -Debug, serta menonaktifkan pengikatan parameter posisi, dll. Selanjutnya kami akan menganalisis penggunaan parameter khusus.

Parameter -Force digunakan untuk menekan permintaan untuk berbagai operasi;

-Bagaimana jikadiperlukan untuk meniru peluncuran dan menampilkan informasi tentang konsekuensi menjalankan fungsi (perintah) tanpa parameter ini. Biasa digunakan jika suatu fungsi dapat melakukan tindakan merusak.

Hapus-Item C: \ Windows \ notepad.exe -WhatIf

gambar

-Confirm memerlukan konfirmasi dan juga digunakan jika fungsi tersebut dapat melakukan tindakan destruktif.

function Delete-File {
[CmdletBinding(
    ConfirmImpact = 'High',
    SupportsShouldProcess = $true
)]
    param(
        [string]$File,
        [switch]$Force
    )
    if ($Force -or $PSCmdlet.ShouldProcess($File,"Delete file")) {
        Remove-Item $File
    }
}


gambar

Untuk memproses -WhatIf dan / atau -Confirm, metode ShouldProcess (SupportsShouldProcess = $ true) dipanggil, yang meminta atau mengemulasi pelaksanaan perintah. Untuk mengimplementasikan pemrosesan -Force, kami menempatkannya terlebih dahulu dalam kondisi IF. Pertama, ekspresi di sebelah kiri operator -atau dicentang, dan jika itu benar, tes berhenti - metode ShouldProcess tidak akan dipanggil. Juga, dalam atribut [CmdletBinding ()], kami menentukan argumen ConfirmImpact, yang menentukan tingkat pengaruh kode pada sistem dan termasuk penangan parameter -Confirm. Argumen ini dapat mengambil nilai-nilai berikut:

Tidak ada atau tidak ditentukan - pesan konfirmasi tidak akan ditampilkan, bahkan jika parameter -Confirm dilewatkan.

Rendah - fungsinya sedikit memengaruhi sistem dan tidak menimbulkan risiko kehilangan data yang signifikan.

Medium - paparan media dengan sedikit risiko kehilangan data sebagai akibat dari tindakan destruktif.

Tinggi - kode menciptakan risiko kehilangan data yang tinggi sebagai akibat dari tindakan destruktif.

Secara default, untuk sesi PowerShell, level eksposur dianggap Tinggi. Nilai saat ini disimpan dalam variabel $ ConfirmPreference, dan jika kode memiliki tingkat dampak yang sama atau lebih tinggi pada sistem, permintaan konfirmasi akan selalu ditampilkan.

Opsi -Verbose dan -Debugdiperlukan untuk menampilkan informasi debug. Penggunaannya dianggap sebagai gaya pemrograman yang baik (lupakan Write-Host, ini tidak perlu dalam fungsi lanjutan). Parameter pertama menampilkan informasi tentang kemajuan, dan informasi debugging kedua yang terperinci. Itu juga memungkinkan untuk beralih ke eksekusi kode langkah-demi-langkah. Perilaku -Verbose dan -Debug didefinisikan seperti ini:

function Get-Something {
[CmdletBinding()]
    param()
    if ($PSBoundParameters.Verbose) {$VerbosePreference = "Continue"}
    if ($PSBoundParameters.Debug) {$DebugPreference = "Continue"}
    Write-Verbose "Type some verbose information"
    Write-Debug "Type some debug information"
}

Untuk bekerja dengan parameter khusus, kami menggunakan variabel $ PSBoundParameters. Secara default, nilai $ VerbosePreference dan $ DebugPreference sama dengan 'SilentlyContinue', oleh karena itu, bahkan jika parameter terkait ditentukan, informasi debug tidak akan ditampilkan - mereka harus ditransfer ke negara 'Lanjutkan'.

Modul Script dan Pembuatan Cmdlet


Mari kita mulai membuat cmdlet kita sendiri. Bahkan, ini adalah fungsi-fungsi lanjutan yang dijelaskan dalam apa yang disebut modul skrip - file teks dengan ekstensi .psm1. Mereka disimpan dalam direktori yang didefinisikan dalam variabel lingkungan PSModulePath. Anda dapat melihat path ke mereka menggunakan perintah berikut:

Get-ChildItem Env: \ PSModulePath | Format-Tabel -AutoSize

Set standar terlihat seperti ini:

C: \ Users \% UserName% \ Documents \ WindowsPowerShell \ Modul
C: \ Program Files \ WindowsPowerShell \ Modul
C: \ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modul

Setelah membuat file ModuleName.psm1 dengan fungsi Delete-File yang diperluas dari bagian sebelumnya, Anda perlu menyimpannya, misalnya, dalam] C: \ Users \% UserName% \ Documents \ WindowsPowerShell \ Modules \ ModuleName. Harap dicatat bahwa modul skrip harus disimpan dalam subdirektori terpisah, nama yang bertepatan dengan nama dasar (tanpa ekstensi) dari file .psm1. Setelah menjalankan perintah Import-Module ModuleName , fungsi Delete-File akan tersedia bagi pengguna, dan karena itu dikembangkan, dari sudut pandang praktis itu adalah cmdlet yang sama.

gambar

Dalam artikel ini, kami telah memeriksa secara terperinci kelulusan parameter ke fungsi dan skrip. Bagian selanjutnya dari seri ini akan fokus pada pemrograman berorientasi objek.

Bagian 1: Windows PowerShell Essentials
2: Windows PowerShell
4: ,



All Articles