I am struggling to use Psexec inside of a PS script to execute an interactive program. I have tried this:
PsExec.exe -i \\192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell notepad" 2> $null
... and it runs perfectly fine. Notepad is launched on a remote machine. Now, when I want to run .exe from Program Files (x86) I get absolutely nothing. I have tried this variations to run 1.exe located in ProgramFiles(x86):
PsExec.exe -i \\192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell "${env:ProgramFiles(x86)}\1.exe"" 2> $null
PsExec.exe -i \\192.168.100.95 -u Administrador -p Test1234 cmd /c "echo . | powershell "${env:ProgramFiles(x86)}" + "\1.exe"" 2> $null
However none of them work. Any idea what´s wrong?
Try the following:
psexec cmd /c 'echo . | powershell "& \"${env:ProgramFiles(x86)}\1.exe\"' 2>$null
Note: To better focus on the fundamentals of the solution, I've simplified the psexec
command, but the original command should work too.
The entire string passed to cmd /k
is single-quoted to prevent PS from interpolating elements up front, notably ${env:ProgramFiles(x86)}
whose expansion should be deferred until the command is executed on the target machine.
cmd /c
when invoking from cmd.exe
itself. From within PowerShell, however, this is not a requirement: PowerShell first parses the string - whether single- or double-quoted originally - interpolates, if applicable, and then passes the resulting string double-quoted to the external command.Note the & \"...\"
construct in the context of the powershell
argument, which ensures that the path with embedded spaces is correctly executed.
Curiously, PS requires "
chars. to be escaped as \"
when a parameter is passed from the outside world (as opposed to escaping as `"
inside the realm of PS).
The command passed to powershell
as a whole must be double-quoted, because cmd.exe
- in whose context powershell
is invoked due to cmd /c
- only recognizes double quotes as parameter delimiters and only double quotes protect the enclosed content (mostly) from interpretation.
Why your commands didn't work:
The primary problem was that the executable path that you wanted powershell.exe
to invoke ended up containing spaces (C:\Program Files...
), causing PowerShell not to recognize the entire path as a single argument. Such a path must be (a) quoted and (b) invoked with &
, the call operator.
(In the 2nd attempt, with + ...
(string concatenation), you would have had to use &
also, and enclose the concatenation in (...)
).
cmd /k
instead of cmd /c
can give you a better sense of how the command is ultimately executed (/k
keeps the console window open after execution of the command).A subtler point is that by using a double-quoted string overall, ${env:ProgramFiles(x86)}
was expanded on the source machine rather than on the target machine, where the definition of that environment variable may or may not be the same.