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-Objectcmdlet
  • 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
  • in het vervangende operandscriptblok van de -replace operator

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 descriptblokkeringen 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:
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 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.

De vervangingsscriptblok van de operator -replace

Vanaf PowerShell 6 kunt u de vervangingsoperator aanroepen $PSItemen een vervangingsscriptblok definiëren. Wanneer u dit doet, is de waarde $PSItem van de waarde van de huidige overeenkomst.

$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 dit voorbeeld vervangt de vervangingsscriptblok de oorspronkelijke datumtekenreeks door de standaardindeling voor de huidige cultuur door de waarde naar datum/tijd te gieten.

Zie ook