about_PSItem
Krótki opis
Zmienna automatyczna zawierająca bieżący obiekt w obiekcie potoku.
Długi opis
Program PowerShell zawiera zmienną $PSItem
i jej alias , $_
jako zmienne automatyczne w skryptach, które przetwarzają bieżący obiekt, na przykład w potoku. W tym artykule użyto $PSItem
w przykładach, ale $PSItem
można go zastąpić $_
w każdym przykładzie.
Tej zmiennej można używać w poleceniach, które wykonują akcję na każdym obiekcie w potoku.
Istnieje kilka typowych przypadków użycia dla programu $PSItem
:
- w bloku skryptu dla parametru
ForEach-Object
Procesu polecenia cmdlet - w bloku skryptu dla parametru
Where-Object
FilterScript polecenia cmdlet - w metodach wewnętrznych ForEach i Where
- z parametrami delay-bind scriptblock
switch
w wartościach warunkowych instrukcji i skojarzonych blokach skryptówprocess
w bloku funkcjifilter
w definicji- w bloku skryptu atrybutu ValidateScript
- w podstawiania operand scriptblock
-replace
operatora
W pozostałej części tego artykułu przedstawiono przykłady użycia $PSItem
dla tych przypadków użycia.
Proces ForEach-Object
Polecenie cmdlet ForEach-Object zostało zaprojektowane tak, aby działało na obiektach w potoku, wykonując skrypt parametru Process raz dla każdego obiektu w potoku.
Można użyć $PSItem
w bloku skryptu parametru Procesu , ale nie w skryptach parametru Początek lub Koniec . Jeśli odwołujesz się $PSItem
do skryptów parametru Początek lub Koniec , wartość jest $null
, ponieważ te bloki skryptów nie działają na każdym obiekcie w potoku.
$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
Polecenie cmdlet Where-Object jest przeznaczone do filtrowania obiektów w potoku.
Można użyć $PSItem
w skrypcie parametru FilterScript , który jest wykonywany raz dla każdego obiektu wejściowego w potoku.
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
W tym przykładzie funkcja FilterScript sprawdza, czy bieżący obiekt jest równomierny, odfiltrowuje wszystkie nieparzyste wartości i zwraca tylko 2
z oryginalnej listy.
Metody ForEach i Where
Metody wewnętrzne ForEach i Where dla tablic przyjmują blok skryptu jako parametr wejściowy. Możesz użyć $PSItem
elementu w tych skryptach, aby uzyskać dostęp do bieżącego obiektu.
@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B
W tym przykładzie blok scriptblock metody ForEach zawiera wielkie litery bieżącego obiektu. Następnie skryptblock metody Where zwraca tylko B
.
Parametry blokady skryptu powiązanego z opóźnieniem
Funkcja Delay-bind scriptblocks umożliwia $PSItem
definiowanie parametrów dla polecenia cmdlet potoku przed jego wykonaniem.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Bloki skryptów instrukcji Switch
W instrukcjach switch można użyć $PSItem
zarówno skryptów akcji, jak i skryptów warunku instrukcji.
$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
W tym przykładzie skrypt warunku instrukcji sprawdza, czy bieżący obiekt jest równomierny. Jeśli jest to równe, skojarzony skrypt akcji bloku zwraca komunikat wskazujący, że bieżący obiekt jest równomierny.
Blok skryptu akcji dla default
warunku zwraca komunikat wskazujący, że bieżący obiekt jest dziwny.
Bloki procesów funkcji
Podczas definiowania funkcji można użyć $PSItem
jej w process
definicji bloku, ale nie w begin
definicjach bloków lub end
. Jeśli odwołujesz się $PSItem
do begin
bloków lub end
, wartość jest $null
tym, że te bloki nie działają na każdym obiekcie w potoku.
W przypadku użycia $PSItem
w process
definicji bloku wartość to bieżący obiekt, jeśli funkcja jest wywoływana w potoku, a w przeciwnym razie $null
.
function Add-One {
process { $PSItem + 1 }
}
1, 2, 3 | Add-One
2
3
4
Napiwek
Chociaż można używać $PSItem
w funkcjach zaawansowanych, niewiele jest powodów, aby to zrobić. Jeśli zamierzasz odbierać dane wejściowe z potoku, najlepiej zdefiniować parametry z jednym z ValueFromPipeline*
argumentów atrybutu Parametr .
Użycie atrybutu parametru i powiązania polecenia cmdlet dla funkcji zaawansowanych sprawia, że implementacja jest bardziej jawna i przewidywalna niż przetwarzanie bieżącego obiektu w celu uzyskania wymaganych wartości.
Jedną z dobrych funkcji $PSItem
zaawansowanych jest sprawdzenie bieżącego obiektu w celu debugowania lub rejestrowania, gdy funkcja ma wiele parametrów, które pobierają dane wejściowe z potoku.
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
}
}
Ta przykładowa funkcja generuje tablicę obiektów JSON z znacznikiem czasu i komunikatem. Wywołana w potoku używa właściwości Message bieżącego obiektu dla każdego wpisu. Zapisuje również reprezentację JSON bieżącego obiektu w pełnym strumieniu, dzięki czemu można zobaczyć rzeczywiste dane wejściowe w porównaniu z dziennikami wyjściowymi.
$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)\/"
}
]
Definicje filtrów
Możesz użyć $PSItem
na liście instrukcji definicji filtru.
W przypadku użycia $PSItem
w filter
definicji wartość jest bieżącym obiektem, jeśli filtr jest wywoływany w potoku i w przeciwnym razie $null
.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
W tym przykładzie Test-IsEven
filtr zwraca dane wyjściowe $true
, jeśli bieżący obiekt jest liczbą parzystą, a $false
jeśli tak nie jest.
Blok skryptów atrybutu ValidateScript
Możesz użyć $PSItem
w bloku skryptowym atrybutu ValidateScript .
W przypadku użycia z językiem ValidateScript$PSItem
wartość bieżącego obiektu jest weryfikowana. Gdy zmienna lub wartość parametru jest tablicą, blok scriptblock jest wywoływany raz dla każdego obiektu w tablicy z $PSItem
jako bieżącym obiektem.
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.
W tym przykładzie blok skryptu dla atrybutu ValidateScript jest uruchamiany raz dla każdej wartości przekazanej do parametru Number , zwracając błąd, jeśli jakakolwiek wartość nie jest nawet.
Funkcja Add-EvenNumber
dodaje prawidłowe liczby wejściowe i zwraca sumę.
Blok skryptu podstawienia operatora -replace
Począwszy od programu PowerShell 6, można użyć podczas $PSItem
wywoływania operatora zastępowania i definiowania skryptu podstawienia. Gdy to zrobisz, wartość to wartość $PSItem
bieżącego dopasowania.
$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
W tym przykładzie skrypt podstawienia zastępuje oryginalny ciąg daty domyślnym formatem bieżącej kultury przez rzutowanie wartości do daty/godziny.