Sdílet prostřednictvím


about_PSItem

Krátký popis

Automatická proměnná, která obsahuje aktuální objekt v objektu kanálu.

Dlouhý popis

PowerShell obsahuje dvě automatické proměnné$_ a $PSItem, které odkazují na aktuální objekt v kanálu.

$PSItem byl přidán do PowerShellu při pokusu o poskytnutí jasnějšího významu názvu proměnné. V praxi se ale nejčastěji používá podtržítko$_ podtržítka dolaru.

I když se tento článek používá $PSItem v příkladech, $PSItem můžete ho nahradit $_ v každém příkladu. $_ je upřednostňovaným využitím.

Existuje několik běžných případů použití $PSItem:

  • V bloku skriptů pro parametr Process cmdletu ForEach-Object
  • V skriptblocku pro parametr FilterScript příkazu Where-Object
  • Ve základních metodách ForEach a Where
  • s parametry skriptového bloku s opožděným svázáním
  • switch V podmíněných hodnotách a přidružených příkazech příkazu
  • process V bloku příkazu funkce
  • V definici filter
  • V bloku skriptu atributu ValidateScript
  • V bloku příkazu catch
  • V nahrazovacím operandovém bloku operátoru -replace

Zbytek tohoto článku obsahuje příklady použití $PSItem pro tyto případy použití.

parametr procesu ForEach-Object

Rutina ForEach-Object je navržena tak, aby pracovala s objekty v pipeline, přičemž spustí blok skriptu parametru Process jednou pro každý objekt v pipeline.

$PSItem můžete použít ve skriptu parametru Process, ale ne ve skriptu parametru Begin nebo End. Pokud odkazujete na $PSItem v parametru skriptového bloku Begin nebo End, hodnota je $null, protože tyto skriptové bloky nepracují s každým objektem v pipeline.

$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

Rutina Where-Object je navržená k filtrování objektů v pipelině.

Můžete použít $PSItem v blokovém skriptu parametru FilterScript, který se spustí jednou pro každý vstupní objekt v potrubí.

1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2

V tomto příkladu FilterScript zkontroluje, jestli je aktuální objekt sudý, odfiltruje všechny liché hodnoty a vrátí z původního seznamu pouze 2.

Metody ForEach a Where

ForEach i Kde vnitřní metody polí přebírají blok skriptu jako vstupní parametr. K přístupu k aktuálnímu objektu můžete použít $PSItem v těchto skriptech.

@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B

V tomto příkladu převede skriptblock metody ForEach aktuální objekt na velká písmena. Poté scriptblock Where metoda vrátí pouze B.

Blokování skriptů s vazbou zpoždění

Zpožděně vázané bloky skriptů umožňují použít $PSItem k definování parametrů pro rutinu s potrubím před jejím spuštěním.

dir config.log | Rename-Item -NewName { "old_$($_.Name)" }

Příkazy přepínače

Ve příkazech switchmůžete použít $PSItem jak v akčních skriptech, tak v podmínkových skriptech.

$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

V tomto příkladu blok příkazu podmínky kontroluje, zda je aktuální objekt sudý. Pokud ano, přidružený blok příkazu akce zobrazí zprávu, která označuje, že aktuální objekt je sudý.

Blok příkazu akce pro podmínku default vypíše zprávu označující, že aktuální objekt je lichý.

Bloky příkazů procesu funkce

Když definujete funkci , můžete použít $PSItem v definici bloku process, ale ne v definicích bloků begin nebo end. Pokud odkazujete na $PSItem v blocích begin nebo end, hodnota je $null, protože tyto bloky nepracují s každým objektem v kanálu.

Při použití $PSItem v process definici bloku příkazu je hodnota aktuální objekt, pokud je funkce volána v kanálu a jinak $null.

function Add-One {
    process { $PSItem + 1 }
}

1, 2, 3 | Add-One
2
3
4

Rada

I když můžete $PSItem použít v pokročilých funkcích, není k tomu mnoho důvodů. Pokud máte v úmyslu přijímat vstup z kanálu, je nejlepší definovat parametry pomocí ValueFromPipeline argumentů v ValueFromPipelineByPropertyName atributu Parameter .

