Why cannot I match for strings from wsl.exe output?

Viewed 248

I am attempting to use PowerShell to grab useful output from wsl.exe. For the life of me, I cannot seem to match for strings in the output (see below). I get the same behavior in both PowerShell 5 and 7. Does anyone have a reliable means to capture the output of wsl.exe?

Thanks

PS C:\Users\gsamuel> $foo = (wsl -l -v)
PS C:\Users\gsamuel> $foo
  NAME            STATE           VERSION

* Ubuntu-20.04    Running         2


PS C:\Users\gsamuel> $foo | Select-String -Pattern 'Ubuntu'
PS C:\Users\gsamuel> $foo -match 'Ubuntu'
PS C:\Users\gsamuel>
PS C:\Users\gsamuel>
PS C:\Users\gsamuel> [string]$foo | Select-String -Pattern 'Ubuntu'
PS C:\Users\gsamuel> [string]$foo -match 'Ubuntu'
False
2 Answers

This appears to be an encoding issue of some sort: there is a null between each letter of the output, probably because a UTF-16 output is being interpreted as UTF-8.

You can see this by replacing all null characters with @:

$foo = (wsl -l -v)
$foo -Replace "`0", '@'

Which gives this:

 @ @N@A@M@E@ @ @ @ @ @ @ @ @ @ @ @ @S@T@A@T@E@ @ @ @ @ @ @ @ @ @ @ @V@E@R@S@I@O@N@
@
@*@ @U@b@u@n@t@u@-@2@0@.@0@4@ @ @ @ @R@u@n@n@i@n@g@ @ @ @ @ @ @ @ @ @2@
@
@

So the output doesn't actually contain the string "Ubuntu"!

A simple workaround would be to replace those with empty strings:

$foo -Replace "`0", '' | Select-String 'Ubuntu'

Which outputs the expected match:


* Ubuntu-18.04    Stopped         2


This is now fixed in the latest WSL Preview release 0.64.0, but you do have to "opt-in" to the fix so that older workarounds don't inadvertently break.

Adding the environment variable WSL_UTF8 with a value of 1 (and only that value) will now prevent wsl.exe from generating this "mangled" UTF-16 that was causing the issue.

For your example:

> $env:WSL_UTF8=1
> $foo = (wsl -l -v)

> $foo | Select-String -NoEmphasis -Pattern 'Ubuntu'


  Ubuntu20.04_WSL1       Stopped         1
  Ubuntu20.04_WSL2       Stopped         2
  Ubuntu_21.10_WSL2      Stopped         2
  Ubuntu-22.04           Stopped         2
  Ubuntu                 Running         2

> $foo -match 'Ubuntu'

# Same

I'll also point to another solution in this answer for those who can't yet upgrade to Windows 11 and/or the WSL Preview. That solution changes the console's OutputEncoding in PowerShell to force wsl.exe's output to be usable.

Related