If I create a PowerShell function with a parameter of type [scriptblock], which method is the best to execute the script block inside the function? And why?
I am aware of the following options:
.source operator&(call) operatorInvoke-Expression
. runs the scriptblock in the current scope. & runs the scriptblock in a child scope (same as running the scripblock via its Invoke() method). Which one you want to use depends on the outcome you want to achieve.
Demonstration:
Running via Invoke() method:
PS C:\> $s = { $a = 2; $a }
PS C:\> $a = 1
PS C:\> $s.Invoke()
2
PS C:\> $a
1
Running via call operator:
PS C:\> $s = { $a = 2; $a }
PS C:\> $a = 1
PS C:\> & $s
2
PS C:\> $a
1
Running via dot-sourcing operator:
PS C:\> $s = { $a = 2; $a }
PS C:\> $a = 1
PS C:\> . $s
2
PS C:\> $a
2
If you need the scriptblock to modify something in the current scope: use the . operator. Otherwise use call operator or Invoke() method.
. operator. If you want some variables shared between scriptblocks but not all of them you could use the global: or script: scope modifier. With that said, I wouldn't recommend actually doing this as it reeks of bad design.