It looks like you're trying to store a complete command (executable + arguments) in a variable for later execution on demand.
Use a script block ({ ... }
) for that, which you can call on demand with &
, the call operator:
# Define the full command as a script block.
$scriptBlock = { myFuncWithArgs $temp }
# Invoke it.
# You may also pass arguments to it, but that only makes sense
# if it is designed to accept them, e.g. via $args
& $scriptBlock
Note:
&
does not work with a string containing a complete command. Its argument must either be a script block, as shown, or command name or executable path, and any arguments to pass to that script block / command / executable must be specified separately, e.g.
& { Write-Output $args } arg1 ...
or & $pathToExecutable arg1 ...
- Read on for how execute a complete command stored in a string, which can be a security risk, however.
The above uses a script-block literal.
To create a script block from a string, use [scriptblock]::Create()
:
# IMPORTANT:
# Be sure that you either fully control or implicitly trust
# the content of this string, so as to prevent execution of unwanted code.
$commandString = 'myFuncWithArgs $temp'
$scriptBlock = [scriptblock]::Create($commandString)
& $scriptBlock
You mention Read-Host
, i.e. prompting the user, as the source of your command string, in which case the caveat under "IMPORTANT:" above definitely applies.
If the risk of execution arbitrary user-supplied commands is acceptable to you, you could simply use Invoke-Expression
$commandString
- but note that Invoke-Expression
is generally discouraged precisely for its ability to execute arbitrary code stored in a string.
However, there is middle ground, which does require [scriptblock]::Create()
:
- Before invoking the script block, you can call its
.CheckRestrictedLanguage()
method to ensure that the resulting command only contains commands permitted in Restricted
language mode, with configurability as to which specific commands and variables are permitted.