Laurent Guinard
Laurent Guinard

Reputation: 11

Psexec issue with variable command in Powershell

I'm looking to automate the use of Psexec through a Powershell script. The aim is to send mass commands to a list of servers. So far, nothing extraordinary when you know the possibilities of Psexec. The problem arises when I want to put the command to be executed on the remote machines in a variable. As soon as the command has a space, it cannot be executed on the remote machine and I get the error : The specified path cannot be found. I've tried putting my variable between "" or '' or `` but nothing changes.

In the script, this command works fine :

PsExec.exe \\$SelectedServerIP -u my_user -p my_password ipconfig /all

but these one don't work :

$command = "ipconfig /all"
PsExec.exe \\$SelectedServerIP -u my_user -p my_password $command

$command = "ipconfig /all"
PsExec.exe \\$SelectedServerIP -u my_user -p my_password ""$command""

$command = ipconfig /all
PsExec.exe \\$SelectedServerIP -u my_user -p my_password ""$command""

$command = ipconfig /all
PsExec.exe \\$SelectedServerIP -u my_user -p my_password """$command"""

Thank you for your answers.

LG

Upvotes: 1

Views: 205

Answers (1)

mklement0
mklement0

Reputation: 439777

psexec expects the command line to be executed remotely to be specified as individual arguments rather than a single string.

Thus, use an array to programmatically define these arguments:

# The following is equivalent to:
#   PsExec.exe \\$SelectedServerIP -u my_user -p my_password ipconfig /all
$command = @('ipconfig', '/all')
PsExec.exe \\$SelectedServerIP -u my_user -p my_password $command

Note:

  • When an array is passed to an external program, PowerShell automatically passes its elements as individual arguments; in other words: it implicitly performs splatting; for conceptual clarity you could choose to use splatting explicitly, however, by passing @command instead of $command.

  • However, there is a quoting caveat, and it applies to all external programs, not just psexec:

    • The sad reality in Windows PowerShell and in PowerShell (Core) up to v7.2.x is that an extra, manual layer of \-escaping of embedded " characters is required in arguments passed to external programs. This is fixed in PowerShell v7.3+, with selective exceptions on Windows. See this answer for details.

    • A quick example (run from an elevated session):

      # OK in v7.3+ only, because only there are the 
      # embedded " chars. properly passed.
      # Should print: hi there
      $command = @('powershell', '-noprofile', '"hi there"')
      psexec -s $command
      
      # Solution for v7.2- and Windows PowerShell:
      # Manual `\`-escaping.
      $command = @('powershell', '-noprofile', '\"hi there\"')
      psexec -s $command
      

Upvotes: 0

Related Questions