In the example below after Measure-Command
variable x
is updated, but in example with my own version of command x
remains the same.
$x = 0
Measure-Command -Expression { $x } | Out-Null
$x # outputs 1
function Measure-Command2
{
param([ScriptBlock]$Expression)
. $Expression
}
$x = 0
Measure-Command2 -Expression { $x }
$x # outputs 0
Can I use the same magic in my own functions?
CodePudding user response:
The most user-friendly solution is to define your function in a dynamic module, using New-Module
:
$null = New-Module {
function Measure-Command2 {
param([ScriptBlock]$Expression)
. $Expression
}
}
$x = 0
Measure-Command2 -Expression { $x }
$x # outputs *1* now, as desired.
Note:
Modules run in their own scope domain aka session state that is separate from the caller's. Thus, unlike with non-module functions, no child scope of the caller's scope is created on invocation.
The script block passed as an argument, due to having been created as a literal (
{ ... }
) in the caller's scope, executes there, not in the function's.
Without a module, you'd need to dot-source the invocation of Measure-Command2
itself, given that functions and scripts run in a child scope by default:
function Measure-Command2 {
param([ScriptBlock]$Expression)
. $Expression
}
$x = 0
# Note the dot-sourcing
. Measure-Command2 -Expression { $x }
$x # outputs *1* now, as desired.