about_Pipelines

Deskripsi singkat

Menggabungkan perintah ke dalam alur di PowerShell

Deskripsi panjang

Alur adalah serangkaian perintah yang terhubung oleh operator alur (|) (ASCII 124). Setiap operator alur mengirimkan hasil perintah sebelumnya ke perintah berikutnya.

Output perintah pertama dapat dikirim untuk diproses sebagai input ke perintah kedua. Dan output itu dapat dikirim ke perintah lain. Hasilnya adalah rantai perintah kompleks atau alur yang terdiri dari serangkaian perintah sederhana.

Contohnya,

Command-1 | Command-2 | Command-3

Dalam contoh ini, objek yang Command-1 memancarkan dikirim ke Command-2. Command-2 memproses objek dan mengirimkannya ke Command-3. Command-3 memproses objek dan mengirimkannya ke alur. Karena tidak ada lagi perintah dalam alur, hasilnya ditampilkan di konsol.

Dalam alur, perintah diproses secara berurutan dari kiri ke kanan. Pemrosesan ditangani sebagai operasi tunggal dan output ditampilkan saat dihasilkan.

Berikut contoh sederhana. Perintah berikut mendapatkan proses Notepad lalu menghentikannya.

Contohnya,

Get-Process notepad | Stop-Process

Perintah pertama menggunakan Get-Process cmdlet untuk mendapatkan objek yang mewakili proses Notepad. Ini menggunakan operator alur (|) untuk mengirim objek proses ke Stop-Process cmdlet, yang menghentikan proses Notepad. Perhatikan bahwa Stop-Process perintah tidak memiliki parameter Nama atau ID untuk menentukan proses, karena proses yang ditentukan dikirimkan melalui alur.

Contoh alur ini mendapatkan file teks di direktori saat ini, hanya memilih file yang panjangnya lebih dari 10.000 byte, mengurutkannya berdasarkan panjang, dan menampilkan nama dan panjang setiap file dalam tabel.

Get-ChildItem -Path *.txt |
  Where-Object {$_.length -gt 10000} |
    Sort-Object -Property length |
      Format-Table -Property name, length

Alur ini terdiri dari empat perintah dalam urutan yang ditentukan. Ilustrasi berikut menunjukkan output dari setiap perintah saat diteruskan ke perintah berikutnya dalam alur.

Get-ChildItem -Path *.txt
| (FileInfo objects for *.txt)
V
Where-Object {$_.length -gt 10000}
| (FileInfo objects for *.txt)
| (      Length > 10000      )
V
Sort-Object -Property Length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
V
Format-Table -Property name, length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
| (   Formatted in a table   )
V

Name                       Length
----                       ------
tmp1.txt                    82920
tmp2.txt                   114000
tmp3.txt                   114000

Menggunakan alur

Sebagian besar cmdlet PowerShell dirancang untuk mendukung alur. Dalam kebanyakan kasus, Anda dapat menyalurkan hasil cmdlet Get ke cmdlet lain dengan kata benda yang sama. Misalnya, Anda dapat menyalurkan output Get-Service cmdlet ke Start-Service cmdlet atau Stop-Service .

Contoh alur ini memulai layanan WMI di komputer:

Get-Service wmi | Start-Service

Untuk contoh lain, Anda dapat menyalurkan output Get-Item dari atau Get-ChildItem dalam penyedia registri PowerShell ke New-ItemProperty cmdlet. Contoh ini menambahkan entri registri baru, NoOfEmployees, dengan nilai 8124, ke kunci registri MyCompany .

Get-Item -Path HKLM:\Software\MyCompany |
  New-ItemProperty -Name NoOfEmployees -Value 8124

Banyak cmdlet utilitas, seperti Get-Member, , Where-ObjectSort-Object, Group-Object, dan Measure-Object digunakan hampir secara eksklusif dalam alur. Anda dapat menyalurkan jenis objek apa pun ke cmdlet ini. Contoh ini menunjukkan cara mengurutkan semua proses di komputer berdasarkan jumlah handel terbuka di setiap proses.

Get-Process | Sort-Object -Property handles

Anda dapat menyalurkan objek ke cmdlet pemformatan, ekspor, dan output, seperti Format-List, , Export-ClixmlFormat-Table, Export-CSV, dan Out-File.

Contoh ini menunjukkan cara menggunakan Format-List cmdlet untuk menampilkan daftar properti untuk objek proses.

Get-Process winlogon | Format-List -Property *

Anda juga dapat menyalurkan output perintah asli ke cmdlet PowerShell. Contohnya:

