Title: Redirection vs. -*Variable common parameters, and the limited usefulness of the data that is captured · Issue #10236 · PowerShell/PowerShell · GitHub
Open Graph Title: Redirection vs. -*Variable common parameters, and the limited usefulness of the data that is captured · Issue #10236 · PowerShell/PowerShell
X Title: Redirection vs. -*Variable common parameters, and the limited usefulness of the data that is captured · Issue #10236 · PowerShell/PowerShell
Description: I'm working on #6702 right now, normalizing the stream-related common parameters so that you can capture a stream in a variable or provide an ActionPreference for any stream, when I came across what appears to be a design bug. It's easie...
Open Graph Description: I'm working on #6702 right now, normalizing the stream-related common parameters so that you can capture a stream in a variable or provide an ActionPreference for any stream, when I came across wha...
X Description: I'm working on #6702 right now, normalizing the stream-related common parameters so that you can capture a stream in a variable or provide an ActionPreference for any stream, when I came across...
Opengraph URL: https://github.com/PowerShell/PowerShell/issues/10236
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Redirection vs. -*Variable common parameters, and the limited usefulness of the data that is captured","articleBody":"I'm working on #6702 right now, normalizing the stream-related common parameters so that you can capture a stream in a variable or provide an `ActionPreference` for any stream, when I came across what appears to be a design bug.\r\n\r\nIt's easier to understand when looking at an example, so run this script first to get started:\r\n\r\n```powershell\r\n# Capture a warning using redirection\r\n$o1 = Write-Warning 'Message' 3\u003e\u00261\r\n\r\n# Capture a warning using -WarningVariable\r\n$o2 = $null\r\nWrite-Warning 'Message' -WarningVariable o2\r\n\r\n# Capture a warning using a -WarningVariable while silencing output via -WarningAction\r\n$o3 = $null\r\nWrite-Warning 'Message' -WarningVariable o3 -WarningAction Ignore\r\n\r\n# Capture a warning using a -WarningVariable while silencing output via redirection\r\n$o4 = $null\r\nWrite-Warning 'Message' -WarningVariable o4 *\u003e$null\r\n\r\n# Look at the default output, and notice the rendering differences\r\n$o1,$o2,$o3,$o4\r\n\r\n# Look at the list output, and notice how the rendering differences persist\r\n$o1,$o2,$o3,$o4 | Format-List * -Force\r\n\r\n# Look at the string output, and notice that you can't tell at all that the messages\r\n# came from warnings\r\n$o1,$o2,$o3,$o4 | Out-String\r\n```\r\n\r\nWhile each of these commands are designed to capture warning records, there are several problems that this output illustrates, as follows:\r\n\r\n1. All `WarningRecord` instances captured while redirection is used are decorated with additional information that is not captured when redirection is not used.\r\n1. `WarningRecord` instances are indistinguishable from other output when converted to string, such as when the results of a command are captured and written to a log file.\r\n1. PowerShell hosts not only apply specific colors to records from various streams, they also render additional text before the object data, even when that object data is displayed in its non-default format such as a list or a table.\r\n\r\nThe exact same behavior holds true for verbose and debug message streams, as can be seen through the PR that I am working on.\r\n\r\nThe first issue is not a huge issue, but it would probably be better if records captured via `-*Variable` common parameters were also properly decorated for proper output in a console.\r\n\r\nThe second and third issue are the more serious problem, because they limit the usefulness of capturing various types of stream data. Scripters who run a command and want to capture and review results from a log will find that much easier if output from different streams is properly identified in a black and white format with a prefix. This isn't just nice to have information: it's critical for scanning and searching purposes.\r\n\r\nDigging into the technical details, part of the problems stem from these methods in the default host implementation:\r\n\r\n```none\r\n TypeName: System.Management.Automation.Internal.Host.InternalHostUserInterface\r\nName MemberType Definition\r\n---- ---------- ----------\r\nWrite Method void Write(string value), void Write(System.ConsoleColor foregroundColor, System.ConsoleColor backgroundColor, string value)\r\nWriteDebugLine Method void WriteDebugLine(string message)\r\nWriteErrorLine Method void WriteErrorLine(string value)\r\nWriteInformation Method void WriteInformation(System.Management.Automation.InformationRecord record)\r\nWriteLine Method void WriteLine(), void WriteLine(string value), void WriteLine(System.ConsoleColor foregroundColor, System.ConsoleColor backgroundColor, string value)\r\nWriteProgress Method void WriteProgress(long sourceId, System.Management.Automation.ProgressRecord record)\r\nWriteVerboseLine Method void WriteVerboseLine(string message)\r\nWriteWarningLine Method void WriteWarningLine(string message)\r\n````\r\n\r\nNotice how progress and information streams have methods that accept actual records, but error, warning, verbose and debug streams only have methods that accept strings. Also note that some of these methods decorate output with stream-identifying text (`WriteDebugLine`, `WriteVerboseLine`, `WriteWarningLine`), while others do not (`WriteInformation`, `WriteErrorLine`).\r\n\r\nWhat I think should happen to address this issue and provide a much better foundation for script logging going forward:\r\n\r\n1. New methods should be added to an abstract `PSHostUserInterface2` class that is derived from `PSHostUserInterface` to avoid breaking changes. There should be one `Write*Line` method and one `Write*` method for each stream.\r\n1. Once the abstract methods are added, internal classes that derive from `PSHostUserInterface` should derive from the new `PSHostUserInterface2` class and implement the new methods. Other hosts can catch up when they're ready to do so.\r\n1. The F\u0026O layer should decorate the default output of Warning, Verbose, Debug, and Information records with an all caps prefix so that they can be properly identified and searched for when all you have is text data to work with (e.g. log files).\r\n1. Any internal classes that output stream data to the host should apply a prefix in the `Write*Line` methods, but not apply in the `Write*` methods (for those we rely on the default output from the F\u0026O layer for those records). That allows for prefixing in text written directly to the host while leveraging prefixing that is inherent in the default format applied to stream record instances.\r\n\r\nThoughts/comments are welcome and appreciated.\r\n\r\n# Environment data\r\n\r\n```none\r\nName Value\r\n---- -----\r\nPSVersion 6.2.1\r\nPSEdition Core\r\nGitCommitId 6.2.1\r\nOS Microsoft Windows 10.0.17763\r\nPlatform Win32NT\r\nPSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}\r\nPSRemotingProtocolVersion 2.3\r\nSerializationVersion 1.1.0.1\r\nWSManStackVersion 3.0\r\n```\r\n","author":{"url":"https://github.com/KirkMunro","@type":"Person","name":"KirkMunro"},"datePublished":"2019-07-27T00:25:39.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":10},"url":"https://github.com/10236/PowerShell/issues/10236"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:68e075fd-68d5-7c16-4865-ec0caa24a841 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | DB98:3F527:91128:EFC23:6A59F047 |
| html-safe-nonce | d160824eb64cc4ab5876f481cf28aba9db71e37918833b058d91631f5e79b1dd |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEQjk4OjNGNTI3OjkxMTI4OkVGQzIzOjZBNTlGMDQ3IiwidmlzaXRvcl9pZCI6IjYzNTc0ODIxMjYwMDM3OTM5OTEiLCJyZWdpb25fZWRnZSI6Indlc3R1czIiLCJyZWdpb25fcmVuZGVyIjoid2VzdHVzMiJ9 |
| visitor-hmac | 69dc19627f77e82ede8dc3e540db4374684240c9d51f111ca148dfeab38dfc78 |
| hovercard-subject-tag | issue:473577430 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/PowerShell/PowerShell/10236/issue_layout |
| twitter:image | https://opengraph.githubassets.com/a83d575f952154d094f8f09c1b4efce684dc2699d2cec4145a6f3f5da95780eb/PowerShell/PowerShell/issues/10236 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/a83d575f952154d094f8f09c1b4efce684dc2699d2cec4145a6f3f5da95780eb/PowerShell/PowerShell/issues/10236 |
| og:image:alt | I'm working on #6702 right now, normalizing the stream-related common parameters so that you can capture a stream in a variable or provide an ActionPreference for any stream, when I came across wha... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | KirkMunro |
| hostname | github.com |
| expected-hostname | github.com |
| None | ba3976babb66479b1c943a8edc0777d96157da48fadc0161f9ddb219deee8353 |
| turbo-cache-control | no-preview |
| go-import | github.com/PowerShell/PowerShell git https://github.com/PowerShell/PowerShell.git |
| octolytics-dimension-user_id | 11524380 |
| octolytics-dimension-user_login | PowerShell |
| octolytics-dimension-repository_id | 49609581 |
| octolytics-dimension-repository_nwo | PowerShell/PowerShell |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 49609581 |
| octolytics-dimension-repository_network_root_nwo | PowerShell/PowerShell |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 24801cf86623a319252348d1fd69122ad974b842 |
| ui-target | canary-1 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width