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 $_ 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 binding 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
Anda dapat menggunakan $PSItem di blok skrip parameter Mulai atau Akhiri, 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
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
Dalam contoh ini, FilterScript memeriksa apakah objek yang ada genap, menyaring nilai ganjil, dan hanya mengembalikan 2 dari daftar asli.
Metode ForEach dan Where
Baik metode intrinsik ForEach dan Where untuk array mengambil scriptblock sebagai parameter masukan. Anda dapat menggunakan $PSItem dalam blok 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 scriptblock dari metode Where hanya mengembalikan B.
Blokir skrip tertunda-ikat
Skrip dengan pembindaan tertunda
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Beralih pernyataan
Dalam pernyataan pengalihan , Anda dapat menggunakan $PSItem di blok 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 definisi blok process tetapi tidak dalam definisi blok begin atau end. Jika Anda mereferensikan $PSItem di blok begin atau end, nilainya $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
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 tingkat lanjut membuat implementasi lebih eksplisit dan dapat diprediksi daripada memproses objek saat ini untuk mendapatkan nilai yang diperlukan.
Salah satu penggunaan terbaik dari $PSItem dalam fungsi lanjutan adalah untuk memeriksa objek itu sendiri dalam proses debugging atau pencatatan ketika fungsi memiliki beberapa parameter yang menerima input dari pipeline.
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. Saat dipanggil dalam alur, itu menggunakan properti Pesan dari objek saat ini untuk setiap entri. Ini juga menulis representasi JSON dari objek saat ini itu sendiri ke stream terperinci, sehingga Anda dapat melihat input sebenarnya dibandingkan dengan log keluaran.
$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 definisi filter, nilainya adalah objek saat ini jika filter dipanggil dalam jalur pemrosesan dan jika tidak, nilai tersebut adalah $null.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
Contoh ini menunjukkan bahwa filter Test-IsEven menghasilkan output $true jika objek saat ini adalah angka genap dan menghasilkan $false jika sebaliknya.
Atribut ValidateScript ScriptBlock
Anda dapat menggunakan $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 Number, mengembalikan kesalahan jika ada nilai yang tidak genap.
Fungsi Add-EvenNumber menambahkan 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 melakukan hal tersebut, 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 menggantikan 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.
Lihat juga
- tentang_Arrays
- tentang_Variabel_Otomatis
- tentang_Operator_Perbandingan
- tentang_Fungsi
- tentang_Bloks_Skrip
- tentang_Switch
- ForEach-Object
- Where-Object