Does Powershell have an operator like Python's :=
, which can assign a variable within an expression? (e.g., if (match := pattern.search(data)) is not None
)
Suppose I want to store a value in Powershell as a variable, but also pass it down the pipeline. Is there a more elegant way than ...| ForEach-Object { $foo = $_.split(': ')[1]; $foo } |
...?
I'm trying to pipe an expression, but also store it as a variable for 2 steps down the pipe
In this case you might consider using the common parameter -PipelineVariable
(-pv
). It has the advantage that the variable doesn't pollute the parent scope of the pipeline as explicitly assigning to a variable would do. It will just live as long as the pipeline runs.
...| ForEach-Object -PipelineVariable foo { $_.split(': ')[1] }
A reproducible example will make the difference clearer:
1..3 | ForEach-Object { ($a = $_) } | ForEach-Object { $_ * 2 } | ForEach-Object { "$a * 2 = $_" }
$a # Print the value of $a
Output:
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
3
Note that it ouputs the value of $a
in the last line, because the variable has "leaked" from the pipeline into the parent scope. This may be an undesired side effect when you actually wanted to use $a
only within the pipeline scope.
Now see what happens when we change to -PipelineVariable
:
1..3 | ForEach-Object -PipelineVariable a { $_ } | ForEach-Object { $_ * 2 } | ForEach-Object { "$a * 2 = $_" }
$a # Print the value of $a
Output:
1 * 2 = 2
2 * 2 = 4
3 * 2 = 6
Now $a
after the pipeline doesn't output anything, because the variable is defined only within the pipeline scope.