Created
December 14, 2017 13:15
-
-
Save raandree/48f17a6c8a9fa8553e1af2179288fe0e to your computer and use it in GitHub Desktop.
Show-Tree.ps1
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
using namespace System.Collections.Generic | |
function Show-Tree | |
{ | |
# .SYNOPSIS | |
# Print a tree given a key property and parent property | |
# | |
# .PARAMETER InputObject | |
# | |
# The object to print. | |
# | |
# .PARAMETER KeyProperty | |
# | |
# The property name that is unique in each value in InputObject | |
# | |
# .PARAMETER ParentProperty | |
# | |
# The property name of the value that refers to the parent | |
# | |
# .PaRAMETER Formatter | |
# | |
# An option script block to format the output. | |
# | |
# .EXAMPLE | |
# | |
# Get-CimInstance Win32_Process | | |
# print_tree.ps1 -KeyProperty ProcessId -ParentProperty ParentProcessId -Formatter { param($o) "{0} ({1})" -f $o.Name, $o.ProcessId } | |
# | |
param( | |
[Parameter(ValueFromPipeline)] | |
[object[]]$InputObject, | |
[Parameter(Mandatory)] | |
[string] $KeyProperty, | |
[Parameter(Mandatory)] | |
[string] $ParentProperty, | |
[Parameter()] | |
[scriptblock] $Formatter, | |
[Parameter()] | |
[string]$IndentString = "| " | |
) | |
begin | |
{ | |
class Node | |
{ | |
$Key | |
[List[Node]]$Children = [List[Node]]::new() | |
$Value | |
} | |
$root = [List[Node]]::new() | |
$nodeLookup = @{} | |
} | |
process | |
{ | |
foreach ($obj in $InputObject) | |
{ | |
$node = [Node]@{Key = $obj.$KeyProperty; Value = $obj} | |
if ($nodeLookup[$node.Key]) | |
{ | |
Write-Warning "Ignoring duplicate: $obj" | |
} | |
else | |
{ | |
$nodeLookup[$node.Key] = $node | |
} | |
$parentPropertyValue = $obj.$ParentProperty | |
$parent = if ($parentPropertyValue) { $nodeLookup[$parentPropertyValue] } else { $null } | |
if (!$parent) | |
{ | |
$root.Add($node) | |
} | |
else | |
{ | |
$parent.Children.Add($node) | |
} | |
} | |
} | |
end | |
{ | |
function PrintNode([Node]$node, [string]$Indent) | |
{ | |
$formatted = if ($Formatter) { | |
& $Formatter $node.Value | |
} else { | |
($node.Value | Format-Wide | Out-String).Trim() | |
} | |
"{0}{1}" -f $indent, $formatted | |
$Indent += $IndentString | |
foreach ($n in $node.Children) | |
{ | |
PrintNode $n $Indent | |
} | |
} | |
foreach ($n in $root) | |
{ | |
PrintNode $n '' | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment