0

I want my powershell script to detect which WSL distribution is installed

    PS> wsl -l
    Windows Subsystem for Linux Distributions:
    Ubuntu (Default)

    PS> wsl -l | where {$_ -match "^Ubuntu"}
    # Doesn't print anything

I would expect it to print:

    Ubuntu (Default)

A few more experiments:

    PS> $x = wsl -l
    PS> $x.GetType()
    True True Object[]  System.Array
    PS> $x[0].GetType()
    True True String   System.Object
    PS> $x[1].GetType()
    True True String   System.Object
pico
  • 1,660
  • 4
  • 22
  • 52
  • 2
    Out of curiosity: You've asked 29 questions in the last month and either received or provided answers on most of them - yet you've only accepted 1. Is there a particular reason for your apparent refusal to accept answers? – Mathias R. Jessen Nov 02 '21 at 13:58
  • PowerShell decodes output from external programs into .NET strings based on the character encoding stored in `[Console]::OutputEncoding`, which on Windows defaults to the given system's legacy _OEM_ code page (e.g. `437` on US-English systems) If a given external program uses a _different_ encoding, `[Console]::OutputEncoding` must (temporarily) be set to that encoding. See [this answer](https://stackoverflow.com/a/66905220/45375) for more information and helper functions. `wsl -l` outputs UTF-16LE ("Unicode") encoded text, as explained in the linked duplicate. – mklement0 Nov 02 '21 at 14:45

1 Answers1

3

Windows PowerShell appears to decode UTF-encoded output from wsl -l as ASCII and the string therefore contains a bunch of NUL-bytes.

Change to:

wsl -l |Where {$_.Replace("`0","") -match '^Ubuntu'}

And you should get the expected result

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • Replacing the NULs is a pragmatic workaround that works as long as the output comprises only characters in the Unicode code-point range `0x1` - `0xFF` (corresponding to ISO-8859-1, which roughly coincides with Windows-1252). In the case at hand this is enough, but the proper solution requires (temporarily) setting `[Console]::OutputEncoding = [System.Text.Encoding]::Unicode` to ensure that PowerShell decodes the output from `wsl -l` properly. – mklement0 Nov 02 '21 at 14:52
  • Two quibbles: "UTF" should be "UTF-16LE", and it isn't ASCII that PowerShell uses for decoding, it is whatever encoding is stored in `[Console]::OutputEncoding`, which reflects the console's output code page default (as reported by `chcp`) and on Windows defaults to the given system's _OEM_ code page, such as [`437`](https://en.wikipedia.org/wiki/Code_page_437) on US-English systems). – mklement0 Nov 02 '21 at 14:54