about_PSItem

Description courte

Variable automatique qui contient l’objet actuel dans l’objet de pipeline.

Description longue

PowerShell inclut la $PSItem variable et son alias, $_en tant que variables automatiques dans les blocs de script qui traitent l’objet actuel, comme dans le pipeline. Cet article utilise $PSItem dans les exemples, mais $PSItem peut être remplacé $_ par chaque exemple.

Vous pouvez utiliser cette variable dans les commandes qui effectuent une action sur chaque objet d’un pipeline.

Il existe quelques cas d’usage courants pour $PSItem:

  • dans le scriptblock pour le paramètre Process de l’applet ForEach-Objectde commande
  • dans le scriptblock pour le paramètre FilterScript de l’applet Where-Object de commande
  • dans les méthodes intrinsèques ForEach et Where
  • avec des paramètres de script de liaison différée
  • dans les valeurs conditionnelles d’une switch instruction et les scriptsblocks associés
  • dans le process bloc d’une fonction
  • dans une filter définition
  • dans le scriptblock de l’attribut ValidateScript
  • dans le script d’opérande de substitution de l’opérateur -replace

Le reste de cet article inclut des exemples d’utilisation $PSItem pour ces cas d’usage.

Processus ForEach-Object

L’applet de commande ForEach-Object est conçue pour fonctionner sur des objets dans le pipeline, en exécutant le scriptblock du paramètre Process une fois pour chaque objet du pipeline.

Vous pouvez utiliser $PSItem dans le scriptblock du paramètre Process , mais pas dans les blocs de script de paramètre Begin ou End . Si vous référencez $PSItem dans les scripts de paramètre Begin ou End , la valeur est $null due au fait que ces blocs de script ne fonctionnent pas sur chaque objet du pipeline.

$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

L’applet de commande Where-Object est conçue pour filtrer des objets dans le pipeline.

Vous pouvez utiliser $PSItem dans le scriptblock du paramètre FilterScript , qui s’exécute une fois pour chaque objet d’entrée dans le pipeline.

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

Dans cet exemple, le FilterScript case activée s pour voir si l’objet actuel est même, en filtrant les valeurs impaires et retourne uniquement 2 à partir de la liste d’origine.

Méthodes ForEach et Where

Les méthodes intrinsèques ForEach et Where pour les tableaux prennent un scriptblock comme paramètre d’entrée. Vous pouvez utiliser ces $PSItem scriptsblocks pour accéder à l’objet actuel.

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

Dans cet exemple, le scriptblock de la méthode ForEach majuscules de l’objet actif. Ensuite, le scriptblock de la méthode Where retourne uniquement B.

Paramètres de script de liaison différée

Les blocs de script de liaison différé vous $PSItem permettent de définir des paramètres pour une applet de commande pipeline avant de l’exécuter.

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

Switch statement scriptblocks

Dans les instructions switch, vous pouvez utiliser $PSItem dans les scripts d’action et les scripts de condition d’instruction.

$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

Dans cet exemple, le scriptblock de condition d’instruction case activée indique si l’objet actuel est même. Si c’est le cas, le scriptblock d’action associé génère un message indiquant que l’objet actuel est même.

Le script d’action pour la default condition génère un message indiquant que l’objet actuel est impair.

Blocs de processus de fonction

Lorsque vous définissez une fonction, vous pouvez l’utiliser $PSItem dans la définition de process bloc, mais pas dans les begin définitions ou end les définitions de bloc. Si vous référencez $PSItem dans le begin ou end les blocs, la valeur est $null due au fait que ces blocs ne fonctionnent pas sur chaque objet du pipeline.

Lorsque vous utilisez $PSItem dans la définition de process bloc, la valeur est l’objet actuel si la fonction est appelée dans le pipeline et sinon $null.

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

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

Conseil

Bien que vous puissiez utiliser $PSItem dans les fonctions avancées, il n’y a pas de raison de le faire. Si vous envisagez de recevoir une entrée du pipeline, il est préférable de définir des paramètres avec l’un des ValueFromPipeline* arguments de l’attribut Paramètre .

L’utilisation de l’attribut Parameter et de la liaison d’applet de commande pour les fonctions avancées rend l’implémentation plus explicite et prévisible que le traitement de l’objet actuel pour obtenir les valeurs requises.

Une bonne utilisation des $PSItem fonctions avancées consiste à inspecter l’objet actuel lui-même pour le débogage ou la journalisation lorsque la fonction a plusieurs paramètres qui prennent l’entrée du pipeline.

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

Cet exemple de fonction génère un tableau d’objets JSON avec un message et un horodatage. Lorsqu’elle est appelée dans un pipeline, elle utilise la propriété Message de l’objet actif pour chaque entrée. Il écrit également la représentation JSON de l’objet actuel lui-même dans le flux détaillé, de sorte que vous pouvez voir l’entrée réelle par rapport aux journaux de sortie.

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

Définitions de filtres

Vous pouvez utiliser $PSItem dans la liste d’instructions de la définition d’un filtre.

Lorsque vous utilisez $PSItem dans une filter définition, la valeur est l’objet actuel si le filtre est appelé dans le pipeline et sinon $null.

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

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

Dans cet exemple, le Test-IsEven filtre se $true produit si l’objet actuel est un nombre pair et $false si ce n’est pas le cas.

Scriptblock d’attribut ValidateScript

Vous pouvez utiliser $PSItem dans le scriptblock d’un attribut ValidateScript . Lorsqu’il est utilisé avec ValidateScript, $PSItem est la valeur de l’objet actuel en cours de validation. Lorsque la variable ou la valeur du paramètre est un tableau, le scriptblock est appelé une fois pour chaque objet du tableau avec $PSItem comme objet actuel.

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.

Dans cet exemple, le scriptblock pour l’attribut ValidateScript s’exécute une fois pour chaque valeur passée au paramètre Number , en retournant une erreur si aucune valeur n’est même.

La Add-EvenNumber fonction ajoute les nombres d’entrée valides et retourne le total.

Scriptblock de substitution de l’opérateur -replace

À compter de PowerShell 6, vous pouvez utiliser $PSItem lors de l’appel de l’opérateur replace et de la définition d’un script de substitution. Lorsque vous le faites, la valeur est $PSItem la valeur de la correspondance actuelle.

$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

Dans cet exemple, le scriptblock de substitution remplace la chaîne de date d’origine par le format par défaut de la culture actuelle en cas de conversion de la valeur en datetime.

Voir aussi