Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

PowerShell Scripting for Linux is Still About the Objects

Posted on October 8, 2019October 2, 2020

I've been trying to increase my Linux skills, especially as I begin to write PowerShell scripts and tools that can work cross-platform. One very important concept I want to make sure you don't overlook is that even when scripting for non-Windows platforms, you must still be thinking about objects. The assumption is that you are writing PowerShell commands to co-exist and interoperate with other PowerShell commands. So even though Linux and MacOS are text-based, you need to work with objects.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Linux Commands to Objects

As an example, consider this Linux command.

image

The command is writing strings to the pipeline, even though it looks like an object. Why not turn it into an object? I can split the output into an array of strings and then split each line into two parts using the : as a delimiter.

image

The hashtable, $h, becomes the pre-cursor to an object. By the way, I am removing the space so that the property name will have no spaces.

Let's jump right to the finished product.

A Cross-Platform Reference Function

#requires -version 6.2
#requires -psedition Core

<#
Convert this output:

Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:        18.04

into a PowerShell object

Requires LSB-Core package
# https://www.computerhope.com/unix/lsb_release.htm
#>

Function Get-LinuxLSB {
    [cmdletbinding()]
    [alias("lsb")]
    [outputtype("LinuxLSB")]
    Param(
        [Parameter(Position = 0)]
        [ValidateNotNullorEmpty()]
        [string]$Hostname = [Environment]::Machinename,
        [Parameter(Position = 1)]
        [ValidateNotNullorEmpty()]
        [string]$UserName
    )

    Write-Verbose "Starting $($myinvocation.MyCommand)"
    #define a scriptblock to run locally or remotely
    $sb = {
        if ($isLinux) {
            try {
                $app = Get-Command -Name lsb_release -erroraction stop
                $ok = $True
            }
            catch {
                Write-Warning "This command relies on lsb_release. You may need to install the lsb-core package."
                $ok = $false
            }
            if ($ok) {
                $data = (lsb_release -idr) -split "`n"
                $data | ForEach-Object -Begin { $h = [ordered]@{PSTypename = "LinuxLSB" } } -Process {
                    $s = $_.split(":")
                    Write-Verbose "Adding $s[0]"
                    $h.add($s[0].Replace(" ", ""), $s[1].trim())
                } -end {
                    $h.Add("Computername", [environment]::MachineName)
                    New-Object -TypeName PSObject -Property $h
                }
            }
        }
        else {
            Write-Warning "This command requires a Linux distribution"
        }

    } #close scriptblock

    Write-Verbose "Querying $hostname"
    if ($Hostname -eq [Environment]::Machinename) {
        Invoke-Command -ScriptBlock $sb
    }
    else {
        $params = $myinvocation.BoundParameters
        $params.Add("SSHTransport", $True)
        $params.Add("Scriptblock", $sb)
        $params.Add("HideComputername", $True)

        Invoke-Command @params | Select-Object -Property * -exclude RunspaceID
    }
    Write-Verbose "Ending $($myinvocation.MyCommand)"
}

This function leverages the remoting changes introduced in PowerShell Core that allow you to connect to a remote computer via SSH. This command uses SSH-based PowerShell remoting if the computer name (ie Hostname) is something other than the localhost. As a side note, normally I prefer to use $env:Computername to reflect the local computer name, but that isn't an option in PowerShell on Linux so I'm resorting to the .NET Framework.

Here's the command in action locally on an Ubuntu instance.

image

And here it is in action in PowerShell 7 on a Windows system:

image

Summary

I don't expect this function to be especially useful and hope you view it more as a proof of concept and showcase for some scripting techniques you might use when working cross-platform. You could do something similar to the output of the hostnamectl command.

image

But I'll leave that fun to you. In the meantime, give the function a spin. Maybe enhance it a bit. And I'd love to hear about your cross-platform scripting experiences.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

5 thoughts on “PowerShell Scripting for Linux is Still About the Objects”

  1. John Kavanagh says:
    October 8, 2019 at 11:06 am

    and yet another reason I still find the Linux to be interesting… lsb_release might not be available. For that reason I use /etc/issue

    1. Jeffery Hicks says:
      October 8, 2019 at 1:45 pm

      There are many approaches for release information. Doing something with uname is another option. As I mentioned, the function itself isn’t that important. What matters are the concepts and ideas.

      1. John Kavanagh says:
        October 8, 2019 at 3:53 pm

        Completely understand… just a thought on the “Linux” requirements as I look for a job…. I like pwsh returning objects for things like installed packages… sudo apt list –installed | select-Object -Skip 1

  2. Pingback: A PowerShell Cross-Platform Challenge – Iron Scripter
  3. Gregory Suvalian says:
    October 8, 2019 at 6:35 pm

    I wish PSCore had Convert-FromString cmdlet with “TemplateContent” parameter to do the heavy lifting for converting string to objects

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d