Skip to content

Preference variable $OutputEncoding in child scopes misbehaves with encodings created with New-Object / commands rather than expressions #5763

@mklement0

Description

@mklement0

Note: This issue may well be just a symptom of #5579; if so, it still may be of interest, because it demonstrate that the linked issue has real-world consequences.

Preference variable $OutputEncoding determines the encoding used to send text to external utilities.

In the global scope, assigning the output from a New-Object call or, generally, a command (as opposed to an expression) works fine.

However, in a non-global scope, such as inside a function, it does not: assigning output from a command to $OutputEncoding is effectively ignored.

For simplicity, the example below uses Write-Output in a somewhat contrived manner, but an attempt to use New-Object to instantiate a specific encoding, e.g., New-Object System.Text.Utf8Encoding, would exhibit the same problem: it would be ignored.

The workaround is to apply .psobject.BaseObject to New-Object's result, or, in PSv5+, to use [<encoding>]::new() instead.

Steps to reproduce

On Windows:

function foo0 { 'ü' | findstr 'ü'  }
function foo1 { $OutputEncoding = [Console]::OutputEncoding; 'ü' | findstr 'ü'  }
# Same as foo1, except that Write-Output is used to produce output.
function foo2 { $OutputEncoding = Write-Output ([Console]::OutputEncoding); 'ü' | findstr 'ü'  }

foo0; '---'; foo1; '---'; foo2

Expected behavior

---
ü
---
ü

Note that foo0, perhaps surprisingly, does not output anything, because the default $OuputEncoding value - UTF-8 in PowerShell Core and ASCII in Windows PowerShell - results in output that prevents findstr.exe from matching non-ASCII characters.

Actual behavior

---
ü
---

That is, only the expression-based assignment to the (non-global) $OutputEncoding variable took effect, not the command-based one.

The command-based one seems to quietly fall back to ASCII.

Also note that this issue won't arise on Unix platforms, where PowerShell now emits UTF-8 by default and external utilities such as grep expect just that.

Environment data

PowerShell Core v6.0.0-rc.2 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.674 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIssue has been identified as a bug in the productResolution-No ActivityIssue has had no activity for 6 months or moreWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions