You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Start-Process doesn't pass arguments with embedded whitespace and double quotes correctly #5576
That is, script file ./t 1.ps1 should execute, and double-quoted string literal "Hi!" should print.
Actual behavior
Embedded whitespace:
Invocation fails, because the ./t 1.ps1 is passed as two arguments:
The argument './t' is not recognized as the name of a script file. Check the spelling of the name, or if a path was included, verify that the path is
correct and try again.
The only way to make this currently work is to embed (potentially escaped) double quotes: '"./t 1.ps1"' or "`"./t 1.ps1`""; e.g.:
Update: Overall, the best workaround is to pass a single string containing all arguments to -ArgumentList and use embedded quoting and escaping as necessary:
PowerShell Core v6.0.0-rc (v6.0.0-rc) on Microsoft Windows 7 Enterprise (64-bit; v6.1.7601)
Windows PowerShell v5.1.14409.1012 on Microsoft Windows 7 Enterprise (64-bit; v6.1.7601)
The code where it deconstructs -Argumentlist to the Argument string for ProcessStartInfo.Argumentshere and it simply joins the arguments by separating it with a space character. Therefore it sees ./t and 1.ps1 as two separate arguments. As pointed out by ZSkycat (@ZSkycat) one has to correctly quote the file.
Arguments are parsed and interpreted by the target application, so must align with the expectations of that application. For.NET applications as demonstrated in the Examples below, spaces are interpreted as a separator between multiple arguments. A single argument that includes spaces must be surrounded by quotation marks, but those quotation marks are not carried through to the target application. In include quotation marks in the final parsed argument, triple-escape each mark.
I don't understand how we can fix this for all platforms and for an indefinite number of applications. If there is no standard to which we should follow I would rather expect a common way of passing arguments so that they reach the goal application in exactly the user specified form.
Well, I guess we can only improve it (see my PR 5703) or maybe the better solution is to add an -Arguments parameter that is just a string to reduce complexity and leave the -ArgumentList parameter there only for legacy reasons.
Ultimately, the single string passed to ProcessStartInfo.Arguments should be constructed the same way that a direct call to an external program is handled, namely based on inverse of the MSVC++ command-line parsing rules, as discussed in TSlivede's RFC proposal.
Longer-term, once https://github.com/dotnet/corefx/issues/23592 is implemented in CoreFx, PowerShell will simply be able to pass the array through. The linked issue also points to a utility method in the CoreFx code where the kind of array-to-command-line transformation that would be needed here is used internally.
And, yes, this will break things, inevitably and in multiple scenarios, but I think if PowerShell wants to be taken seriously as a multi-platform shell, there's no way around that.
While we may consider adding a new -Arguments parameter for someone who wants to pass a single-string, pre-escaped command line (directly assignable to ProcessStartInfo.Arguments - which, notably, still needs to be split back into an array before creating a process on Unix), it is -ArgumentList that must be fixed - which breaks things.
Ilya (@iSazonov): Yes, with said proposal implemented, PowerShell could just use the new ProcessStartInfo.ArgumentList property directly and, on Windows, let CoreFX translate that into a single command line string with appropriate quoting.
I think it is not critical and not a secure hole so we can wait and it is better to direct our efforts to other areas or contribute directly in CoreFX now.
changed the title [-]Start-Process doesn't pass arguments with embedded whitespace correctly[/-][+]Start-Process doesn't pass arguments with embedded whitespace and double quotes correctly[/+]on Jul 28, 2019
The Cmdlet WG was discussing some proposed changes to Start-Process and it was apparent that there needed to be an overall discussion of how we move cmdlets forward in such a way that: We can moder...
The Cmdlet WG was discussing some proposed changes to Start-Process and it was apparent that there needed to be an overall discussion of how we move cmdlets forward in such a way that: We can moder...
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically.
Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original.
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically.
Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original.
Activity
ZSkycat commentedon Nov 29, 2017
I think it just executes
{filename} {ArgumentList.join(' ')}try this code
bergmeister commentedon Dec 15, 2017
The code where it deconstructs
-Argumentlistto the Argument string forProcessStartInfo.Argumentshere and it simply joins the arguments by separating it with a space character. Therefore it sees./tand1.ps1as two separate arguments. As pointed out by ZSkycat (@ZSkycat) one has to correctly quote the file.iSazonov commentedon Dec 16, 2017
I see the feature is documented:
I don't understand how we can fix this for all platforms and for an indefinite number of applications. If there is no standard to which we should follow I would rather expect a common way of passing arguments so that they reach the goal application in exactly the user specified form.
bergmeister commentedon Dec 16, 2017
Well, I guess we can only improve it (see my PR 5703) or maybe the better solution is to add an
-Argumentsparameter that is just a string to reduce complexity and leave the-ArgumentListparameter there only for legacy reasons.mklement0 commentedon Dec 17, 2017
Christoph Bergmeister (@bergmeister): Thanks for taking this on in your PR, but there are additional edge cases to consider, such as tokens ending in
\- see #1995 (comment)Ultimately, the single string passed to
ProcessStartInfo.Argumentsshould be constructed the same way that a direct call to an external program is handled, namely based on inverse of the MSVC++ command-line parsing rules, as discussed in TSlivede's RFC proposal.Longer-term, once https://github.com/dotnet/corefx/issues/23592 is implemented in CoreFx, PowerShell will simply be able to pass the array through. The linked issue also points to a utility method in the CoreFx code where the kind of array-to-command-line transformation that would be needed here is used internally.
And, yes, this will break things, inevitably and in multiple scenarios, but I think if PowerShell wants to be taken seriously as a multi-platform shell, there's no way around that.
While we may consider adding a new
-Argumentsparameter for someone who wants to pass a single-string, pre-escaped command line (directly assignable toProcessStartInfo.Arguments- which, notably, still needs to be split back into an array before creating a process on Unix), it is-ArgumentListthat must be fixed - which breaks things.iSazonov commentedon Dec 18, 2017
Michael Klement (@mklement0) As far as I understand the shortest way to get this is to implement https://github.com/dotnet/corefx/issues/23592, isn't it?
mklement0 commentedon Dec 18, 2017
Ilya (@iSazonov): Yes, with said proposal implemented, PowerShell could just use the new
ProcessStartInfo.ArgumentListproperty directly and, on Windows, let CoreFX translate that into a single command line string with appropriate quoting.bergmeister commentedon Dec 18, 2017
Ok. Shall I close the PR then or do we want to consider it as an intermediate improvement?
iSazonov commentedon Dec 18, 2017
I think it is not critical and not a secure hole so we can wait and it is better to direct our efforts to other areas or contribute directly in CoreFX now.
[-]Start-Process doesn't pass arguments with embedded whitespace correctly[/-][+]Start-Process doesn't pass arguments with embedded whitespace and double quotes correctly[/+]Artoria2e5 commentedon Sep 18, 2019
On a related note, it seems to truncate at the
>character too:(Windows PS 7.0.0-preview3)
read the reply. ho boy... this is bad
51 remaining items
SteveL-MSFT commentedon Jan 17, 2024
I created https://github.com/orgs/PowerShell/discussions/21089 to discuss this broader topic
mklement0 commentedon Jan 1, 2025
Note that the link in the previous comment no longer works; here's the current one:
viocha commentedon Apr 27, 2025
It's hard to imagine that this problem still hasn't been solved after all these years. This is the solution provided by ChatGPT.
microsoft-github-policy-service commentedon Oct 25, 2025
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically.
Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original.
cbryn commentedon Oct 31, 2025
This is still open.
microsoft-github-policy-service commentedon Apr 29, 2026
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically.
Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original.
noamper commentedon Apr 29, 2026
Still open
ringerc commentedon May 5, 2026
There's still no correct, portable way to start a process in Powershell, so this issue remains open.