Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner Author

@mac2000 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

This comment has been minimized.

Copy link

@ishu3101 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

@davidwallis3101

This comment has been minimized.

Copy link

@davidwallis3101 davidwallis3101 commented Apr 19, 2017

I could do with the same!

@davidwallis3101

This comment has been minimized.

Copy link

@davidwallis3101 davidwallis3101 commented Apr 19, 2017

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

This comment has been minimized.

Copy link

@Stevie-O Stevie-O commented Aug 1, 2017

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

@TylerRudie

This comment has been minimized.

Copy link

@TylerRudie 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 ' | '
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.