IndexOf finds a string, but -match doesn't

Viewed 67

I need to find my wsl kernel version in a script, so I'm trying to run wsl --status to find it out, but when I try to -match it, PowerShell won't find what I'm looking for:

$wsl = wsl --status
(Invoke-Command { wsl --status | Out-String }) -match 'kernel'
False

I was able to find a workaround using IndexOf:

$wsl = wsl --status
(Invoke-Command { wsl --status | Out-String }).IndexOf('kernel')
412

That workaround definitely solves my problem, but I'd like to understand what's going on, because it makes no sense to me.

Maybe it's a character encoding issue, I don't know... So far, I tried changing [Console]::OutputEncoding and using [System.Text.Encoding]::Convert, [System.Text.Encoding]::UTF8.GetString and [System.Text.Encoding]::UTF8.GetBytes with no success.

Thanks in advance!

1 Answers

For some reason there is a null character after each character.

(wsl --status) -match "k`0" | Format-Hex

   Label: String (System.String) <216842AD>

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 00 4B 00 65 00 72 00 6E 00 65 00 6C 00 20 00 76  K e r n e l   v
0000000000000010 00 65 00 72 00 73 00 69 00 6F 00 6E 00 3A 00 20  e r s i o n :
0000000000000020 00 35 00 2E 00 31 00 30 00 2E 00 31 00 30 00 32  5 . 1 0 . 1 0 2
0000000000000030 00 2E 00 31 00                                   . 1

I haven't figured out why it is there. You can remove it like this.

(wsl --status) -replace "`0"

Not sure why you are using Invoke-Command, you can simplify to this.

(wsl --status) -replace "`0" -match 'kernel'

Now this will return the matching line since the left hand side is an array. This is equivalent to $true in a true/false check. To force a boolean you could use Out-String like you did before, cast to boolean, etc

(wsl --status | Out-String) -replace "`0" -match 'kernel'

[bool]((wsl --status) -replace "`0" -match 'kernel')

Edit

As Santiago pointed out in the comments, setting the encoding to

[Console]::OutputEncoding = [System.Text.Encoding]::Unicode

resolves this particular issue.

(wsl --status) -match "kernel"
Related