Skip to content

Instantly share code, notes, and snippets.

@mac2000
Forked from BenNeise/ConvertTo-Markdown.ps1
Last active October 4, 2022 00:59
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 ' | '
}
}
}
@mac2000
Copy link
Author

mac2000 commented Apr 17, 2015

Example output:

Region        | Category   | Count
------------- | ---------- | -----
UK            | java       | 35   
UK            | javascript | 34   
CA            | javascript | 27   
CA            | java       | 27   
NY            | java       | 23   
allows remote | javascript | 22   
Deutschland   | java       | 21   
UK            | c#         | 21   
CA            | python     | 21   
UK            | php        | 20

@ishu3101
Copy link

ishu3101 commented Nov 7, 2015

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

@davidwallis
Copy link

I could do with the same!

@davidwallis
Copy link

and as if by magic I have sussed it :)

Function ConvertTo-Markdown {
    <#
    .Synopsis
       Converts a PowerShell object to a Markdown table.
    .EXAMPLE
       $data | ConvertTo-Markdown
    .EXAMPLE
       ConvertTo-Markdown($data)
    #>
    [CmdletBinding()]
    [OutputType([string])]
    Param (
        [Parameter(
            Mandatory = $true,
            Position = 0,
            ValueFromPipeline = $true
        )]
        [PSObject[]]$collection
    )

    Begin {
        $items = @()
        $columns = [ordered]@{}
    }

    Process {
        ForEach($item in $collection) {
            $items += $item

            $item.PSObject.Properties | %{
                if(-not $columns.Contains($_.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 ' | '
        }
    }
}

@Stevie-O
Copy link

Stevie-O commented Aug 1, 2017

Breaks if an object has a property with the value $null when it calls $_.Value.ToString()

@TylerRudie
Copy link

TylerRudie commented Nov 6, 2019

Here, I wrapped it in a if Statement:

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 | ForEach-Object {
                if ($null -ne $_.Value ){
                    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"

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