1

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
2
  • 3
    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? Commented Nov 2, 2021 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 for more information and helper functions. wsl -l outputs UTF-16LE ("Unicode") encoded text, as explained in the linked duplicate. Commented Nov 2, 2021 at 14:45

1 Answer 1

7

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

Sign up to request clarification or add additional context in comments.

3 Comments

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.
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 on US-English systems).
Something changed recently causing wsl -l and most other WSL commands, even attempting to list wsl based folders, to initate an install of WSL, which isn't good if you don't want to actually install it if it isn't installed. I've found that only wsl --status allows checking on WSL without initiating an install.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.