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-Object
de 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, filterScript vérifie si l’objet actuel est même, en filtrant les valeurs impaires et ne retourne qu’à 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 script de condition d’instruction vérifie 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.