Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Deskripsi singkat
Variabel otomatis yang berisi objek saat ini dalam objek alur.
Deskripsi panjang
PowerShell menyertakan dua variabel otomatis, $_ dan '$PSItem' yang merujuk ke objek saat ini dalam alur.
$PSItem ditambahkan ke PowerShell dalam upaya untuk memberikan arti yang lebih jelas ke nama variabel. Namun, dalam praktiknya, bentuk $_garis bawah tanda dolar paling umum digunakan.
Meskipun artikel ini menggunakan $PSItem dalam contoh, $PSItem dapat diganti dengan $_ dalam setiap contoh.
$_ adalah penggunaan yang disukai.
Ada beberapa kasus penggunaan umum untuk $PSItem:
- Dalam blok skrip untuk parameter Proses dari cmdlet
ForEach-Object - Dalam blok skrip untuk FilterScript parameter dari cmdlet
Where-Object - Dalam metode intrinsik ForEach dan Where
- dengan parameter blok skrip yang tertunda
-
switchDalam nilai bersyarkat pernyataan dan pernyataan terkait -
processDalam blok pernyataan fungsi - Dalam definisi
filter - Dalam blok skrip atribut ValidateScript
- Dalam blok pernyataan
catch - Dalam blok skrip substitusi dari operator
-replace
Sisa artikel ini mencakup contoh penggunaan $PSItem untuk kasus penggunaan ini.
parameter Proses ForEach-Object
Cmdlet ForEach-Object dirancang untuk beroperasi pada objek dalam alur, menjalankan blok skrip parameter Proses sekali untuk setiap objek dalam alur.
Anda dapat menggunakan $PSItem dalam blok skrip parameter Proses tetapi tidak di blok skrip parameter Mulai atau Akhir . Jika Anda mereferensikan $PSItemdalam blokir skrip parameter Mulai atau Akhir , nilainya adalah $null karena blok skrip tersebut tidak beroperasi pada setiap objek dalam alur.
$parameters = @{
Begin = { Write-Host "PSItem in Begin is: $PSItem" }
Process = {
Write-Host "PSItem in Process is: $PSItem"
$PSItem + 1
}
End = { Write-Host "PSItem in End is: $PSItem" }
}
$result = 1, 2, 3 | ForEach-Object @parameters
Write-Host "Result is: $result"
PSItem in Begin is:
PSItem in Process is: 1
PSItem in Process is: 2
PSItem in Process is: 3
PSItem in End is:
Result is: 2 3 4
FilterScript Where-Object
Cmdlet Where-Object dirancang untuk memfilter objek dalam alur.
Anda dapat menggunakan $PSItem dalam blokir skrip parameter FilterScript , yang dijalankan sekali untuk setiap objek input dalam alur.
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
Dalam contoh ini, FilterScript memeriksa untuk melihat apakah objek saat ini genap, memfilter nilai ganjil apa pun, dan hanya 2 mengembalikan dari daftar asli.
Metode ForEach dan Where
Baik metode intrinsik ForEach maupun Di mana untuk array mengambil blok skrip sebagai parameter input. Anda dapat menggunakan $PSItem dalam blokir skrip tersebut untuk mengakses objek saat ini.
@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B
Dalam contoh ini, blok skrip metode ForEach mengutamakan objek saat ini. Kemudian blok skrip metode Where hanya Bmengembalikan .
Blokir skrip tertunda-ikat
Blokir skrip yang tertunda memungkinkan Anda menggunakan $PSItem untuk menentukan parameter untuk cmdlet yang disalurkan sebelum mengeksekusinya.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Beralih pernyataan
Dalam pernyataan switch, Anda dapat menggunakan $PSItem dalam blokir skrip tindakan dan blok skrip kondisi pernyataan.
$numbers = 1, 2, 3
switch ($numbers) {
{ ($PSItem % 2) -eq 0 } { "$PSItem is even" }
default { "$PSItem is odd" }
}
1 is odd
2 is even
3 is odd
Dalam contoh ini, blok pernyataan kondisi memeriksa apakah objek saat ini genap. Jika bahkan, blok pernyataan tindakan terkait menghasilkan pesan yang menunjukkan objek saat ini bahkan.
Blok pernyataan tindakan untuk kondisi menghasilkan default pesan yang menunjukkan objek saat ini ganjil.
Blok pernyataan proses fungsi
Saat Anda menentukan fungsi, Anda dapat menggunakan $PSItem dalam process definisi blok tetapi tidak dalam begin definisi blok atau end . Jika Anda mereferensikan $PSItembegin di blok atau end , nilainya adalah $null karena blok tersebut tidak beroperasi pada setiap objek dalam alur.
Ketika Anda menggunakan $PSItem dalam process definisi blok pernyataan, nilainya adalah objek saat ini jika fungsi dipanggil dalam alur dan sebaliknya $null.
function Add-One {
process { $PSItem + 1 }
}
1, 2, 3 | Add-One
2
3
4
Petunjuk / Saran
Meskipun Anda dapat menggunakan $PSItem dalam fungsi lanjutan, ada sedikit alasan untuk melakukannya. Jika Anda berniat menerima input dari alur, yang terbaik adalah menentukan parameter dengan menggunakan ValueFromPipeline argumen atau ValueFromPipelineByPropertyName di atribut Parameter .
Menggunakan atribut Parameter dan pengikatan cmdlet untuk fungsi lanjutan membuat implementasi lebih eksplisit dan dapat diprediksi daripada memproses objek saat ini untuk mendapatkan nilai yang diperlukan.
Salah satu penggunaan yang baik dalam fungsi lanjutan $PSItem adalah untuk memeriksa objek saat ini sendiri untuk penelusuran kesalahan atau pengelogan ketika fungsi memiliki beberapa parameter yang mengambil input dari alur.
function Write-JsonLog {
[CmdletBinding()]
param(
[Parameter(ValueFromPipelineByPropertyName)]
[string]$Message
)
begin {
$entries = @()
}
process {
$entries += [pscustomobject]@{
Message = $Message
TimeStamp = [datetime]::Now
}
if ($PSItem) {
$props = $PSItem | ConvertTo-Json
$number = $entries.Length
Write-Verbose "Input object $number is:`n$props"
}
}
end {
ConvertTo-Json -InputObject $entries
}
}
Contoh fungsi ini menghasilkan array objek JSON dengan pesan dan tanda waktu. Ketika dipanggil dalam alur, ia menggunakan properti Pesan dari objek saat ini untuk setiap entri. Ini juga menulis representasi JSON dari objek saat ini itu sendiri ke aliran verbose, sehingga Anda dapat melihat input aktual dibandingkan dengan log output.
$Items = @(
[pscustomobject]@{
Name = 'First Item'
Message = 'A simple note'
}
[pscustomobject]@{
Name = 'Item with extra properties'
Message = 'Missing message, has info instead'
Info = 'Some metadata'
Source = 'Where this came from'
}
[pscustomobject]@{
Name = 'Last Item'
Message = 'This also gets logged'
}
)
$Items | Write-JsonLog -Verbose
VERBOSE: Input object 1 is:
{
"Name": "First Item",
"Message": "A simple note"
}
VERBOSE: Input object 2 is:
{
"Name": "Item with extra properties",
"Message": "Missing message, has info instead",
"Info": "Some metadata",
"Source": "Where this came from"
}
VERBOSE: Input object 3 is:
{
"Name": "Last Item",
"Message": "This also gets logged"
}
[
{
"Message": "A simple note",
"TimeStamp": "\/Date(1670344068257)\/"
},
{
"Message": "Missing message, has info instead",
"TimeStamp": "\/Date(1670344068259)\/"
},
{
"Message": "This also gets logged",
"TimeStamp": "\/Date(1670344068261)\/"
}
]
Definisi filter
Anda dapat menggunakan $PSItem dalam daftar pernyataan definisi filter.
Saat Anda menggunakan $PSItem dalam filter definisi, nilainya adalah objek saat ini jika filter dipanggil dalam alur dan sebaliknya $null.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
Dalam contoh ini, Test-IsEven filter menghasilkan $true output jika objek saat ini adalah angka genap dan $false jika tidak.
Atribut ValidateScript ScriptBlock
Anda dapat menggunakan $PSItem dalam blokir skrip atribut ValidateScript .
Saat digunakan dengan ValidateScript, $PSItem adalah nilai objek saat ini yang sedang divalidasi. Ketika variabel atau nilai parameter adalah array, blok skrip dipanggil sekali untuk setiap objek dalam array dengan $PSItem sebagai objek saat ini.
function Add-EvenNumber {
param(
[ValidateScript({ 0 -eq ($PSItem % 2) })]
[int[]]$Number
)
begin {
[int]$total = 0
}
process {
foreach ($n in $Number) {
$total += $n
}
}
end {
$total
}
}
Add-EvenNumber -Number 2, 4, 6
Add-EvenNumber -Number 1, 2
12
Add-EvenNumber:
Line |
24 | Add-EvenNumber -Number 1, 2
| ~~~~
| Cannot validate argument on parameter 'Number'. The
" 0 -eq ($PSItem % 2) " validation script for the argument
with value "1" did not return a result of True. Determine
why the validation script failed, and then try the command
again.
Dalam contoh ini, blok skrip untuk atribut ValidateScript berjalan sekali untuk setiap nilai yang diteruskan ke parameter Angka , mengembalikan kesalahan jika ada nilai yang bahkan tidak.
Fungsi menambahkan Add-EvenNumber angka input yang valid dan mengembalikan total.
catch Blok pernyataan
catch Dalam blok pernyataan, $PSItem berisi kesalahan saat ini. Objek berjenis ErrorRecord.
try { NonsenseString }
catch {
Write-Host "An error occurred:"
Write-Host $PSItem
}
Menjalankan skrip ini mengembalikan hasil berikut:
An error occurred:
The term 'NonsenseString' 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.
Untuk contoh selengkapnya, lihat bagian Mengakses informasi pengecualian di about_Try_Catch_Finally.
Blokir -replace skrip pengganti operator
Mulai dari PowerShell 6, Anda dapat menggunakan $PSItem saat memanggil operator -replace dan menentukan blokir skrip pengganti . Ketika Anda melakukannya, nilai $PSItem adalah nilai dari kecocokan saat ini.
$datePattern = '\d{4}-\d{2}-\d{2}'
'Today is 1999-12-31' -replace $datePattern, { [datetime]$PSItem.Value }
Today is 12/31/1999 00:00:00
Dalam contoh ini, blok skrip pengganti mengganti string tanggal asli dengan format default untuk budaya saat ini dengan mentransmisikan nilai ke datetime.
Mengubah nilai $PSItem
Anda dapat mengubah nilai $PSItem dengan menetapkan nilai baru ke nilai tersebut. Namun, melakukannya dapat mengubah perilaku yang diharapkan dari kode apa pun yang bergantung pada $PSItem.
Pertimbangkan contoh berikut. Biasanya, switch pernyataan akan memproses semua nilai dalam array $names. Karena nilai $PSItem diubah di dalam blok pernyataan tindakan, switch pernyataan hanya memproses nilai pertama.
$names = 'Alice', 'Charlie'
switch ($names) {
Alice { "$PSItem says 'Hello!'"; $PSItem = 'Bob' }
Bob { "$PSItem says 'Goodbye.'"; $PSItem = 'Charlie'; break }
Charlie { "$PSItem says 'How are you?'" }
}
switch Ketika pernyataan mengevaluasi nilai pertama, Alice, pernyataan tersebut cocok dengan kondisi pertama dan menjalankan blok pernyataan tindakan terkait. Di dalam blok itu, nilai $PSItem diubah menjadi Bob, yang juga memengaruhi evaluasi switch pernyataan.
Alice says 'Hello!'
Bob says 'Goodbye.'
Anda harus menghindari perubahan nilai $PSItem.