about_PSItem

Deskripsi singkat

Variabel otomatis yang berisi objek saat ini dalam objek alur.

Deskripsi panjang

PowerShell menyertakan $PSItem variabel dan aliasnya, $_, sebagai variabel otomatis dalam blok skrip yang memproses objek saat ini, seperti dalam alur. Artikel ini menggunakan $PSItem dalam contoh, tetapi $PSItem dapat diganti dengan $_ dalam setiap contoh.

Anda dapat menggunakan variabel ini dalam perintah yang melakukan tindakan pada setiap objek dalam alur.

Ada beberapa kasus penggunaan umum untuk $PSItem:

  • dalam blok skrip untuk parameter Proses cmdlet ForEach-Object
  • dalam blok skrip untuk parameter FilterScript cmdlet Where-Object
  • dalam metode intrinsik ForEach dan Where
  • dengan parameter blok skrip yang tertunda
  • switch dalam nilai bersyarat pernyataan dan blok skrip terkait
  • process di blok fungsi
  • filter dalam definisi
  • dalam blok skrip atribut ValidateScript
  • dalam blok skrip -replace operand substitusi operator

Sisa artikel ini mencakup contoh penggunaan $PSItem untuk kasus penggunaan ini.

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

Where-Object FilterScript

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 .

Parameter blok 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 blok skrip 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 skrip kondisi pernyataan memeriksa apakah objek saat ini genap. Jika bahkan, blokir skrip tindakan terkait menghasilkan pesan yang menunjukkan objek saat ini bahkan.

Blokir skrip tindakan untuk kondisi menghasilkan default pesan yang menunjukkan objek saat ini ganjil.

Blok 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, nilainya adalah nilai 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

Tip

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 salah ValueFromPipeline* satu argumen untuk 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.

Blokir skrip atribut ValidateScript

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.

Blok skrip penggantian operator -replace

Mulai dari PowerShell 6, Anda dapat menggunakan $PSItem saat memanggil operator ganti 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.

Lihat juga