Last active
January 4, 2018 02:03
-
-
Save lzybkr/ef0cd34a3d312357b87ac09fd35cec5a to your computer and use it in GitHub Desktop.
Print a tree with any Key and Parent properties.
This file contains 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 | |
# 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 } | |
# | |
using namespace System.Collections.Generic | |
param( | |
[Parameter(ValueFromPipeline)] | |
[object[]]$InputObject, | |
[Parameter(Mandatory)] | |
[string] $KeyProperty, | |
[Parameter(Mandatory)] | |
[string] $ParentProperty, | |
[Parameter()] | |
[scriptblock] $Formatter | |
) | |
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 print_node([Node]$node, [string]$indent) | |
{ | |
$formatted = if ($Formatter) { | |
& $Formatter $node.Value | |
} else { | |
($node.Value | Format-Wide | Out-String).Trim() | |
} | |
"{0}{1}" -f $indent, $formatted | |
$indent += "| " | |
foreach ($n in $node.Children) | |
{ | |
print_node $n $indent | |
} | |
} | |
foreach ($n in $root) | |
{ | |
print_node $n "" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment