{"action":"created","issue":{"url":"https://api.github.com/repos/PowerShell/PowerShell/issues/3996","repository_url":"https://api.github.com/repos/PowerShell/PowerShell","labels_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/3996/labels{/name}","comments_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/3996/comments","events_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/3996/events","html_url":"https://github.com/PowerShell/PowerShell/issues/3996","id":235422867,"number":3996,"title":"Inconsistant handling of native command stderr ","user":{"login":"BurtHarris","id":2715647,"avatar_url":"https://avatars3.githubusercontent.com/u/2715647?v=3","gravatar_id":"","url":"https://api.github.com/users/BurtHarris","html_url":"https://github.com/BurtHarris","followers_url":"https://api.github.com/users/BurtHarris/followers","following_url":"https://api.github.com/users/BurtHarris/following{/other_user}","gists_url":"https://api.github.com/users/BurtHarris/gists{/gist_id}","starred_url":"https://api.github.com/users/BurtHarris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BurtHarris/subscriptions","organizations_url":"https://api.github.com/users/BurtHarris/orgs","repos_url":"https://api.github.com/users/BurtHarris/repos","events_url":"https://api.github.com/users/BurtHarris/events{/privacy}","received_events_url":"https://api.github.com/users/BurtHarris/received_events","type":"User","site_admin":false},"labels":[{"id":401720556,"url":"https://api.github.com/repos/PowerShell/PowerShell/labels/Area-Console","name":"Area-Console","color":"5319e7","default":false},{"id":428956727,"url":"https://api.github.com/repos/PowerShell/PowerShell/labels/Area-Remoting","name":"Area-Remoting","color":"5319e7","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2017-06-13T03:07:21Z","updated_at":"2017-06-14T02:55:13Z","closed_at":null,"body":"I discovered recently that the handling of `stderr` from native commands isn't being dealt with consistently between Windows PowerShell and Windows PowerShell ISE.     \r\n\r\nSteps to reproduce\r\n------------------\r\n\r\n```powershell\r\n$errorActionPreference=\"stop\"; try { cmd /c nosuchexe } catch { 'dang!' }\r\n```\r\n\r\nActual ISE behavior (expected)\r\n-----------------\r\n\r\n```none\r\ndang!\r\n```\r\nNative commands writing to `stderr` while `$errorActionPreference=\"stop\"` generate a catchable `NativeCommandError` which encapsulates the original error message in a `ErrorRecord`.   It is easy to capture, analyze, and reword error messages in context.\r\n\r\nActual CLI behavior\r\n---------------\r\n\r\n```none\r\n'nosuchexe' is not recognized as an internal or external command,\r\noperable program or batch file.\r\n```\r\n\r\nNo `NativeCommandError` is generated, no matter how `$errorActionPreference` is set.  The `stderr` from the native command is piped straight through to the default process `stderr`.   \r\n\r\nThis behavior is a serious loss of functionality, leading some to believe that PowerShell can't distinguish between `stderr` and `stdout`.   Lots of community confusion generated because of the discrepency.   See https://stackoverflow.com/questions/44488202/powershell-streaming-output/44491420#44491420, among others.\r\n\r\nAnalysis\r\n---------\r\nThe difference isn't just the ISE, I think it is related to PowerShell remote runspaces!   The full info on the caught error record (in the ISE) demonstrates the underlying exception is a RemoteException like this:\r\n\r\n```powershell\r\nPS C:\\Users\\Burt_> $errorActionPreference=\"stop\"; try { cmd /c nosuchexe } catch { Format-List * -force -InputObject $_ }\r\n\r\n\r\n\r\nPSMessageDetails      : \r\nException             : System.Management.Automation.RemoteException: 'nosuchexe' is not recognized as an internal or external \r\n                        command,\r\nTargetObject          : 'nosuchexe' is not recognized as an internal or external command,\r\nCategoryInfo          : NotSpecified: ('nosuchexe' is ...ternal command,:String) [], RemoteException\r\nFullyQualifiedErrorId : NativeCommandError\r\nErrorDetails          : \r\nInvocationInfo        : System.Management.Automation.InvocationInfo\r\nScriptStackTrace      : at <ScriptBlock>, <No file>: line 1\r\nPipelineIterationInfo : {}\r\n```\r\n\r\n\r\n\r\nEnvironment data\r\n----------------\r\nBoth powershell.exe and powershell_ise.exe report the same version information:\r\n\r\n```powershell\r\nName                           Value\r\n----                           -----\r\nPSVersion                      5.1.15063.296\r\nPSEdition                      Desktop\r\nPSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}\r\nBuildVersion                   10.0.15063.296\r\nCLRVersion                     4.0.30319.42000\r\nWSManStackVersion              3.0\r\nPSRemotingProtocolVersion      2.3\r\nSerializationVersion           1.1.0.1\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/PowerShell/PowerShell/issues/comments/308305373","html_url":"https://github.com/PowerShell/PowerShell/issues/3996#issuecomment-308305373","issue_url":"https://api.github.com/repos/PowerShell/PowerShell/issues/3996","id":308305373,"user":{"login":"mklement0","id":588825,"avatar_url":"https://avatars1.githubusercontent.com/u/588825?v=3","gravatar_id":"","url":"https://api.github.com/users/mklement0","html_url":"https://github.com/mklement0","followers_url":"https://api.github.com/users/mklement0/followers","following_url":"https://api.github.com/users/mklement0/following{/other_user}","gists_url":"https://api.github.com/users/mklement0/gists{/gist_id}","starred_url":"https://api.github.com/users/mklement0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mklement0/subscriptions","organizations_url":"https://api.github.com/users/mklement0/orgs","repos_url":"https://api.github.com/users/mklement0/repos","events_url":"https://api.github.com/users/mklement0/events{/privacy}","received_events_url":"https://api.github.com/users/mklement0/received_events","type":"User","site_admin":false},"created_at":"2017-06-14T02:55:13Z","updated_at":"2017-06-14T02:55:13Z","body":"@lzybkr: Thanks for finding the real cause - I've cleaned up my previous post accordingly.\r\n\r\n> it is common for tools to use stderr and not report errors, and automation is broken if we assume otherwise\r\n\r\nYou're right: external utilities have no choice other than to use stderr for anything that's not data, and the only true indicator of an external utility's success is its _exit code_.\r\nMy initial thought was that it would be harmless to treat stderr lines as non-terminating PS errors, as they'd just collect in `$Error` without stopping the script (and how they should be _formatted for display_  is a secondary issue). \r\n\r\n**But I can definitely see how you do NOT want your script to abort with `$ErrorActionPreference = 'Stop'` in effect just because an external utility happens to write to stderr**.\r\n\r\n**In an ironic twist, that is precisely what happens when you explicitly want to _suppress_ stderr output currently (or redirect it to a file) - see #4002:**\r\n\r\n```powershell\r\n & { $ErrorActionPreference = 'stop'; cmd /c nosuch 2>$null; $? }\r\n```\r\n\r\nAs @BurtHarris has discovered, `2>$null` doesn't actually _just_ mean \"discard that stream's output\" (and `2>file` doesn't _just_ mean \"save that stream's output to a file\"), but it currently _also_ means \"quietly record the output lines as error records in `$Error`\", which is:\r\n\r\n* (a) completely unexpected\r\n* (b) badly interacts with `$ErrorActionPreference = 'stop'`, as demonstrated (writing to `$Error` apparently is tantamount to a non-terminating error)\r\n\r\nHowever, as @BurtHarris  mentions, there _is_ value in making stderr output available to subsequent commands, at least on demand, but `2>$null` is clearly _not_ the way to do it.\r\n\r\nFor instance, being able to inspect stderr input is important for ill-behaved external utilities that, instead of signaling success via their exit code, write to stderr _only_.\r\n\r\nSo, as @BurtHarris  suggests, having something analogous to `-ErrorVariable` would be helpful.\r\nWhile surfacing that via `>` is a natural candidate, it makes it difficult to separate the immediate output behavior from the record-in-a-variable behavior, unless some presumably awkward compound syntax is devised.\r\n\r\nAn `-ErrorAction` analog might also be nice - which raises similar syntax questions - but, based on the discussion above, its semantics should be tied to the _exit code_, not to _stderr output_.\r\n\r\n    "}}
{"actor":{"display_login":"mklement0"}}