Home > Software engineering >  Pass variable string command to powershell -Command
Pass variable string command to powershell -Command

Time:12-06

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.

  • Also, do not call powershell.exe via cmd /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.
  • 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

  • Related