Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Brève description
La variable automatique qui contient l'objet actuel dans l'objet pipeline.
Description longue
PowerShell inclut deux variables automatiques et $_ « $PSItem » qui font référence à l’objet actuel dans le pipeline.
$PSItem a été ajouté à PowerShell dans une tentative de fournir une signification plus claire au nom de la variable. Toutefois, dans la pratique, le formulaire de $_ est le plus couramment utilisé.
Bien que cet article utilise $PSItem dans les exemples, $PSItem il peut être remplacé $_ par chaque exemple.
$_ est l’utilisation préférée.
Il existe quelques cas d'utilisation courante de $PSItem :
- Dans le bloc de script pour le paramètre Process de l’applet de commande
ForEach-Object - Dans le bloc de script pour le paramètre FilterScript de l’applet de commande
Where-Object - Dans les méthodes intrinsèques ForEach et Where
- avec les paramètres du bloc de script delay-bind
- Dans les valeurs conditionnelles d’une
switchinstruction et les instructions associées - Dans le
processbloc d’instruction d’une fonction - Dans une définition
filter - Dans le bloc de script de l'attribut ValidateScript
- Dans le bloc d’instructions d’un
catch - Dans le bloc de script de l'opérande de substitution de l'opérateur
-replace
La suite de cet article présente des exemples d'utilisation de $PSItem dans ces cas.
paramètre de processus ForEach-Object
La cmdlet ForEach-Object est conçue pour opérer sur les objets du pipeline, en exécutant le bloc de script du paramètre Process une fois pour chaque objet du pipeline.
Vous pouvez utiliser $PSItem dans le bloc de script du paramètre Processus , mais pas dans les blocs de script des paramètres Begin ou End . Si vous faites référence à $PSItem dans les blocs de scripts Begin ou End parameter, la valeur est $null car ces blocs de scripts n'opèrent 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 bloc de script du paramètre FilterScript, qui s'exécute une fois pour chaque objet en entrée dans le pipeline.
1, 2, 3 | Where-Object -FilterScript { ($PSItem % 2) -eq 0 }
2
Dans cet exemple, le script FilterScript vérifie si l'objet actuel est un nombre pair, en excluant les valeurs impaires, et retourne uniquement 2 de la liste d'origine.
Méthodes ForEach et Where
Les méthodes intrinsèques ForEach et Where pour les tableaux prennent un bloc de script comme paramètre d'entrée. Vous pouvez utiliser le $PSItem dans ces blocs de script 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 met en majuscules l’objet actuel. Le bloc de script de la méthode Where ne renvoie alors que B.
Blocages de script de liaison différée
les blocs de script à liaison différée vous permettent d’utiliser $PSItem pour définir des paramètres pour une cmdlet en pipeline avant de l’exécuter.
dir config.log | Rename-Item -NewName { "old_$($_.Name)" }
Instructions switch
Dans les instructions de commutation, vous pouvez utiliser $PSItem à la fois dans les blocs de script d'action et dans les blocs de script 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 bloc d’instruction condition vérifie si l’objet actuel est même. Si c’est le cas, le bloc d’instruction d’action associé génère un message indiquant que l’objet actuel est même.
Le bloc d’instruction d’action pour la default condition génère un message indiquant que l’objet actuel est impair.
Blocs d’instructions de processus de fonction
Lorsque vous définissez une fonction , vous pouvez utiliser $PSItem dans la définition de bloc process, mais pas dans les définitions de blocs begin ou end. Si vous faites référence à $PSItem dans les blocs begin ou end, la valeur est $null, car ces blocs n'opèrent pas sur chaque objet du pipeline.
Lorsque vous utilisez $PSItem dans la définition de process bloc d’instruction, 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 guère de raison de le faire. Si vous envisagez de recevoir des entrées à partir du pipeline, il est préférable de définir des paramètres à l’aide des arguments ou ValueFromPipeline des ValueFromPipelineByPropertyName arguments dans l’attribut Paramètre.
L'utilisation de l'attribut Parameter et de la cmdlet binding pour les fonctions avancées rend la mise en œuvre plus explicite et prévisible que le traitement de l'objet courant pour obtenir les valeurs requises.
Une bonne utilisation de $PSItem dans les fonctions avancées est d'inspecter l'objet courant lui-même pour le débogage ou le journal lorsque la fonction a plusieurs paramètres qui prennent des entrées dans le 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 produit 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 courant pour chaque entrée. Il écrit également la représentation JSON de l'objet courant 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 du filtre .
Lorsque vous utilisez $PSItem dans une définition de filter, la valeur correspond à l’objet actuel si le filtre est appelé dans le pipeline ; sinon, elle est $null.
filter Test-IsEven { ($PSItem % 2) -eq 0 }
1, 2, 3 | Test-IsEven
False
True
False
Dans cet exemple, le filtre Test-IsEven produit $true si l'objet courant est un nombre pair et $false s'il ne l'est pas.
Attribut ValidateScript ScriptBlock
Vous pouvez utiliser $PSItem dans le scriptblock d’un attribut ValidateScript.
Lorsqu'il est utilisé avec ValidateScript, $PSItem est la valeur de l'objet courant en cours de validation. Lorsque la valeur de la variable ou du paramètre est un tableau, le bloc de script est appelé une fois pour chaque objet du tableau avec $PSItem comme objet courant.
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 bloc de script de l'attribut ValidateScript s'exécute une fois pour chaque valeur passée au paramètre Number, renvoyant une erreur si une valeur n'est pas paire.
La fonction Add-EvenNumber additionne les nombres valides et renvoie le total.
Bloc d’instructions catch
Dans un bloc d’instructions catch , $PSItem contient l’erreur actuelle. L’objet est de type ErrorRecord.
try { NonsenseString }
catch {
Write-Host "An error occurred:"
Write-Host $PSItem
}
L’exécution de ce script retourne le résultat suivant :
An error occurred:
The term 'NonsenseString' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
Pour plus d’exemples, consultez la section Accès aux informations d’exception dans about_Try_Catch_Finally.
-replace Scriptblock de substitution de l’opérateur
À compter de PowerShell 6, vous pouvez utiliser $PSItem lors de l’appel de l’opérateur -replace et la définition d’un scriptblock de substitution. Lorsque vous le faites, la valeur de $PSItem est la valeur du match en cours.
$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 script de substitution remplace la chaîne de date d’origine par le format par défaut de la culture actuelle en convertissant la valeur en datetime.
Modification de la valeur de $PSItem
Vous pouvez modifier la valeur de celle-ci $PSItem en lui attribuant une nouvelle valeur. Toutefois, cela peut modifier le comportement attendu de n’importe quel code qui s’appuie sur $PSItem.
Considérez l'exemple suivant. Normalement, l’instruction switch traite toutes les valeurs du tableau $names. Étant donné que la valeur de $PSItem l’instruction est modifiée à l’intérieur du bloc d’instructions d’action, l’instruction switch traite uniquement la première valeur.
$names = 'Alice', 'Charlie'
switch ($names) {
Alice { "$PSItem says 'Hello!'"; $PSItem = 'Bob' }
Bob { "$PSItem says 'Goodbye.'"; $PSItem = 'Charlie'; break }
Charlie { "$PSItem says 'How are you?'" }
}
Lorsque l’instruction switch évalue la première valeur, Aliceelle correspond à la première condition et exécute le bloc d’instruction d’action associé. À l’intérieur de ce bloc, la valeur de $PSItem l’instruction est modifiée Bob, ce qui affecte également l’évaluation de l’instruction switch .
Alice says 'Hello!'
Bob says 'Goodbye.'
Vous devez éviter de modifier la valeur de $PSItem.