PS> ipconfig.exe | Select-String -Pattern 'IPv4'

   IPv4 Address. . . . . . . . . . . : 172.24.80.1
   IPv4 Address. . . . . . . . . . . : 192.168.1.45
   IPv4 Address. . . . . . . . . . . : 100.64.108.37

Penting

Aliran Keberhasilan dan Kesalahan mirip dengan aliran stdin dan stderr dari shell lain. Namun, stdin tidak tersambung ke alur PowerShell untuk input. Untuk informasi selengkapnya, lihat about_Redirection.

Dengan sedikit latihan, Anda akan menemukan bahwa menggabungkan perintah sederhana ke dalam alur menghemat waktu dan mengetik, dan membuat pembuatan skrip Anda lebih efisien.

Cara kerja alur

Bagian ini menjelaskan bagaimana objek input terikat ke parameter cmdlet dan diproses selama eksekusi alur.

Menerima input alur

Untuk mendukung pipelining, cmdlet penerima harus memiliki parameter yang menerima input alur. Get-Help Gunakan perintah dengan opsi Penuh atau Parameter untuk menentukan parameter cmdlet mana yang menerima input alur.

Misalnya, untuk menentukan parameter Start-Service cmdlet mana yang menerima input alur, ketik:

Get-Help Start-Service -Full

or

Get-Help Start-Service -Parameter *

Bantuan untuk Start-Service cmdlet menunjukkan bahwa hanya parameter InputObject dan Nama yang menerima input alur.

-InputObject <ServiceController[]>
Specifies ServiceController objects representing the services to be started.
Enter a variable that contains the objects, or type a command or expression
that gets the objects.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByValue)
Accept wildcard characters?  false

-Name <String[]>
Specifies the service names for the service to be started.

The parameter name is optional. You can use Name or its alias, ServiceName,
or you can omit the parameter name.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByPropertyName, ByValue)
Accept wildcard characters?  false

Saat Anda mengirim objek melalui alur ke Start-Service, PowerShell mencoba mengaitkan objek dengan parameter InputObject dan Name .

Metode menerima input alur

Parameter cmdlet dapat menerima input alur dengan salah satu dari dua cara berbeda:

  • ByValue: Parameter menerima nilai yang cocok dengan jenis .NET yang diharapkan atau yang dapat dikonversi ke jenis tersebut.

    Misalnya, parameter Start-Service Nama menerima input alur berdasarkan nilai. Ini dapat menerima objek string atau objek yang dapat dikonversi ke string.

  • ByPropertyName: Parameter menerima input hanya ketika objek input memiliki properti dengan nama yang sama dengan parameter .

    Misalnya, parameter Start-Service Nama dapat menerima objek yang memiliki properti Nama . Untuk mencantumkan properti objek, pipa ke Get-Member.

Beberapa parameter dapat menerima objek berdasarkan nama nilai atau properti, sehingga lebih mudah untuk mengambil input dari alur.

Pengikatan parameter

Saat Anda menyalurkan objek dari satu perintah ke perintah lain, PowerShell mencoba mengaitkan objek yang disalurkan dengan parameter cmdlet penerima.

Komponen pengikatan parameter PowerShell mengaitkan objek input dengan parameter cmdlet sesuai dengan kriteria berikut:

  • Parameter harus menerima input dari alur.
  • Parameter harus menerima jenis objek yang dikirim atau jenis yang dapat dikonversi ke jenis yang diharapkan.
  • Parameter tidak digunakan dalam perintah .

Misalnya, Start-Service cmdlet memiliki banyak parameter, tetapi hanya dua di antaranya, Nama dan InputObject yang menerima input alur. Parameter Nama mengambil string dan parameter InputObject mengambil objek layanan. Oleh karena itu, Anda dapat menyalurkan string, objek layanan, dan objek dengan properti yang dapat dikonversi ke string atau objek layanan.

PowerShell mengelola pengikatan parameter seefisien mungkin. Anda tidak dapat menyarankan atau memaksa PowerShell untuk mengikat parameter tertentu. Perintah gagal jika PowerShell tidak dapat mengikat objek yang disalurkan.

Untuk informasi selengkapnya tentang pemecahan masalah kesalahan pengikatan, lihat Menyelidiki Kesalahan Alur nanti di artikel ini.

Pemrosesan satu per satu

Piping objek ke perintah sama seperti menggunakan parameter perintah untuk mengirimkan objek. Mari kita lihat contoh alur. Dalam contoh ini, kita menggunakan alur untuk menampilkan tabel objek layanan.

Get-Service | Format-Table -Property Name, DependentServices

Secara fungsional, ini seperti menggunakan parameter Format-Table InputObject untuk mengirimkan koleksi objek.

Misalnya, kita dapat menyimpan kumpulan layanan ke variabel yang diteruskan menggunakan parameter InputObject .

$services = Get-Service
Format-Table -InputObject $services -Property Name, DependentServices

Atau kita dapat menyematkan perintah dalam parameter InputObject .

Format-Table -InputObject (Get-Service) -Property Name, DependentServices

Namun, ada perbedaan penting. Saat Anda menyalurkan beberapa objek ke perintah, PowerShell mengirimkan objek ke perintah satu per satu. Saat Anda menggunakan parameter perintah, objek dikirim sebagai objek array tunggal. Perbedaan kecil ini memiliki konsekuensi yang signifikan.

Saat menjalankan alur, PowerShell secara otomatis menghitung jenis apa pun yang mengimplementasikan IEnumerable antarmuka atau rekan generiknya. Item yang dijumlahkan dikirim melalui alur satu per satu. PowerShell juga menghitung jenis System.Data.DataTable melalui Rows properti .

Ada beberapa pengecualian untuk enumerasi otomatis.

  • Anda harus memanggil GetEnumerator() metode untuk tabel hash, jenis yang mengimplementasikan IDictionary antarmuka atau rekan generiknya, dan jenis System.Xml.XmlNode .
  • Kelas System.String mengimplementasikan IEnumerable, namun PowerShell tidak menghitung objek string.

Dalam contoh berikut, array dan hashtable disalurkan ke Measure-Object cmdlet untuk menghitung jumlah objek yang diterima dari alur. Array memiliki beberapa anggota, dan hashtable memiliki beberapa pasangan kunci-nilai. Hanya array yang dijumlahkan satu per satu.

@(1,2,3) | Measure-Object
Count    : 3
Average  :
Sum      :
Maximum  :
Minimum  :
Property :
@{"One"=1;"Two"=2} | Measure-Object
Count    : 1
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

Demikian pula, jika Anda menyalurkan beberapa objek proses dari Get-Process cmdlet ke Get-Member cmdlet, PowerShell mengirim setiap objek proses, satu per satu, ke Get-Member. Get-Member menampilkan kelas .NET (jenis) objek proses, serta properti dan metodenya.

Get-Process | Get-Member
TypeName: System.Diagnostics.Process

Name      MemberType     Definition
----      ----------     ----------
Handles   AliasProperty  Handles = Handlecount
Name      AliasProperty  Name = ProcessName
NPM       AliasProperty  NPM = NonpagedSystemMemorySize
...

Catatan

Get-Member menghilangkan duplikat, jadi jika objek adalah semua jenis yang sama, objek hanya menampilkan satu jenis objek.

Namun, jika Anda menggunakan parameter InputObject , Get-Membermaka Get-Member menerima array objek System.Diagnostics.Process sebagai satu unit. Ini menampilkan properti array objek. (Perhatikan simbol array ([]) setelah nama tipe System.Object .)

Contohnya,

Get-Member -InputObject (Get-Process)
TypeName: System.Object[]

Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
Address            Method        System.Object& Address(Int32 )
Clone              Method        System.Object Clone()
...

Hasil ini mungkin bukan yang Anda inginkan. Tetapi setelah Anda memahaminya, Anda dapat menggunakannya. Misalnya, semua objek array memiliki properti Count . Anda dapat menggunakannya untuk menghitung jumlah proses yang berjalan di komputer.

Contohnya,

(Get-Process).count

Penting untuk diingat bahwa objek yang dikirimkan alur dikirimkan satu per satu.

Menggunakan perintah asli dalam alur

PowerShell memungkinkan Anda menyertakan perintah eksternal asli dalam alur. Namun, penting untuk dicatat bahwa alur PowerShell berorientasi objek dan tidak mendukung data byte mentah.

Mempipa atau mengalihkan output dari program asli yang menghasilkan data byte mentah mengonversi output menjadi string .NET. Konversi ini dapat menyebabkan kerusakan output data mentah.

Sebagai solusinya, panggil perintah asli menggunakan cmd.exe /c atau sh -c dan penggunaan | operator dan > yang disediakan oleh shell asli.

Menyelidiki kesalahan alur

Saat PowerShell tidak dapat mengaitkan objek yang disalurkan dengan parameter cmdlet penerima, perintah gagal.

Dalam contoh berikut, kami mencoba memindahkan entri registri dari satu kunci registri ke kunci registri lainnya. Get-Item Cmdlet mendapatkan jalur tujuan, yang kemudian disalurkan ke Move-ItemProperty cmdlet. Perintah Move-ItemProperty menentukan jalur saat ini dan nama entri registri yang akan dipindahkan.

Get-Item -Path HKLM:\Software\MyCompany\sales |
Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product

Perintah gagal dan PowerShell menampilkan pesan kesalahan berikut:

