Register for Semperis' Hybrid Identity Protection (HIP) Conference - June 30 - July 1 Register for Semperis' Hybrid Identity Protection (HIP) Conference - June 30 - July 1

How to Create a Services List in PowerShell 7 on Linux

Just like Windows, Linux has many running services that need proper management. With the advent of PowerShell 7 and it’s cross-platform ability, the idea of using PowerShell to manage Linux systems becomes more attractive. Not all cmdlets are available on all systems though, notably, one that is missing is that of the Get-Service cmdlet, an easy way to list service status. In this article, we will create an equivalent function in PowerShell 7 that allows for retrieving Linux services in a PowerShell compatible format.

Listing Service Status

Many Linux distributions use SystemD to manage services. Ubuntu 18.04 is the distribution of choice in this article. Using SystemD, how do we retrieve a listing of services and their status? Running the below command lists all SystemD services and their status.

systemctl list-units --type=service --no-legend --all --no-pager

By specifying --no-legend and --no-pager extra formatting that does not helpl in extracting the service information is removed. An example of the default systemctl command output is shown below.

Extracting Information into PowerShell Objects

The systemctl command doesn’t exactly return an easy to parse format by default. Using RegEx to split apart the output will create PowerShell objects that are easy to use. The \\s+ RegEx command means to match one or more whitespace characters (i.e. space, tab, form feed, etc.). By splitting on that RegEx command, only the words are returned. Although the description is separated by multiple spaces, concatenating all remaining words will store the description.

When referencing an object via array notation, [#], the starting value is 0. When using count, the starting value is 1. Therefore, we need to decrement our count by 1 to match our array notation. In this case, when we split the value, our final value is an empty newline so we need to decrement the count by one more, giving us the value of 2.

$services = systemctl list-units --type=service --no-legend --all --no-pager
$services = $services -split "`n"
$services = $services | ForEach-Object {
	$service = $_ -split '\\s+'

		"Name"        = $service[0]
		"Load"        = $service[1]
		"Active"      = $service[2]
		"Status"      = $service[3]
		"Description" = ($service[4..($service.count - 2)] -Join " ")

With this basic code, we now have a $services array of parseable objects as seen below.

Creating the Get-Service Function

Next in the process is to create a simple Get-Service function to return the information we want in a reusable manner.

#Requires -Version 7.0
#Requires -PSEdition Core

Function Get-Service {

      [Parameter( Position = 0, ValueFromPipeline = $True )][String]$Name

  Begin {
    # Stop Function if Not Linux
    If ( -Not $IsLinux ) {
      Write-Error "This function should only be run on Linux systems"

  Process {
		If ( $Name ) {
      $services = & systemctl list-units $Name --type=service --no-legend --all --no-pager
    } Else {
      $services = & systemctl list-units --type=service --no-legend --all --no-pager

    $services = $services -Split "`n"

    $services = $services | ForEach-Object {
      $service = $_ -Split '\\s+'

        "Name"        = ($service[0] -Split "\\.service")[0]
        "Unit"        = $service[0]
        "State"       = $service[1]
        "Active"      = (($service[2] -EQ 'active') ? $true : $false)
        "Status"      = $service[3]
        "Description" = ($service[4..($service.count - 2)] -Join " ")


The example below shows us filtering the results to just those that are active and running. This is a very similar output to the original systemctl, but using objects that allow us to manipulation the output using standard PowerShell commands such Where-Object.

Extending Get-Service Abilities

There are a couple of features that the built-in Windows Get-Service cmdlet has, such as DependentServices and RequiredServices. These will display all of the services that depend on the named service or all of the required services that allow a named service to run. To replicate this with our function we need to add some additional code.

Dependent Services

Thankfully in systemd there is the ability to find those services. Quickly, it may become apparent that there is no easy way to parse this output.

systemctl list-dependencies cron --no-pager --no-legend

There are a few properties that we can use to add some minimal information for required services (essential to operating) and wanted services (if they are unavailable, the service continues to function). We can modify our code to utilize these values.

$services = $services | ForEach-Object {
  $service  = $_ -Split '\\s+'
  $wants    = (((& systemctl show $service[0] --no-pager --property Wants) -Split "=") -Split " ") | Where-Object { $_ -NE "" }
  $requires = (((& systemctl show $service[0] --no-pager --property Requires) -Split "=") -Split " ") | Where-Object { $_ -NE "" }

    "Name"        = ($service[0] -Split "\\.service")[0]
    "Unit"        = $service[0]
    "State"       = $service[1]
    "Active"      = (($service[2] -EQ 'active') ? $true : $false)
    "Status"      = $service[3]
    "Description" = ($service[4..($service.count - 2)] -Join " ")
    "Wants"       = (($wants.count -GT 1) ? $wants[1..($wants.count - 1)] : $null)
    "Requires"    = (($requires.count -GT 1) ? $requires[1..($requires.count - 1)] : $null)

The end result of these modifications is output that can easily be consumed and used in further scripts. Some examples of this output are shown below and with ways to filter the output as needed.

Example 1

Get-Service | Select-Object -First 2 | Format-Table -AutoSize

Example 2

Get-Service | Where-Object Status -EQ 'running' | Format-Table -AutoSize

Example 3

Get-Service | Where-Object Wants -Contains '' | Format-Table -AutoSize


As you might be able to tell, there are many ways to accomplish pulling the needed service information. In this article, we are only pulling a few of the many properties and values that can be included in a Get-Service function. As a starting point, this function gives actionable information that can be used to control the services on the system.

This is just a starting point, as many other useful functions could be created such as Stop-Service and Start-Service. The same methods shown in this article could be used to create those functions. Gluing together PowerShell and Linux command-line tools is a powerful combo that expands the functionality of both!

Related Topics:


Don't have a login but want to join the conversation? Sign up for a Petri Account

Comments (2)

2 responses to “How to Create a Services List in PowerShell 7 on Linux”

  1. brittAlan

    I am trying to use this to learn writing powershell functions/cmdlets for linux and i tried this script, putting it into .local/powershell/modules/ and got no output, so I added Write-Output $service to the end and that gave me output ofcourse but im getting a trailing duplicate last line in each object, any idea why? and was adding Write-Output the right thing to do?

  2. brittAlan

    well ive tried this step by step even putting it in each line at a time on powershell core and my output looks absolutely nothing like this .... It doesnt seem to be indexing properly and the PSCustomObject isn't coming out right...


    I figured it out. I knew something looked off about the regex used in the -split. there is an extra backslash in  "$service  = $_ -Split '\\s+'" which i am guessing was acting as an escape. removing it fixed the output.

Leave a Reply

Entrepreneur, hustler, husband, dad, Automator, content producer, published author, Microsoft MVP, DevOps pro and passionate problem-solver.

Register for the Hybrid Identity Protection (HIP) Europe Conference!

Hybrid Identity Protection (HIP) Europe 2021 - Virtual Conference

Mobile workforces, cloud applications, and digitalization are changing every aspect of the modern enterprise. And with radical transformation come new business risks. Hybrid Identity Protection (HIP) is the premier educational forum for identity-centric practitioners. At the inaugural HIP Europe, join your local IAM experts and Microsoft MVPs to learn all the latest from the Hybrid Identity world.