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

Created on 30 Dec 2017  路  1Comment  路  Source: PowerShell/PowerShell

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)
Issue-Bug WG-Engine

Most helpful comment

Write-Output [Console]::OutputEncoding -> Write-Output ([Console]::OutputEncoding)

Culprit line. Should call PSObject.Base before as.

>All comments

Write-Output [Console]::OutputEncoding -> Write-Output ([Console]::OutputEncoding)

Culprit line. Should call PSObject.Base before as.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rkeithhill picture rkeithhill  路  3Comments

MaximoTrinidad picture MaximoTrinidad  路  3Comments

alx9r picture alx9r  路  3Comments

garegin16 picture garegin16  路  3Comments

SteveL-MSFT picture SteveL-MSFT  路  3Comments