Move-ItemProperty : The input object can't be bound to any parameters for
the command either because the command doesn't take pipeline input or the
input and its properties do not match any of the parameters that take
pipeline input.
At line:1 char:23
+ $a | Move-ItemProperty <<<<  -Path HKLM:\Software\MyCompany\design -Name p

Untuk menyelidikinya, gunakan Trace-Command cmdlet untuk melacak komponen pengikatan parameter PowerShell. Contoh berikut melacak pengikatan parameter saat alur sedang dijalankan. Parameter PSHost menampilkan hasil pelacakan di konsol dan parameter FilePath mengirim hasil pelacakan ke debug.txt file untuk referensi nanti.

Trace-Command -Name ParameterBinding -PSHost -FilePath debug.txt -Expression {
  Get-Item -Path HKLM:\Software\MyCompany\sales |
    Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product
}

Hasil pelacakan panjang, tetapi menunjukkan nilai yang terikat ke Get-Item cmdlet dan kemudian nilai bernama yang terikat ke Move-ItemProperty cmdlet.

...
BIND NAMED cmd line args [`Move-ItemProperty`]
BIND arg [HKLM:\Software\MyCompany\design] to parameter [Path]
...
BIND arg [product] to parameter [Name]
...
BIND POSITIONAL cmd line args [`Move-ItemProperty`]
...

Terakhir, ini menunjukkan bahwa upaya untuk mengikat jalur ke parameter Move-ItemProperty Tujuan gagal.

...
BIND PIPELINE object to parameters: [`Move-ItemProperty`]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values
Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
...

Get-Help Gunakan cmdlet untuk melihat atribut parameter Tujuan.

Get-Help Move-ItemProperty -Parameter Destination

-Destination <String>
    Specifies the path to the destination location.

    Required?                    true
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

Hasilnya menunjukkan bahwa Tujuan hanya mengambil input alur "menurut nama properti". Oleh karena itu, objek yang disalurkan harus memiliki properti bernama Destination.

Gunakan Get-Member untuk melihat properti objek yang berasal dari Get-Item.

Get-Item -Path HKLM:\Software\MyCompany\sales | Get-Member

Output menunjukkan bahwa item adalah objek Microsoft.Win32.RegistryKey yang tidak memiliki properti Tujuan . Itu menjelaskan mengapa perintah gagal.

Parameter Jalur menerima input alur berdasarkan nama atau berdasarkan nilai.

Get-Help Move-ItemProperty -Parameter Path

-Path <String[]>
    Specifies the path to the current location of the property. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true

Untuk memperbaiki perintah, kita harus menentukan tujuan dalam Move-ItemProperty cmdlet dan menggunakan Get-Item untuk mendapatkan Jalur item yang ingin kita pindahkan.

Contohnya,

Get-Item -Path HKLM:\Software\MyCompany\design |
Move-ItemProperty -Destination HKLM:\Software\MyCompany\sales -Name product

Kelanjutan baris intrinsik

Seperti yang telah dibahas, alur adalah serangkaian perintah yang terhubung oleh operator alur (|), biasanya ditulis pada satu baris. Namun, untuk keterbacaan, PowerShell memungkinkan Anda untuk membagi alur di beberapa baris. Ketika operator pipa adalah token terakhir pada baris, pengurai PowerShell bergabung dengan baris berikutnya ke perintah saat ini untuk melanjutkan pembangunan alur.

Misalnya, alur satu baris berikut:

Command-1 | Command-2 | Command-3

dapat ditulis sebagai:

Command-1 |
    Command-2 |
    Command-3

Spasi di awal pada baris berikutnya tidak signifikan. Indentasi meningkatkan keterbacaan.

PowerShell 7 menambahkan dukungan untuk kelanjutan alur dengan karakter alur di awal baris. Contoh berikut menunjukkan bagaimana Anda dapat menggunakan fungsionalitas baru ini.

# Wrapping with a pipe at the beginning of a line (no backtick required)
Get-Process | Where-Object CPU | Where-Object Path
    | Get-Item | Where-Object FullName -match "AppData"
    | Sort-Object FullName -Unique

# Wrapping with a pipe on a line by itself
Get-Process | Where-Object CPU | Where-Object Path
    |
    Get-Item | Where-Object FullName -match "AppData"
    |
    Sort-Object FullName -Unique

Penting

Saat bekerja secara interaktif di shell, menempelkan kode dengan alur di awal baris hanya saat menggunakan Ctrl+V untuk menempelkan. Klik kanan operasi tempel menyisipkan garis satu per satu. Karena baris tidak diakhir dengan karakter alur, PowerShell menganggap input selesai dan menjalankan baris tersebut seperti yang dimasukkan.

Lihat juga