From 807cb7c3fb45aaed0c6103b99d2b44ee2f25669f Mon Sep 17 00:00:00 2001 From: Hayden Barnes Date: Fri, 2 Jun 2023 20:58:44 -0400 Subject: [PATCH] More details in list-wsl --- README.md | 2 +- list-wsl-prompt.txt | 25 +++++++++---- list-wsl.ps1 | 85 ++++++++++++++++++++++++--------------------- 3 files changed, 66 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index cbdbf28..97b6aae 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## list-wsl -Provides a list of installed distributions, the default user, current state, and WSL version. +Provides a list of installed distributions, the official Linux distro name, the Linux distro version, the default user, systemd status, current state, and WSL version. ## wslctl diff --git a/list-wsl-prompt.txt b/list-wsl-prompt.txt index 51cdc6b..f5e4fbd 100644 --- a/list-wsl-prompt.txt +++ b/list-wsl-prompt.txt @@ -1,9 +1,22 @@ -Write a PowerShell 7 Core script that lists installed WSL distributions in a nicely formatted table, including: +Write a PowerShell 7 Core script that lists installed WSL distributions in a table. -- The distribution name, listed under the heading "Distribution Name" -- The distribution's default UID, by reading the default UiD key, listed under the heading "Default UID" +The table should show: + +- Whether the distribution is the default distribution, by reading the DafaultDistribution key at HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss. If the distribution name matches the DefaultDistribution key, then the distribution is the default distribution, display an asterisk (*) next to the distribution name. If the distribution is not the default distribution, then do not display an asterisk next to the distribution name. +- The distribution name from the Windows Registry, listed under the heading "WSL Distro Name" +- The distribution PRETTY_NAME, by spawning a process in that respective distribution and reading the distribution's /etc/os-release file for PRETTY_NAME, listed under the heading "Linux Distro Name" +- The distribution's version, by spawning a process in that respective distribution and reading the distribution's /etc/os-release file for VERSION, listed under the heading "Distro Version" +- Whether the distribution has systemd enabled or not, by spawning a process in that respective distribution and reading /etc/wsl.conf for the systemd=true key, listed under the heading "systemd" +- The distribution's default UID, by reading the default UiD key in the Windows Registry, listed under the heading "Default UID" - The distribution's default username, by spawning a process in that respective distribution, running "id -un -- " followed by the default UID key in the respective WSL distribution, and parsing the output, under the heading "Default User" -- The distribution's state, by reading the State key, and listing "Installed" for a value of 0x1, "Installing" for a value of 0x3, or "Uninstalling", for a value of 0x4, under the heading "State" -- The distribution's WSL version as 1 or 2, by reading the Version key, listed under the heading "Version" +- The distribution's state, by reading the State key in the Windows Registry, and listing "Installed" for a value of 0x1, "Installing" for a value of 0x3, or "Uninstalling", for a value of 0x4, under the heading "State" +- The distribution's WSL version as 1 or 2, by reading the Version key in the Windows Registry, listed under the heading "WSL Version" + +Additionallly: -Do not check for, display the default username, or default username header if the optional flag --skip-username is passed to the script. \ No newline at end of file +- Do not display the distro GUID in the table. +- Do not create a column for default distro, simply append an asterix next to the default distro's name. +- Do not use \\wsl$\ to access the /etc/os-release file or /etc/wsl.conf file. +- Get the /etc/os-release and /etc/wsl.conf files through \AppData\Local\Packages, get them by spawning a process with wsl.exe -d followed by the distribution name then cat each file and parse the output. +- If /etc/wsl.conf is not found, then the distribution does not have systemd enabled. +- Do not check for, display the default username, or default username header if the optional flag --skip-username is passed to the script. \ No newline at end of file diff --git a/list-wsl.ps1 b/list-wsl.ps1 index 0aea000..cad8d02 100644 --- a/list-wsl.ps1 +++ b/list-wsl.ps1 @@ -1,43 +1,50 @@ -$skipUsername = $false -if ($args -contains "--skip-username") { - $skipUsername = $true -} +$defaultGuid = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss").DefaultDistribution + +$wslDistributions = Get-ChildItem -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss" | ForEach-Object { + $distribution = @{ + Name = "" + "Linux Distro" = "" + "Distro Version" = "" + systemd = "" + "Default User" = "" + State = "" + WSL = "" + } + + $distribution["Name"] = $_.GetValue("DistributionName") -$wslRegPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss" -$wslRegKeys = Get-ChildItem $wslRegPath - -$table = @() -foreach ($key in $wslRegKeys) { - $distroName = (Get-ItemProperty -Path $key.PSPath -Name DistributionName).DistributionName - $defaultUid = (Get-ItemProperty -Path $key.PSPath -Name DefaultUid).DefaultUid - $state = (Get-ItemProperty -Path $key.PSPath -Name State).State - $version = (Get-ItemProperty -Path $key.PSPath -Name Version).Version - - if ($skipUsername) { - $table += [pscustomobject]@{ - "Distribution Name" = $distroName - "Default UID" = $defaultUid - "State" = switch ($state) { - 0x1 { "Installed" } - 0x3 { "Installing" } - 0x4 { "Uninstalling" } - } - "Version" = $version - } - } else { - $defaultUser = Invoke-Command -ScriptBlock { wsl.exe -d $args[0] -- id -un -- $args[1] } -ArgumentList $distroName, $defaultUid -ErrorAction SilentlyContinue - $table += [pscustomobject]@{ - "Distribution Name" = $distroName - "Default UID" = $defaultUid - "Default User" = $defaultUser - "State" = switch ($state) { - 0x1 { "Installed" } - 0x3 { "Installing" } - 0x4 { "Uninstalling" } - } - "Version" = $version - } + $osRelease = Invoke-Expression "wsl.exe -d $($distribution["Name"]) cat /etc/os-release" + if ($osRelease) { + $distribution["Linux Distro"] = ($osRelease | Where-Object { $_ -like "PRETTY_NAME=*" }).Split("=")[1].Replace('"', '') + $distribution["Distro Version"] = ($osRelease | Where-Object { $_ -like "VERSION=*" }).Split("=")[1].Replace('"', '') } + + $wslConf = Invoke-Expression "wsl.exe -d $($distribution["Name"]) cat /etc/wsl.conf" + if ($wslConf) { + $distribution["systemd"] = ($wslConf | Where-Object { $_ -like "systemd=true" }).Count -gt 0 + } + + $distribution["DefaultUid"] = $_.GetValue("DefaultUid") + + $username = Invoke-Command -ScriptBlock { wsl.exe -d $($distribution["Name"]) -- id -un -- $args[0] } -ArgumentList $distribution["DefaultUid"] -ErrorAction SilentlyContinue + if ($username) { + $distribution["Default User"] = $username + } + + $distribution["State"] = $_.GetValue("State") + switch ($distribution["State"]) { + 0x1 { $distribution["State"] = "Installed" } + 0x3 { $distribution["State"] = "Installing" } + 0x4 { $distribution["State"] = "Uninstalling" } + } + + $distribution["WSL"] = $_.GetValue("Version") + + if ($defaultGuid -eq $_.PSChildName) { + $distribution["Name"] += "*" + } + + New-Object -TypeName PSObject -Property $distribution } -$table | Format-Table -AutoSize +$wslDistributions | Format-Table -AutoSize "Name", "Linux Distro", "Distro Version", "Default User", systemd, State, WSL \ No newline at end of file