Screenshot
Code
$processName = "explorer.exe" Set-StrictMode -Version 3 Add-Type -Assembly System.Windows.Forms $inputObject = dir variable:\* -Exclude InputObject,Args | Where-Object { $_.Value -and ($_.Value.GetType() -eq $processName.GetType()) -and ($_.Value.GetHashCode() -eq $processName.GetHashCode()) } $inputObject = $inputObject| % Name | Select -First 1 if(-not $inputObject) { $inputObject = "InputObject" } function PopulateNode($node, $object) { if(-not $object) { return } if([System.Management.Automation.LanguagePrimitives]::GetEnumerator($object)) { $count = 0 $isOnlyEnumerable = $object.GetHashCode() -eq $object[0].GetHashCode() foreach($childObjectValue in $object) { $newChildNode = New-Object Windows.Forms.TreeNode $newChildNode.Text = "$($node.Name)[$count] = $childObjectValue : " + $childObjectValue.GetType() if($isOnlyEnumerable) { $newChildNode.Name = "@" } $newChildNode.Name += "[$count]" $null = $node.Nodes.Add($newChildNode) AddPlaceholderIfRequired $newChildNode $childObjectValue $count++ } } else { foreach($child in $object.PSObject.Properties) { $childObject = $child.Value $childObjectType = $null if($childObject) { $childObjectType = $childObject.GetType() } $childNode = New-Object Windows.Forms.TreeNode $childNode.Text = $child.Name + " = $childObject : $childObjectType" $childNode.Name = $child.Name $null = $node.Nodes.Add($childNode) AddPlaceholderIfRequired $childNode $childObject } } } function AddPlaceholderIfRequired($node, $object) { if(-not $object) { return } if([System.Management.Automation.LanguagePrimitives]::GetEnumerator($object) -or @($object.PSObject.Properties)) { $null = $node.Nodes.Add( (New-Object Windows.Forms.TreeNode "...") ) } } function OnAfterSelect { param($Sender, $processTreeEventArgs) $nodeSelected = $Sender.SelectedNode $nodePath = GetPathForNode $nodeSelected $resultObject = Invoke-Expression $nodePath $output.Text = $nodePath if($resultObject) { $members = Get-Member -InputObject $resultObject | Out-String $output.Text += "`n" + $members } } function OnBeforeExpand { param($Sender, $processTreeCancelEventArgs) $selectedNode = $processTreeCancelEventArgs.Node if($selectedNode.FirstNode -and ($selectedNode.FirstNode.Text -eq "...")) { $selectedNode.Nodes.Clear() } else { return } $nodePath = GetPathForNode $selectedNode Invoke-Expression "`$resultObject = $nodePath" PopulateNode $selectedNode $resultObject } function OnKeyPress { param($Sender, $KeyPressEventArgs) if($KeyPressEventArgs.KeyChar -eq 3) { $KeyPressEventArgs.Handled = $true $node = $Sender.SelectedNode $nodePath = GetPathForNode $node [System.Windows.Forms.Clipboard]::SetText($nodePath) $winform.Close() } } function GetPathForNode { param($Node) $nodeElements = @() while($Node) { $nodeElements = ,$Node + $nodeElements $Node = $Node.Parent } $nodePath = "" foreach($Node in $nodeElements) { $nodeName = $Node.Name if($nodeName.StartsWith('@')) { $nodeName = $nodeName.Substring(1) $nodePath = "@(" + $nodePath + ")" } elseif($nodeName.StartsWith('[')) { } elseif($nodePath) { $nodePath += "." } $nodePath += $nodeName } $nodePath } $processTree = New-Object Windows.Forms.TreeView $processTree.Dock = "Top" $processTree.Height = 200 $processTree.PathSeparator = "." $processTree.Add_AfterSelect( { OnAfterSelect @args } ) $processTree.Add_BeforeExpand( { OnBeforeExpand @args } ) $processTree.Add_KeyPress( { OnKeyPress @args } ) $output = New-Object System.Windows.Forms.TextBox $output.Multiline = $true $output.ScrollBars = "Vertical" $output.Font = "Calibri" $output.Dock = "Top" $output.Height = 600 $root = New-Object Windows.Forms.TreeNode $root.Text = "$processName : " + $processName.GetType() $root.Name = '$' + $inputObject $root.Expand() $null = $processTree.Nodes.Add($root) PopulateNode $root $processName $winform = New-Object Windows.Forms.Form $winform.Text = "Browsing " + $root.Text $winform.Width = 1100 $winform.Height = 800 $winform.Controls.Add($output) $winform.Controls.Add($processTree) $null = $winform.ShowDialog() $winform.Dispose()