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
Change $PSNativeCommandArgumentPassing to default to Legacy on stable release and Windows on previews #18694
Given the impact to users with the 7.3.0 release, proposal is to change the default of $PSNativeCommandArgumentPassing to Legacy on Windows (still Standard on non-Windows). We would keep the default as Windows on Windows for preview releases. This would be backported to 7.3.x
I expect to script block to inherit passing behavior ('Legacy' in my case).
However I'm not sure if script block doesn't inherit all global variables (and it's expected behavior) or only this one.
inikulshin, this is a separate issue: script blocks that run in the context of background jobs know nothing about the caller's state (the only exception are environment variables); any such state must be recreated explicitly, as needed: (Start-Job { $PSNativeCommandArgumentPassing = $using:PSNativeCommandArgumentPassing; ... }); that said, there's a proposal for thread-based parallelism to allow inheriting the caller's state on demand - see #12240 (it is in the context of ForEach-Object -Parallel, but it should be added to Start-ThreadJob too; thread-based jobs are generally preferable to child-process-based ones).
Recently I hit an issue that makes me reconsider this change. I have a native command that accepts JSON as input to parameters. With Legacy mode, all the double quotes get dropped so it's no longer valid JSON. It took a bit of work to figure out that was the problem and I don't see normal users figuring that out (it was made more difficult because it worked on my local machine which defaulted to Windows mode while CI/CD was 7.2 which only has Legacy mode).
PowerShell's argument-passing to native programs has been broken since v1, with respect to passing arguments with embedded " chars. and passing an empty string as an argument.
Generations of PowerShell users have learned to live with this bug, employing workarounds that build on the broken behavior.
In v7.3.0, a breaking change was foisted upon unsuspecting users, which broke all existing workarounds. I say "unsuspecting", because the only reference to it in the relevant release notes in no way, shape or form did justice to the ramifications of this change.
The nature of that breaking change introduced a half-fix on Windows, inexplicably selectively retaining the old, broken behavior via the ill-fated Windows mode of the newly introduced $PSNativeCommandArgumentPassing preference variable.
Based on your comment, it sounds like you're now considering retaining the half-broken behavior going forward.
This is the worst of both worlds:
It forces modification of existing code in order to continue to work, i.e. constitutes a serious break of backward compatibility.
It forces new users to grapple with the obscure behavior of Windows mode.
Michael Klement (@mklement0) will bring this topic back up to the committee. Based on your proposal, we'll just stick with Legacy on Windows forever, which IS an option.
@PowerShell/powershell-committee re-discussed this. We debated on whether we prioritize existing PowerShell users (primarily Windows-only) or for new/existing customers that may encounter issues with new commands that don't work with legacy mode and may not figure out how to escape properly.
In short, we decided that we would prioritize cross-platform compat the future than WinPS compat and the past. One action item we will be taking is adding telemetry to detect if people are changing the mode as this will inform us if we need to revisit the default.
At this time, we plan to continue evolving Windows mode rather than switching to Standard mode on Windows. This was not an easy discussion and we'll continue to monitor feedback.
Steve Lee (@SteveL-MSFT): Is there definitive documentation or guidance from the PowerShell team for how script authors should react to these changes? So far the best documentation I have found are these resources:
I use WinSCP within a Powershell script. It suddenly stopped working. After a while I could figure out that the problem appeared from a more recent version of PowerShell:
Reduced code:
& winscp...
Activity
inikulshin commentedon Dec 19, 2022
Also, when I do
I expect to script block to inherit passing behavior (
'Legacy'in my case).However I'm not sure if script block doesn't inherit all global variables (and it's expected behavior) or only this one.
mklement0 commentedon Dec 19, 2022
inikulshin, this is a separate issue: script blocks that run in the context of background jobs know nothing about the caller's state (the only exception are environment variables); any such state must be recreated explicitly, as needed: (
Start-Job { $PSNativeCommandArgumentPassing = $using:PSNativeCommandArgumentPassing; ... }); that said, there's a proposal for thread-based parallelism to allow inheriting the caller's state on demand - see #12240 (it is in the context ofForEach-Object -Parallel, but it should be added toStart-ThreadJobtoo; thread-based jobs are generally preferable to child-process-based ones).mklement0 commentedon Dec 25, 2022
With respect to the issue at hand:
SteveL-MSFT commentedon Mar 20, 2023
Recently I hit an issue that makes me reconsider this change. I have a native command that accepts JSON as input to parameters. With
Legacymode, all the double quotes get dropped so it's no longer valid JSON. It took a bit of work to figure out that was the problem and I don't see normal users figuring that out (it was made more difficult because it worked on my local machine which defaulted to Windows mode while CI/CD was 7.2 which only has Legacy mode).mklement0 commentedon Mar 22, 2023
Steve Lee (@SteveL-MSFT), let us recap:
PowerShell's argument-passing to native programs has been broken since v1, with respect to passing arguments with embedded
"chars. and passing an empty string as an argument.Generations of PowerShell users have learned to live with this bug, employing workarounds that build on the broken behavior.
In v7.3.0, a breaking change was foisted upon unsuspecting users, which broke all existing workarounds. I say "unsuspecting", because the only reference to it in the relevant release notes in no way, shape or form did justice to the ramifications of this change.
Windowsmode of the newly introduced$PSNativeCommandArgumentPassingpreference variable.Based on your comment, it sounds like you're now considering retaining the half-broken behavior going forward.
This is the worst of both worlds:
It forces modification of existing code in order to continue to work, i.e. constitutes a serious break of backward compatibility.
It forces new users to grapple with the obscure behavior of
Windowsmode.See also: #18660 (comment)
SteveL-MSFT commentedon Mar 27, 2023
Michael Klement (@mklement0) will bring this topic back up to the committee. Based on your proposal, we'll just stick with Legacy on Windows forever, which IS an option.
SteveL-MSFT commentedon Mar 29, 2023
@PowerShell/powershell-committee re-discussed this. We debated on whether we prioritize existing PowerShell users (primarily Windows-only) or for new/existing customers that may encounter issues with new commands that don't work with legacy mode and may not figure out how to escape properly.
In short, we decided that we would prioritize cross-platform compat the future than WinPS compat and the past. One action item we will be taking is adding telemetry to detect if people are changing the mode as this will inform us if we need to revisit the default.
At this time, we plan to continue evolving Windows mode rather than switching to Standard mode on Windows. This was not an easy discussion and we'll continue to monitor feedback.
mikeharder commentedon Jul 27, 2023
Steve Lee (@SteveL-MSFT): Is there definitive documentation or guidance from the PowerShell team for how script authors should react to these changes? So far the best documentation I have found are these resources:
https://stackoverflow.com/a/74440425
#13428 (comment)
Michael Klement (@mklement0): Thank you for creating these docs!