Freigeben über


about_PSItem

Kurze Beschreibung

Die automatische Variable, die das aktuelle Objekt im Pipelineobjekt enthält.

Lange Beschreibung

PowerShell enthält die $PSItem Variable und ihren Alias als $_automatische Variablen in Skriptblöcken, die das aktuelle Objekt verarbeiten, z. B. in der Pipeline. Dieser Artikel verwendet $PSItem in den Beispielen, kann aber $PSItem in jedem Beispiel durch $_ ersetzt werden.

Sie können diese Variable in Befehlen verwenden, die eine Aktion für jedes Objekt in einer Pipeline ausführen.

Es gibt einige häufige Anwendungsfälle für $PSItem:

  • im Skriptblock für den Process-Parameter des Cmdlets ForEach-Object
  • im Skriptblock für den FilterScript-Parameter des Cmdlets Where-Object
  • in den systeminternen Methoden ForEach und Where
  • mit Verzögerungsbindungs-Skriptblockparametern
  • in den bedingten Werten einer switch Anweisung und den zugeordneten Skriptblocks
  • im process Block einer Funktion
  • in einer filter Definition
  • im Skriptblock des ValidateScript-Attributs
  • im Ersetzungsoperndenskriptblock des -replace -Operators

Der Rest dieses Artikels enthält Beispiele für die Verwendung $PSItem für diese Anwendungsfälle.

ForEach-Object Prozess

Das Cmdlet ForEach-Object ist für die Ausführung von Objekten in der Pipeline konzipiert, wobei der Skriptblock des Process-Parameters einmal für jedes Objekt in der Pipeline ausgeführt wird.

Sie können im Scriptblock des Process-Parameters, aber nicht in den Skriptblocks der Begin- oder End-Parameter verwenden$PSItem. Wenn Sie in den Skriptblöcken des Begin- oder End-Parameters verweisen$PSItem, ist $null der Wert darauf zurückzuführen, dass diese Skriptblöcke nicht für jedes Objekt in der Pipeline ausgeführt werden.

$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

Das Cmdlet Where-Object ist zum Filtern von Objekten in der Pipeline konzipiert.

Sie können im Skriptblock den FilterScript-Parameter verwenden$PSItem, der für jedes Eingabeobjekt in der Pipeline einmal ausgeführt wird.

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

In diesem Beispiel überprüft FilterScript , ob das aktuelle Objekt gerade ist, filtert ungerade Werte heraus und gibt nur 2 aus der ursprünglichen Liste zurück.

ForEach- und Where-Methoden

Sowohl die systeminternen Methoden ForEach als auch Where für Arrays verwenden einen Scriptblock als Eingabeparameter. Sie können die $PSItem in diesen Skriptblöcken verwenden, um auf das aktuelle Objekt zuzugreifen.

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

In diesem Beispiel enthält der Skriptblock der ForEach-Methode Großbuchstaben für das aktuelle Objekt. Dann gibt der Skriptblock der Where-Methode nur Bzurück.

Verzögerte Bindung von Skriptblockparametern

Mithilfe von Verzögerungsbindungsskriptblöcken können Sie $PSItem Parameter für ein Pipeline-Cmdlet definieren, bevor Sie es ausführen.

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

Skriptblocks für Die Switch-Anweisung

In switch-Anweisungen können Sie sowohl in Aktionsskriptblocks als auch in Anweisungsbedingungs-Skriptblocks verwenden $PSItem .

$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

In diesem Beispiel überprüft die Anweisungsbedingung scriptblock, ob das aktuelle Objekt gerade ist. Wenn dies gerade ist, gibt der zugeordnete Aktionsskriptblock eine Meldung aus, die angibt, dass das aktuelle Objekt gerade ist.

Der Aktionsskriptblock für die default Bedingung gibt eine Meldung aus, die angibt, dass das aktuelle Objekt ungerade ist.

Funktionsprozessblöcke

Wenn Sie eine Funktion definieren, können Sie in der process Blockdefinition, aber nicht in der begin Blockdefinition oder end verwenden$PSItem. Wenn Sie in den begin Blöcken oder end verweisen$PSItem, liegt $null der Wert daran, dass diese Blöcke nicht für jedes Objekt in der Pipeline ausgeführt werden.

Wenn Sie in der Blockdefinition verwenden$PSItem, ist der Wert das aktuelle Objekt, wenn die Funktion in der Pipeline aufgerufen wird und andernfalls $null.process

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

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

Tipp

Obwohl Sie in erweiterten Funktionen verwenden $PSItem können, gibt es wenig Grund dazu. Wenn Sie Eingaben aus der Pipeline empfangen möchten, ist es am besten, Parameter mit einem der ValueFromPipeline* Argumente für das Parameter-Attribut zu definieren.

Die Verwendung des Parameter-Attributs und des Cmdlets für erweiterte Funktionen macht die Implementierung expliziter und vorhersagbarer als die Verarbeitung des aktuellen Objekts zum Abrufen der erforderlichen Werte.

Eine gute Verwendung von $PSItem in erweiterten Funktionen besteht darin, das aktuelle Objekt selbst zum Debuggen oder Protokollieren zu untersuchen, wenn die Funktion über mehrere Parameter verfügt, die Eingaben aus der Pipeline übernehmen.

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

Diese Beispielfunktion gibt ein Array von JSON-Objekten mit einer Nachricht und einem Zeitstempel aus. Wenn sie in einer Pipeline aufgerufen wird, wird die Message-Eigenschaft des aktuellen Objekts für jeden Eintrag verwendet. Außerdem wird die JSON-Darstellung des aktuellen Objekts selbst in den ausführlichen Stream geschrieben, sodass Sie die tatsächliche Eingabe im Vergleich zu den Ausgabeprotokollen sehen können.

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

Filterdefinitionen

Sie können in der Anweisungsliste der Definition eines Filters verwenden$PSItem.

Wenn Sie in einer filter Definition verwenden$PSItem, ist der Wert das aktuelle Objekt, wenn der Filter in der Pipeline und andernfalls $nullaufgerufen wird.

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

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

In diesem Beispiel gibt der Test-IsEven Filter aus $true , wenn das aktuelle Objekt eine gerade Zahl ist und $false wenn dies nicht der Fall ist.

Der Skriptblock des ValidateScript-Attributs

Sie können im Skriptblock eines ValidateScript-Attributs verwenden$PSItem. Bei Verwendung mit ValidateScript ist der Wert des aktuellen Objekts, $PSItem das überprüft wird. Wenn es sich bei der Variablen oder dem Parameterwert um ein Array handelt, wird der Skriptblock einmal für jedes Objekt im Array mit $PSItem als aktuelles Objekt aufgerufen.

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.

In diesem Beispiel wird der Skriptblock für das ValidateScript-Attribut einmal für jeden Wert ausgeführt, der an den Parameter Number übergeben wird, und gibt einen Fehler zurück, wenn ein Wert nicht gerade ist.

Die Add-EvenNumber Funktion fügt die gültigen Eingabenummern hinzu und gibt die Summe zurück.

Der Ersetzungsskriptblock des -replace-Operators

Ab PowerShell 6 können Sie verwenden $PSItem , wenn Sie den Replace-Operator aufrufen und einen Ersetzungsskriptblock definieren. Wenn Sie dies tun, ist der Wert von $PSItem der Wert der aktuellen Übereinstimmung.

$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

In diesem Beispiel ersetzt der Ersetzungsskriptblock die ursprüngliche Datumszeichenfolge durch das Standardformat für die aktuelle Kultur, indem der Wert in datetime konvertiert wird.

Weitere Informationen