Použitím atributu Parametr a vazby rutin pro pokročilé funkce je implementace explicitnější a předvídatelnější než zpracování aktuálního objektu k získání požadovaných hodnot.

Jedním z důvodů pro použití $PSItem v pokročilých funkcích je prozkoumat samotný aktuální objekt pro ladění nebo protokolování, pokud má funkce více parametrů, které přebírají vstup z potrubí.

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
    }
}

Tato ukázková funkce vypíše pole objektů JSON se zprávou a časovým razítkem. Při použití v zpracovatelském řetězci používá vlastnost Message pro aktuální objekt pro každou položku. Zapisuje také reprezentaci JSON aktuálního objektu do podrobného datového proudu, takže můžete vidět skutečný vstup v porovnání s výstupními protokoly.

$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)\/"
    }
]

Definice filtru

Můžete použít $PSItem v seznamu příkazů při definování filtru .

Pokud použijete $PSItem v definici filter, je hodnota aktuálním objektem, pokud je filtr volán v kanálu, a jinak je $null.

filter Test-IsEven { ($PSItem % 2) -eq 0 }

1, 2, 3 | Test-IsEven
False
True
False

V tomto příkladu Test-IsEven filtruje výstup $true, pokud je aktuální objekt sudým číslem a $false pokud ne.

Atribut ValidateScript ScriptBlock

V bloku skriptu atributu $PSItem můžete použít . Při použití s ValidateScript, $PSItem je hodnota aktuálního objektu, který se ověřuje. Pokud je proměnná nebo hodnota parametru polem, skript-blok se volá jednou pro každý objekt v poli, s $PSItem jako aktuálním objektem.

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.

V tomto příkladu se skriptblock pro atribut ValidateScript spustí jednou pro každou hodnotu předanou parametru Number a vrátí chybu, pokud žádná hodnota ani není.

Funkce Add-EvenNumber sečte platná vstupní čísla a vrátí součet.

Blok catch příkazu

catch V bloku $PSItem příkazu obsahuje aktuální chybu. Objekt je typu ErrorRecord.

try { NonsenseString }
catch {
    Write-Host "An error occurred:"
    Write-Host $PSItem
}

Spuštění tohoto skriptu vrátí následující výsledek:

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.

Další příklady najdete v části Přístup k informacím o výjimce v about_Try_Catch_Finally.

Blok -replace skriptu nahrazení operátora

Počínaje PowerShellem 6 můžete použít $PSItem při volání operátoru -replace a definování náhradního skriptu . Když to uděláte, hodnota $PSItem je hodnota aktuální shody.

$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

V tomto příkladu náhradní skriptblock nahradí původní řetězec data výchozím formátem aktuální jazykové verze přetypováním hodnoty na datetime.

Změna hodnoty $PSItem

Hodnotu $PSItem můžete změnit přiřazením nové hodnoty. To však může změnit očekávané chování libovolného kódu, který spoléhá na $PSItem. Podívejte se na následující příklad. Za normálních switch okolností by příkaz zpracovával všechny hodnoty v matici $names. Vzhledem k tomu, že hodnota $PSItem je změněna uvnitř bloku příkazu akce, switch příkaz zpracuje pouze první hodnotu.

$names = 'Alice', 'Charlie'
switch ($names) {
    Alice   { "$PSItem says 'Hello!'"; $PSItem = 'Bob' }
    Bob     { "$PSItem says 'Goodbye.'"; $PSItem = 'Charlie'; break }
    Charlie { "$PSItem says 'How are you?'" }
}

Když příkaz switch vyhodnotí první hodnotu, Aliceodpovídá první podmínce a spustí přidružený blok příkazu akce. Uvnitř tohoto bloku se hodnota $PSItem změní na Bob, což má vliv také na vyhodnocení switch příkazu.

Alice says 'Hello!'
Bob says 'Goodbye.'

Měli byste se vyhnout změně hodnoty $PSItem.

Viz také