about_PSItem
Korte beschrijving
De automatische variabele die het huidige object in het pijplijnobject bevat.
Lange beschrijving
PowerShell bevat de $PSItem
variabele en de alias, $_
als automatische variabelen in scriptblocks die het huidige object verwerken, zoals in de pijplijn. Dit artikel gebruikt $PSItem
in de voorbeelden, maar $PSItem
kan in elk voorbeeld worden vervangen $_
door.
U kunt deze variabele gebruiken in opdrachten waarmee een actie wordt uitgevoerd op elk object in een pijplijn.
Er zijn enkele veelvoorkomende gebruiksvoorbeelden voor $PSItem
:
- in de scriptblock voor de procesparameter van de
ForEach-Object
cmdlet - in de scriptblock voor de FilterScript-parameter van de
Where-Object
cmdlet - in de intrinsieke methoden ForEach en Where
- met parameters voor scriptblokkering voor vertragingsbinding
- in de voorwaardelijke waarden en bijbehorende scriptblokkeringen van een
switch
instructie - in het
process
blok van een functie - in een
filter
definitie - in het scriptblok van het kenmerk ValidateScript
De rest van dit artikel bevat voorbeelden van het gebruik $PSItem
voor deze use cases.
ForEach-Object Process
De Cmdlet ForEach-Object is ontworpen om te werken op objecten in de pijplijn, waarbij de scriptblokkering van de procesparameter eenmaal wordt uitgevoerd voor elk object in de pijplijn.
U kunt het scriptblok van de procesparameter gebruiken$PSItem
, maar niet in de scriptblokkeringen begin- of eindparameter. Als u in de scriptblokkeringen begin- of eindparameter verwijst$PSItem
, is $null
de waarde omdat deze scriptblokkeringen niet op elk object in de pijplijn werken.
$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
De cmdlet Where-Object is ontworpen om objecten in de pijplijn te filteren.
U kunt deze gebruiken $PSItem
in het scriptblok van de FilterScript-parameter , die eenmaal wordt uitgevoerd voor elk invoerobject in de pijplijn.
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
In dit voorbeeld controleert FilterScript of het huidige object even is, worden eventuele oneven waarden uitgefilterd en wordt alleen 2
geretourneerd uit de oorspronkelijke lijst.
ForEach- en Where-methoden
Zowel de ForEach - als where-intrinsieke methoden voor matrices nemen een scriptblok als invoerparameter. U kunt de $PSItem
in deze scriptblokkeringen gebruiken om toegang te krijgen tot het huidige object.
@('a', 'b', 'c').ForEach({ $PSItem.ToUpper() }).Where({ $PSItem -ceq 'B' })
B
In dit voorbeeld wordt in het scriptblok van de ForEach-methode hoofdletters van het huidige object weergegeven. Vervolgens retourneert de scriptblock van de where-methode alleen B
.
Parameters voor scriptblokkering voor vertragingsbinding
Met scriptblokkeringen voor vertragingsbinding kunt u $PSItem
parameters voor een pijplijn-cmdlet definiƫren voordat u deze uitvoert.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Scriptblokkeringen voor switchinstructies
In switch-instructies kunt u zowel actiescriptblocks als instructievoorwaardescriptblocks gebruiken $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 dit voorbeeld controleert het scriptblok voor de instructievoorwaarde of het huidige object zelfs is. Als het even is, voert het bijbehorende actiescriptblok een bericht uit dat het huidige object zelfs is.
Met het actiescriptblok voor de default
voorwaarde wordt een bericht weergegeven dat aangeeft dat het huidige object oneven is.
Functieprocesblokken
Wanneer u een functie definieert, kunt u deze gebruiken $PSItem
in de process
blokdefinitie, maar niet in de begin
of end
blokdefinities. Als u in de begin
of end
blokken verwijst$PSItem
, is $null
de waarde omdat deze blokken niet op elk object in de pijplijn werken.
Wanneer u in de blokdefinitie gebruikt$PSItem
, is de waarde de waarde het huidige object als de functie wordt aangeroepen in de pijplijn en anders$null
.process
function Add-One {
process { $PSItem + 1 }
}
1, 2, 3 | Add-One
2
3
4
Tip
Hoewel u in geavanceerde functies kunt gebruiken$PSItem
, is er weinig reden om dit te doen. Als u invoer van de pijplijn wilt ontvangen, kunt u het beste parameters definiƫren met een van de ValueFromPipeline*
argumenten voor het parameterkenmerk .
Het gebruik van het parameterkenmerk en de cmdlet-binding voor geavanceerde functies maakt de implementatie explicieter en voorspelbaarder dan het verwerken van het huidige object om de vereiste waarden op te halen.
Een goed gebruik van $PSItem
geavanceerde functies is om het huidige object zelf te inspecteren voor foutopsporing of logboekregistratie wanneer de functie meerdere parameters heeft die invoer van de pijplijn overnemen.
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
}
}
Met deze voorbeeldfunctie wordt een matrix van JSON-objecten uitgevoerd met een bericht en tijdstempel. Wanneer deze wordt aangeroepen in een pijplijn, wordt de eigenschap Message van het huidige object voor elke vermelding gebruikt. Ook wordt de JSON-weergave van het huidige object zelf naar de uitgebreide stroom geschreven, zodat u de werkelijke invoer kunt zien in vergelijking met de uitvoerlogboeken.
$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)\/"
}
]
Filterdefinities
U kunt deze gebruiken $PSItem
in de instructielijst van de definitie van een filter.
Wanneer u in een definitie gebruikt$PSItem
, is de waarde het huidige object als het filter wordt aangeroepen in de pijplijn en anders$null
.filter
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
In dit voorbeeld wordt het Test-IsEven
filter uitgevoerd $true
als het huidige object een even getal is en $false
of dit niet het is.
Het scriptblok van het ValidateScript-kenmerk
U kunt het scriptblok van een ValidateScript-kenmerk gebruiken$PSItem
.
Wanneer het wordt gebruikt met ValidateScript, $PSItem
is de waarde van het huidige object dat wordt gevalideerd. Wanneer de variabele of parameterwaarde een matrix is, wordt het scriptblok eenmaal aangeroepen voor elk object in de matrix met $PSItem
als het huidige object.
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 : 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.
At line:1 char:24
+ Add-EvenNumber -Number 1, 2
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Add-EvenNumber],
ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,
Add-EvenNumber
In dit voorbeeld wordt het scriptblok voor het ValidateScript-kenmerk eenmaal uitgevoerd voor elke waarde die wordt doorgegeven aan de parameter Getal , waarbij een fout wordt geretourneerd als een waarde niet eens is.
Met Add-EvenNumber
de functie worden de geldige invoernummers toegevoegd en wordt het totaal geretourneerd.