title: PowerShell stripping double quotes from command line arguments
body: <p>Recently I have been having some trouble using GnuWin32 from PowerShell whenever double quotes are involved.</p>
  <p>Upon further investigation, it appears PowerShell is stripping double quotes from command line arguments, even when properly escaped.</p>
  <pre class="lang-none prettyprint-override"><code>PS C:\Documents and Settings\Nick&gt; echo '&quot;hello&quot;'
  &quot;hello&quot;
  PS C:\Documents and Settings\Nick&gt; echo.exe '&quot;hello&quot;'
  hello
  PS C:\Documents and Settings\Nick&gt; echo.exe '\&quot;hello\&quot;'
  &quot;hello&quot;
  </code></pre>
  <p>Notice that the double quotes are there when passed to PowerShell's <strong>echo</strong> cmdlet, but when passed as an argument to <strong>echo.exe</strong>, the double quotes are stripped unless escaped with a backslash (even though PowerShell's escape character is a backtick, not a backslash).</p>
  <p>This seems like a bug to me. If I am passing the correct escaped strings to PowerShell, then PowerShell should take care of whatever escaping may be necessary for however it invokes the command.</p>
  <p>What is going on here?</p>
  <p>For now, the fix is to escape command line arguments in accordance with these rules (which seem to be used (indirectly) by the <code>CreateProcess</code> API call which PowerShell uses to invoke .exe files):</p>
  <ul>
  <li>To pass a double quote, escape with a backslash: <code>\&quot;</code> -&gt; <code>&quot;</code></li>
  <li>To pass a one or more backslashes followed by a double quote, escape each backslash with another backslash and escape the quote: <code>\\\\\&quot;</code> -&gt; <code>\\&quot;</code></li>
  <li>If not followed by a double quote, no escaping is necessary for backslashes: <code>\\</code> -&gt; <code>\\</code></li>
  </ul>
  <p>Note that further escaping of double quotes may be necessary to escape the double quotes in the Windows API escaped string to PowerShell.</p>
  <p>Here are some examples, with <strong>echo.exe</strong> from GnuWin32:</p>
  <pre class="lang-none prettyprint-override"><code>PS C:\Documents and Settings\Nick&gt; echo.exe &quot;\`&quot;&quot;
  &quot;
  PS C:\Documents and Settings\Nick&gt; echo.exe &quot;\\\\\`&quot;&quot;
  \\&quot;
  PS C:\Documents and Settings\Nick&gt; echo.exe &quot;\\&quot;
  \\
  </code></pre>
  <p>I imagine that this can quickly become hell if you need to pass a complicated command line parameter. Of course, none of this documented in the <code>CreateProcess()</code> or PowerShell documentation.</p>
  <p>Also note that this is not necessary to pass arguments with double quotes to .NET functions or PowerShell cmdlets. For that, you need only escape your double quotes to PowerShell.</p>
  <p><strong>Edit:</strong> As Martin pointed out in his excellent answer, this is documented in the <code>CommandLineToArgv()</code> function (which the CRT uses to parse the command line arguments) documentation.</p>