mailwal

Solving The PowerShell Markdown Table Challenge

Jeff Hicks

Solving The PowerShell Markdown Table Challenge

Behind the PowerShell Pipeline · October 27, 2026

Did someone forward you this? Subscribe to this newsletter.

In this issue:

  • Overview
  • Introduction
  • Markdown Tables
  • Column Headings
    • Join-String
  • Alignment Organization
  • ConvertTo-MarkdownTable
  • Summary

Overview

My solution to the scripting challenge of converting PowerShell output to a Markdown table. My solution takes advantage of PSObject, Switch statements, ordered hashtables, and generic lists.

Introduction

Time once again to look at a solution to the previous month's PowerShell scripting challenge. The best way to learn is to do so I hope you learned a lot from this challenge. Last month I tasked you with creating a PowerShell function that would accept pipeline input from a PowerShell command and create a Markdown table. Optionally, your function could let the user specify column alignment. Presumably you could pipe the output of the new command to a file or the clipboard.

As with all of these challenges, my solution is by no means definitive, or even the only one. In fact, I hope you found a solution that differs from mine because then you can compare the two and learn even more.

Let's dig in.

Markdown Tables

I made an assumption that you know how to create a table in Markdown. If not, that is the first thing you would need to research and understand. Here's what a Markdown table looks like:

| columnA | columnB | columnC |
| --- | --- | --- |
| apple | banana | cherry |
| monkey | foo | zebra |

The column headings are set off by line markers. You can use more than 3 dashes, but there's no reason to. The Markdown style guide also suggests single spaces to offset the vertical pipes.

> I am assuming that there will be no properties or data with vertical pipes as part of the value.

Don't try to align the table columns in Markdown. You should end up with a table that looks like this:

columnAcolumnBcolumnC
applebananacherry
monkeyfoozebra

To align columns, specify alignment with the line segment:

  • right ---:
  • left :---
  • center :---:

I'll modify my test table to demonstrate:

| columnA | columnB | columnC |
| :--- | :---: | ---: |
| apple | banana | cherry |
| monkey | foo | zebra |

The alignment may be subtle depending on the length of the column items.

columnAcolumnBcolumnC
applebananacherry
monkeyfoozebra

Column Headings

For my solution, I want to format the output of this command as a Markdown table.

PS C:\> $p = Get-Process pwsh -IncludeUserName |
Select-Object ID, WorkingSet, Name,Username, StartTime,
@{Name = 'RunTime'; Expression = { New-TimeSpan -Start $_.StartTime -End (Get-Date) } }

PS C:\> $p

Id         : 13664
WorkingSet : 526389248
Name       : pwsh
UserName   : Cadenza\jeff
StartTime  : 10/26/2026 9:40:03 AM
RunTime    : 00:23:51.1134522

Id         : 14928
WorkingSet : 253558784
Name       : pwsh
UserName   : Cadenza\jeff
StartTime  : 10/26/2026 10:02:10 AM
RunTime    : 00:01:44.4863944

Id         : 19716
WorkingSet : 136015872
Name       : pwsh
UserName   : Cadenza\jeff
StartTime  : 10/26/2026 9:46:29 AM
RunTime    : 00:17:25.2146531

I don't want to force the user to know what the column headings should be. I can use PowerShell. I could use Get-Member:

PS C:\> $p | Get-Member -MemberType Properties | Select-Object -ExpandProperty Name
Id
Name
RunTime
StartTime
UserName
WorkingSet

But this lists the property names in alphabetical order, not the order I selected them.

For this kind of task I like to use the PSObject property. I only need to look at the first object.

PSObject
figure 1 - PSObject

Diving into the object shows what I have to work with.

PS C:\> $p[0].PSObject.Properties | Select-Object -First 1

MemberType      : NoteProperty
IsSettable      : True
IsGettable      : True
Value           : 13664
TypeNameOfValue : System.Int32
Name            : Id
IsInstance      : True

It should be easy now to get the property names and in the correct order. In fact, I can also get the value.

PS C:\> $p[0].PSObject.Properties | Select Name,Value

Name                       Value
----                       -----
Id                         13664
WorkingSet             526389248
Name                        pwsh
UserName            Cadenza\jeff
StartTime  10/26/2026 9:40:03 AM
RunTime         00:23:51.1134522

Join-String

But let's not get ahead of ourselves. I need to take the name properties and turn them into a Markdown table header with the vertical pipes. Here's an opportunity to use the Join-String cmdlet. I could have used the -join operator, but as you'll see that has limitations.

PS C:\> $p[0].PSObject.Properties | Join-String -Property Name -Separator ' | '
Id | WorkingSet | Name | UserName | StartTime | RunTime

Where Join-String works to my advantage is that I can also specify text to go at the beginning of the string, and text to go at the end.

PS C:\> $p[0].PSObject.Properties | Join-String -Property Name -Separator ' | ' -OutputPrefix '| ' -OutputSuffix ' |'
| Id | WorkingSet | Name | UserName | StartTime | RunTime |

Note my careful use of spaces.

(c) 2022-2026 JDH Information Technology Solutions, Inc. - all rights reserved
GitHub Bluesky LinkedIn Mastodon jdhitsolutions.github.io