I need to run this command, which is read from another script.
$command = "$arr = @($input)
$arr.count
Write-Host $arr[0]"
"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {$command}
So I am getting something through the pipe and then I use it in my string command. The code does not work because $command
is not expanded to the string inside the call and therefore unknown in the launched powershell command.
These work as expected, but the commands are not taken from a string:
"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {Invoke-Expression "Write-Host $input"}
# No: System.Management.Automation.Runspaces.PipelineReader`1 <GetReadEnumerator>d__20[System.Object]
# "Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {Write-Host $input}
"Classical Music for When You are on a Deadline." | & cmd /C powershell -Command {$arr = @($input)
$arr.count
Write-Host $arr[0]}
CodePudding user response:
{ $command }
does not turn the value of string$command
into a script block - it simply creates a script block that references a variable named$command
.- To create a script block from a string, use
[scriptblock]::Create()
- To create a script block from a string, use
Also, do not call
powershell.exe
viacmd /c
- it is generally unnecessary.
Therefore:
$command = '$arr = @($input)
$arr.count
Write-Host $arr[0]'
"Classical Music for When You are on a Deadline." |
powershell ([scriptblock]::Create($command)) # -Command is implied.
The above is the dynamic, variable-based equivalent of the last solution attempt in your question.
Taking a step back: Since you're already running in PowerShell, there is no need to create another instance, as a child process, which is expensive.
$command = '$arr = @($input)
$arr.count
Write-Host $arr[0]'
# Invoke the dynamically created script block directly.
"Classical Music for When You are on a Deadline." |
& ([scriptblock]::Create($command))
Note:
&
, the call operator is used to invoke the script block, which runs it in a child scope.- If you want the script block to run directly in the caller's scope, use
.
, the dot-sourcing operator instead.
- If you want the script block to run directly in the caller's scope, use
Invoke-Expression
(iex
) - which should generally be avoided - is not an option here anyway, because it doesn't support using the pipeline to pass data to the code being evaluated.
CodePudding user response:
you can use the Invoke-Expression cmdlet to run a variable string as a command in PowerShell. For example:
Invoke-Expression $commandString