2

Today I'm just looking to check if a specific subsystem is installed on my windows workstation. So I'm using Windows Subsystem for Linux (WSL) and install Ubuntu available from Microsoft Store. Now i'm trying to have a way to check if it's installed in a programmatic manner.

I've this output:

PS C:\> wsl -l -v
NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2

And I need to know if "Ubuntu-20.04" is installed. I've tried many things, but nothing revelant like:

$state = wsl -l -v
if($state -like '*Ubuntu*') {
      Write-Host 'Installed'
} else {
      Write-Host 'Nope'
}

But not working. Do you have a clue for me ? Thanks everyone !

marsze
  • 15,079
  • 5
  • 45
  • 61

5 Answers5

4

This seems to be an encoding issue. There are (invisible) null characters in your string. I'm still trying to find out what's the best way to deal with it.

In the meanwhile ... here's a quick fix:

$state = (wsl -l -v) -replace "\x00",""

UPDATE

Another workaround, but this will change the encoding for the entire session:

[System.Console]::OutputEncoding = [System.Text.Encoding]::Unicode
marsze
  • 15,079
  • 5
  • 45
  • 61
2

Your example code will now work properly with an opt-in fix in the latest WSL Preview release (0.64.0), but note that (at least while in Preview) it is only available to Windows 11 users.

To opt-in (so that you don't accidentally break older code when you've implemented workarounds like the previous answers), simply set the WSL_UTF8 environment variable with a value of 1 (only this value will work).

For instance, from PowerShell:

$env:WSL_UTF8=1

Or you can set it globally in Windows if desired.

If running wsl.exe from inside WSL itself, see this answer for sample code using WSLENV.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
1

If you are running wsl from WSL itself or Windows Git Bash, you can use this to convert:

wsl -l -v | iconv -f UTF-16LE -t UTF-8
sourcedelica
  • 23,940
  • 7
  • 66
  • 74
0

Illustrating how wsl outputs utf16le. So even bytes are null "`0". If you have emacs, you can run esc-x hexl-mode on a file with the output to get a similar display. As far as I know, there's no iconv equivalent in powershell.

wsl --help | select -first 1 | format-hex


   Label: String (System.String) <09F5DDB6>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 43 00 6F 00 70 00 79 00 72 00 69 00 67 00 68 00 C o p y r i g h
0000000000000010 74 00 20 00 28 00 63 00 29 00 20 00 4D 00 69 00 t   ( c )   M i
0000000000000020 63 00 72 00 6F 00 73 00 6F 00 66 00 74 00 20 00 c r o s o f t
0000000000000030 43 00 6F 00 72 00 70 00 6F 00 72 00 61 00 74 00 C o r p o r a t
0000000000000040 69 00 6F 00 6E 00 2E 00 20 00 41 00 6C 00 6C 00 i o n .   A l l
0000000000000050 20 00 72 00 69 00 67 00 68 00 74 00 73 00 20 00   r i g h t s
0000000000000060 72 00 65 00 73 00 65 00 72 00 76 00 65 00 64 00 r e s e r v e d
0000000000000070 2E 00    

With single character wildcards for utf16 encoding:

(wsl -l -v) -like '*u?b?u?n?t?u*'

  NAME    STATE     VERSION
* Ubuntu  Stopped   2

Looks like linux commands themselves are in ascii or utf8:

(wsl cat /etc/lsb-release) -like '*ubuntu*'

DISTRIB_ID=Ubuntu
...
js2010
  • 23,033
  • 6
  • 64
  • 66
0

I find that the combination of both commands work find : $env:WSL_UTF8=1 [System.Console]::OutputEncoding = [System.Text.Encoding]::utf8