Skip to content

Instantly share code, notes, and snippets.

@mac2000
Forked from BenNeise/ConvertTo-Markdown.ps1
Last active July 22, 2024 22:20
Show Gist options
  • Save mac2000/86150ab43cfffc5d0eef to your computer and use it in GitHub Desktop.
Save mac2000/86150ab43cfffc5d0eef to your computer and use it in GitHub Desktop.
Converts a PowerShell object to a Markdown table.
<#
.Synopsis
Converts a PowerShell object to a Markdown table.
.EXAMPLE
$data | ConvertTo-Markdown
.EXAMPLE
ConvertTo-Markdown($data)
#>
Function ConvertTo-Markdown {
[CmdletBinding()]
[OutputType([string])]
Param (
[Parameter(
Mandatory = $true,
Position = 0,
ValueFromPipeline = $true
)]
[PSObject[]]$collection
)
Begin {
$items = @()
$columns = @{}
}
Process {
ForEach($item in $collection) {
$items += $item
$item.PSObject.Properties | %{
if(-not $columns.ContainsKey($_.Name) -or $columns[$_.Name] -lt $_.Value.ToString().Length) {
$columns[$_.Name] = $_.Value.ToString().Length
}
}
}
}
End {
ForEach($key in $($columns.Keys)) {
$columns[$key] = [Math]::Max($columns[$key], $key.Length)
}
$header = @()
ForEach($key in $columns.Keys) {
$header += ('{0,-' + $columns[$key] + '}') -f $key
}
$header -join ' | '
$separator = @()
ForEach($key in $columns.Keys) {
$separator += '-' * $columns[$key]
}
$separator -join ' | '
ForEach($item in $items) {
$values = @()
ForEach($key in $columns.Keys) {
$values += ('{0,-' + $columns[$key] + '}') -f $item.($key)
}
$values -join ' | '
}
}
}
@chenjienan
Copy link

How do you get it to order the columns in the order they are added. So for example: Get-Process | Select Name, Path, Company | ConvertTo-Markdown should have the columns in order Name, Path, Company rather than Path, Name, Company

Use the ordered dictionary and change "ContainsKey" to "Contains"

@kris6673
Copy link

kris6673 commented Jul 22, 2024

For anyone that stumbles upon this in the future, I modified the function to do the following extra things

  • Handle null values
  • Be an ordered list, so the properties will be listed in the order they are in the PS object
  • Add | before and after each line, to comply with markdownlint rules
  • Converted it to use generic lists instead of += for a lot more speed on large objects

Hope it helps someone!

Function ConvertTo-Markdown {
    [CmdletBinding()]
    [OutputType([string])]
    Param (
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true
        )]
        [PSObject[]]$collection
    )

    Begin {
        $items = [System.Collections.Generic.List[System.Object]]::new()
        $columns = [ordered]@{}
    }

    Process {
        ForEach ($item in $collection) {
            $items.Add($item)

            $item.PSObject.Properties | ForEach-Object {
                if ($null -ne $_.Value ) {
                    if (-not $columns.Contains($_.Name) -or $columns[$_.Name] -lt $_.Value.ToString().Length) {
                        $columns[$_.Name] = $_.Value.ToString().Length
                    }
                } else {
                    # Add the property to the columns, even if it's empty. If this is not done, the property will be missing from the output if it's null in all the values in the collection
                    $columns[$_.Name] = ' '
                }
            }
        }
    }

    End {
        foreach ($key in $($columns.Keys)) {
            $columns[$key] = [Math]::Max($columns[$key], $key.Length)
        }

        $header = [System.Collections.Generic.List[System.Object]]::new()
        foreach ($key in $columns.Keys) {
            $header.Add((('{0,-' + $columns[$key] + '}') -f $key))
        }
        # Make markdown header row
        Write-Output "| $($header -join ' | ') |"

        $separator = [System.Collections.Generic.List[System.Object]]::new()
        foreach ($key in $columns.Keys) {
            $separator.Add(('-' * $columns[$key]))
        }
        # Make markdown separator row
        Write-Output "| $($separator -join ' | ')  |"

        foreach ($item in $items) {
            $values = [System.Collections.Generic.List[System.Object]]::new()
            foreach ($key in $columns.Keys) {
                $values.Add((('{0,-' + $columns[$key] + '}') -f $item.($key)))
            }
            # Make all the values into a table rows
            Write-Output "| $($values -join ' | ') |"
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment