about_Pipelines
Menggabungkan perintah ke dalam alur di PowerShell
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
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-Object
Sort-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
, , Format-Table
Export-Clixml
, 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.
Bagian ini menjelaskan bagaimana objek input terikat ke parameter cmdlet dan diproses selama eksekusi 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 .
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, 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 keGet-Member
.
Beberapa parameter dapat menerima objek berdasarkan nama nilai atau properti, sehingga lebih mudah untuk mengambil input dari alur.
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.
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 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 mengimplementasikanIDictionary
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-Member
maka 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.
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.
Namun, PowerShell 7.4 menambahkan PSNativeCommandPreserveBytePipe
fitur eksperimental yang mempertahankan data byte-stream saat mengalihkan aliran stdout perintah asli ke file atau saat memipakan data byte-stream ke aliran stdin dari perintah asli.
Misalnya, menggunakan perintah curl
asli, Anda dapat mengunduh file biner dan menyimpannya ke disk menggunakan pengalihan.
$uri = 'https://github.com/PowerShell/PowerShell/releases/download/v7.3.4/powershell-7.3.4-linux-arm64.tar.gz'
# native command redirected to a file
curl -s -L $uri > powershell.tar.gz
Anda juga dapat menyalurkan data byte-stream ke aliran stdin dari perintah asli lainnya. Contoh berikut mengunduh file TAR zip menggunakan curl
. Data file yang diunduh dialirkan ke tar
perintah untuk mengekstrak konten arsip.
# native command output piped to a native command
curl -s -L $uri | tar -xzvf - -C .
Anda juga dapat menyalurkan output byte-stream dari perintah PowerShell ke input perintah asli. Contoh berikut menggunakan Invoke-WebRequest
untuk mengunduh file TAR yang sama dengan contoh sebelumnya.
# byte stream piped to a native command
(Invoke-WebRequest $uri).Content | tar -xzvf - -C .
# bytes piped to a native command (all at once as byte[])
,(Invoke-WebRequest $uri).Content | tar -xzvf - -C .
Fitur ini tidak mendukung data byte-stream saat mengalihkan output stderr ke stdout. Saat Anda menggabungkan aliran stderr dan stdout , aliran gabungan diperlakukan sebagai data string.
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 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
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.
Umpan balik PowerShell
PowerShell adalah proyek sumber terbuka. Pilih tautan untuk memberikan umpan balik: