Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
March 6, 2026

PowerShell Tools For Linux

In this issue:

  • Get-LxUptime
  • Get-LxTotalMemory
  • Get-LxMemoryInfo
  • Get-LxTotalDiskSize
  • Get-LxDiskInfo
  • Get-LxStatus
  • Get-LxService
  • Get-LxOSInfo
  • Get-LxTools
  • Aliases
  • Summary

For me, one of the advantages of having PowerShell work cross-platform, is that I can use native PowerShell tools. My Linux skills are basic, so being able to use PowerShell to get information is a great timesaver. However, there are obvious limitations. PowerShell commands that have no basis for support are unavailable. This means no CIM cmdlets on Linux, and presumably MacOS.

> I don't have access to a Mac to test anything so I am going to assume that any statement I make regarding Linux applies to Macs.

That's not to say that CIM-like information isn't available. I can get information on a Linux host's memory, but it requires parsing to create an equivalent PowerShell object. And that's what I want. Yes, I know that Linux experts can easily parse. But I want an object that I can work with in a PowerShell pipeline.

I set out to create a set of PowerShell tools that can provide system information. I'll state up front that for a few commands I needed AI to help me use native Linux tools to parse the information. In some cases, I didn't even know where to look to find the information. I think this is a terrific use-case for AI in your scripting. Let it fill in the gaps and accelerate your work.

I thought I'd share how I worked through my toolset.

Get-LxUptime

Uptime information is stored in proc/uptime. The first value in the output is the number of seconds of uptime. AI gave me this code to parse the file.

cat /proc/uptime | cut -d. -f1

There's nothing wrong with that since the command is running in Linux. However, once I understood what information I needed, I could use a PowerShell equivalent.

$seconds = (Get-Content /proc/uptime).split(".")[0]

From here it is trivial to create the uptime.

$uptime = New-TimeSpan -Seconds $seconds

Get-LxTotalMemory

Memory information is stored in proc/meminfo. AI suggested I parse the file to get the total memory with this command:

$bytes = [int64](cat /proc/meminfo | grep MemTotal | awk '{print $2}') * 1024

The PowerShell equivalent is a little more complicated.

[int]$k = (Get-Content /proc/meminfo | Select-String MemTotal:).Line.Split().where({[int]($_ -match "\d+")})[0]
[int64]$bytes = $k * 1KB

Although I could have used a regular expression pattern.

Because the value in the file is stored as a KB value, multiplying the value by 1024 gives me the value in bytes. I always recommend providing values like this in bytes. Don't presume to know how the user might want to format the data. Let them do that. Although, I did add parameters to the function to let the user specify the format.

[int]$size = Switch ($as) {
    "kb" { $bytes/1kb}
    "mb" { $bytes/1mb}
    "gb" {$bytes/1gb}
    default {$bytes}
}
$size

Get-LxMemoryInfo

After looking at meminfo I realized there was more information I could return. The native Linux commands to parse the data are more succinct, so I decided not to spend time creating PowerShell alternatives.

$total = [int64](cat /proc/meminfo | grep MemTotal | awk '{print $2}') * 1024
$free = [int64](cat /proc/meminfo | grep MemFree | awk '{print $2}') * 1024
$avail = [int64](cat /proc/meminfo | grep MemAvailable | awk '{print $2}') * 1024
$Used = $total - $free

Once I have the data, I can easily create a custom object.

[PSCustomObject]@{
    PSTypeName      = 'lxMemoryInfo'
    TotalSize       = $total
    FreeMemory      = $free
    InUseMemory     = $used
    Available       = $avail
    PctFree         = [math]::Round(($free / $total) * 100,2)
    Computername    = [System.Environment]::MachineName
}

I provided a typename so that I could create a custom format file.

PS /home/jeff> Get-LxMemoryInfo

   Hostname: Cadenza

MemoryGB FreeMemGB InUseGB PctFree
-------- --------- ------- -------
   31      29.26    1.77      94.3

Get-LxTotalDiskSize

Likewise, I often want to get disk information. In Linux, the df command will provide the necessary information.

PS /home/jeff> df /
Filesystem      1K-blocks     Used Available Use% Mounted on
/dev/sdd       1055762868 14305796 987753600   2% /

I can parse this information to get the total disk size.

#stored size is in KB so convert it down to bytes
$bytes = [int64](df / | Select-Object -Skip 1 | ForEach-Object {
        $fields = $_ -split '\s+'
        $fields[1]
    }) * 1024

[int64]$size = switch ($As) {
    'kb' { $bytes / 1kb }
    'mb' { $bytes / 1mb }
    'gb' { $bytes / 1gb }
    default { $bytes }
}
$size

The output is a single value

PS /home/jeff> Get-LxTotalDiskSize
1081101176832
PS /home/jeff> Get-LxTotalDiskSize -as gb
1007

As an alternative, I could parse the entire output of the df command. I can't treat the multiple spaces as a delimiter, but I can replace them with on and then convert from CSV data.

PS /home/jeff> (df).replace("Mounted on","Mounted") -replace "\s+","," | ConvertFrom-Csv | Format-Table

Filesystem 1K-blocks  Used      Available Use% Mounted
---------- ---------  ----      --------- ---- -------
none       16268292   0         16268292  0%   /usr/lib/modules/6.6.87.2-microsoft-standard-WSL2
none       16268292   4         16268288  1%   /mnt/wsl
drivers    497775612  250245780 247529832 51%  /usr/lib/wsl/drivers
/dev/sdd   1055762868 14305796  987753600 2%   /
none       16268292   100       16268192  1%   /mnt/wslg
none       16268292   0         16268292  0%   /usr/lib/wsl/lib
rootfs     16254004   2664      16251340  1%   /init
none       16268292   932       16267360  1%   /run
none       16268292   0         16268292  0%   /run/lock
none       16268292   0         16268292  0%   /run/shm
none       16268292   76        16268216  1%   /mnt/wslg/versions.txt
none       16268292   76        16268216  1%   /mnt/wslg/doc
C:\        497775612  250245780 247529832 51%  /mnt/c
tmpfs      16268296   4         16268292  1%   /tmp
tmpfs      1024       0         1024      0%   /run/credentials/systemd-journald.service
tmpfs      1024       0         1024      0%   /run/credentials/systemd-resolved.service
tmpfs      1024       0         1024      0%   /run/credentials/console-getty.service
tmpfs      3253656    48        3253608   1%   /run/user/1000

The heading has a space in the last column, so I strip that off first. Keep in mind that ConvertFrom-Csv will treat all values as strings which could effect any sorting you might want to do. That said, it wouldn't take that much effort to create a function to create typed PowerShell output from the df command.

Get-LxDiskInfo

It didn't take that much more effort to create a function to provide meaningful disk usage information

df / | Select-Object -Skip 1 | ForEach-Object {
    $fields = $_ -split '\s+'
}

[int64]$total = [int32]$fields[1] * 1024
[int64]$free = [int32]$fields[3] * 1024
[PSCustomObject]@{
    PSTypeName   = 'lxDiskInfo'
    TotalSize    = $total
    Used         = ([int32]$fields[2] * 1024) -as [int64]
    Free         = $free
    PctFree      = [math]::Round(($free / $total) * 100, 2)
    Computername = [System.Environment]::MachineName
}

This too I created a custom format file.

PS /home/jeff> Get-LxDiskInfo

   Hostname: Cadenza

TotalDiskGB UsedDiskGB FreeDiskGB PctFree
----------- ---------- ---------- -------
   1007       13.64      942.00     93.56
Want to read the full issue?
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.