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 Skriptblocks, die das aktuelle Objekt verarbeiten, z. B. in der Pipeline. In diesem Artikel werden die Beispiele verwendet $PSItem
, können aber $PSItem
in jedem Beispiel 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 Scriptblock für den Parameter "Process" des Cmdlets
ForEach-Object
- im Scriptblock für den FilterScript-Parameter des Cmdlets
Where-Object
- in den systeminternen Methoden ForEach und Where
- mit Parametern für "delay-bind scriptblock"
- in den bedingten Werten einer
switch
Anweisung und den zugehörigen Scriptblocks process
im Block einer Funktion- in einer
filter
Definition - im Scriptblock 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-Objektprozess
Das Cmdlet ForEach-Object ist für die Ausführung von Objekten in der Pipeline konzipiert, wobei der Scriptblock des Process-Parameters für jedes Objekt in der Pipeline einmal ausgeführt wird.
Sie können den Scriptblock des Process-Parameters verwenden$PSItem
, aber nicht in den Skriptblocks des Begin- oder End-Parameters. Wenn Sie in den Skriptblocks für den Begin- oder End-Parameter verweisen$PSItem
, liegt $null
der Wert daran, dass diese Scriptblocks 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 wurde entwickelt, um Objekte in der Pipeline zu filtern.
Sie können im Scriptblock des FilterScript-Parameters 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 und gibt nur 2
aus der ursprünglichen Liste zurück.
ForEach- und Where-Methoden
Sowohl die systeminternen Methoden ForEach als auch die systeminternen Methoden für Arrays verwenden einen Scriptblock als Eingabeparameter. Sie können die $PSItem
in diesen Scriptblocks verwenden, um auf das aktuelle Objekt zuzugreifen.
@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B
In diesem Beispiel wird mit dem Scriptblock der ForEach-Methode das aktuelle Objekt in Großbuchstaben geschrieben. Then the scriptblock of the Where method returns only B
.
Delay-bind scriptblock-Parameter
Mit Skriptblocks mit Verzögerungsbindung können Sie $PSItem
Parameter für ein weitergeleitetes Cmdlet definieren, bevor Sie es ausführen.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Switch-Anweisungsskriptblocks
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 der Skriptblock für die Anweisungsbedingung, ob das aktuelle Objekt gerade ist. Wenn dies sogar der Grund 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 den begin
Definitionen oder end
Blockdefinitionen verwenden$PSItem
. Wenn Sie in den end
begin
Blöcken 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 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
Während Sie in erweiterten Funktionen verwenden $PSItem
können, gibt es wenig Grund, dies zu tun. Wenn Sie eingaben von der Pipeline empfangen möchten, ist es am besten, Parameter mit einem der ValueFromPipeline*
Argumente für das Parameter-Attribut zu definieren.
Wenn Sie das Parameter-Attribut und die Cmdlet-Bindung für erweiterte Funktionen verwenden, wird die Implementierung expliziter und vorhersehbarer als die Verarbeitung des aktuellen Objekts, um die erforderlichen Werte abzurufen.
Eine gute Verwendung in $PSItem
erweiterten Funktionen besteht darin, das aktuelle Objekt selbst für das Debuggen oder Protokollieren zu prüfen, 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 Datenstrom 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 Definition verwenden$PSItem
, ist der Wert das aktuelle Objekt, wenn der Filter in der Pipeline aufgerufen wird und andernfalls $null
.filter
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 Scriptblock des ValidateScript-Attributs
Sie können im Scriptblock eines ValidateScript-Attributs verwenden$PSItem
.
Bei Verwendung mit ValidateScript$PSItem
ist der Wert des aktuellen Objekts, das überprüft wird. Wenn die Variable oder der Parameterwert ein Array ist, wird der Scriptblock einmal für jedes Objekt im Array mit $PSItem
dem aktuellen 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 Scriptblock 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 Beliebiger Wert nicht einmal ist.
Die Add-EvenNumber
Funktion addiert die gültigen Eingabenummern und gibt die Summe zurück.
Das Skriptblock des Ersetzungsoperators -replace
Ab PowerShell 6 können Sie beim Aufrufen des Ersetzungsoperators und Definieren eines Ersetzungsskriptblocks verwenden$PSItem
. Wenn Sie dies tun, ist der Wert des $PSItem
Werts 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 er den Wert in "datetime" umgibt.