0
powershell "Start-Process -FilePath 'c:\PSexec.exe' -ArgumentList "-s -i -d -u .\USERNAME -p PASSWORD \\192.168.1.1 cmd /C "O: && cd O:\SOMEDIR && perl run.pl --socket 192.168.0.1:7890 & pause"" -Wait -Passthru -WindowStyle Hidden"

Launches a remote psexec process and uses powershell wrapper to wait for the process to finish.

It all works except when I add the powershell wrapper I can't seem to figure out how to correctly escape the internal double quotes.

The string is missing the terminator: '.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

'pause'`" -Wait -Passthru -WindowStyle Hidden"' is not recognized as an internal or external command,
operable program or batch file.

What I've Tried:

  1. I don't want to encode it into base64 using -EncodedString because the command will be called with some parts substituted potentially 1000s of times. Also this is being called from a perl script and don't want to have a powershell file that has to be checked for every time the perl script runs. (i.e. I would prefer to have to powershell command contained within the perl script)

  2. From How to escape powershell double quotes from a bat file? it suggests replacing double quotes with quadruple quotes. However when I do that I get

    powershell "Start-Process -FilePath 'c:\PSexec.exe' -ArgumentList ""-s -i -d -u .\USERNAME -p PASSWORD \\192.168.1.1 cmd /C ""O: && cd O:\SOMEDIR && perl run.pl --socket 192.168.0.1:7890 & pause"""" -Wait -Passthru -WindowStyle Hidden"
    
At line:1 char:1
+ Start-Process -FilePath 'c:\PSexec.exe' -ArgumentList -EncodedCommand ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Start-Process], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand
  1. ` escaping doesn't work because you need to escape the " from the command prompt so that it can be passed to powershell.
TheAschr
  • 899
  • 2
  • 6
  • 19
  • Why do you need to invoke `powershell.exe` at all? – Bill_Stewart Jan 19 '18 at 21:03
  • As a wrapper so that the command called by psexec blocks until completion – TheAschr Jan 19 '18 at 21:04
  • Why not just run `psexec.exe` directly? – Bill_Stewart Jan 19 '18 at 21:05
  • I got it from here https://stackoverflow.com/questions/41111450/wait-for-psexec-calling-cmd-c-to-finish-in-powershell When I run psexec directly, psexec exits before run.pl completes. Im running many run.pl that have to be run one after the other. – TheAschr Jan 19 '18 at 21:07
  • I don't think that would make a difference because right now psexec doesn't wait for run.pl to finish so it would still exit immediatly regardless. – TheAschr Jan 19 '18 at 21:33
  • It does wait. It is called by the system() command in perl which is blocking. The problem is that psexec.exe doesn't wait for run.pl to finish and exits immediatly. run.pl is located on the remote computer – TheAschr Jan 19 '18 at 22:47
  • XY problem. I would suggest rewriting your question and tell the problem you are actually facing, rather than asking for help with PowerShell quoting. Your question is _not_ about PowerShell quoting. It's about calling `psexec.exe` from something and waiting for `psexec.exe` to complete before continuing. Ask about your actual problem, not the attempted solution. – Bill_Stewart Jan 19 '18 at 22:50
  • I don't think my problem is waiting for psexec because I know the solution already (others have faced this exact issue before and used this solution) https://stackoverflow.com/questions/41111450/wait-for-psexec-calling-cmd-c-to-finish-in-powershell. I have also tried this solution with other commands and they work correctly. My problem is quoting. – TheAschr Jan 19 '18 at 22:54
  • Ask about the actual problem, not your attempted solution. If you don't want to do that, then unfortunately I'm not going to be able to help. – Bill_Stewart Jan 19 '18 at 22:56
  • My actual problem is quoting. What if someone else comes across a similar quoting issue in a different situation? Are you going to tell them they should just never use nested double quotes? – TheAschr Jan 19 '18 at 22:59
  • I swear every time I ask a question like "Why won't my horse run?" with the powershell tag I get a flood of people who say "The horse is walking because it isn't running therefore you should ride a dog" – TheAschr Jan 19 '18 at 23:12
  • 1
    Perhaps you're asking a lot of [XY Problem](http://xyproblem.info/) without realizing it? – Hovercraft Full Of Eels Jan 19 '18 at 23:14
  • 1
    @TheAschr, that wouldn't happen if you weren't trying to abuse PowerShell from within some other programming environment. It's not a loop-hole or short-cut out of your environment. Either write your scripts in PowerShell or use Perl or something else. – jwdonahue Jan 19 '18 at 23:14
  • @TheAschr you're like the guy standing on the bank of a river, directly across from his desired destination. Bridge to the left and Bridge to right, but you're asking for a new bridge from your current location. In fact, you got to the wrong side of the river, by crossing the wrong way over one of those bridges a while back. – jwdonahue Jan 19 '18 at 23:17
  • X was an implemenation problem. No one was able to explain my actual question Y with powershell which was how to call a command with nested double quotes in powershell. Even "Its not possible" would have been an answer but telling me to replace X (while it is appreciated) does not help anybody with actually solving problem Y. I guess I should have just removed all the implementation parts. – TheAschr Jan 19 '18 at 23:26

1 Answers1

2

Drop the PowerShell call, it's not needed. Drop the -d option from the psexec invocation and it will wait for whatever process that it launched to complete. Read the psexec docs. From the docs we have:

-d Don't wait for process to terminate (non-interactive).

jwdonahue
  • 6,199
  • 2
  • 21
  • 43
  • The -d is being passed. It still exits prematurely. From above: 'c:\PSexec.exe' -ArgumentList "-s -i -d -u – TheAschr Jan 19 '18 at 23:09
  • Worked perfectly. Thank you. – TheAschr Jan 19 '18 at 23:16
  • You're welcome! Please take the time to edit your original question so that folks who actually need assistance with PowerShell quotes/escapes won't waste their time rolling in here. – jwdonahue Jan 19 '18 at 23:20