-
-
Save mac2000/86150ab43cfffc5d0eef to your computer and use it in GitHub Desktop.
Converts a PowerShell object to a Markdown table.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.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 ' | ' | |
} | |
} | |
} |
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 ' | '
}
}
}
Breaks if an object has a property with the value $null
when it calls $_.Value.ToString()
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 ' | '
}
}
}
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"
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
I could do with the same!