Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
Log in
Subscribe
July 31, 2026

July 2026 PowerShell Potluck

In this issue:

  • Show-ObjectTree
    • Limitations
    • MinUi
  • PSScriptTools Update
    • Write-PSHorizontalRule
    • Show-Enum
    • New-ANSIHyperLink
    • Get-ProcessTree
    • Show-ProcessTree
    • Show-HiddenMember
    • Format-BorderBox
  • PSConfEU Interview
  • MVP Year 20
  • Scripting Challenge
  • Summary

I hope those of you in the northern hemisphere are enjoying your summer. I've been able to enjoy a little downtime with the family. Of course, PowerShell marches on so let's wrap up the month with our now traditional PowerShell Potluck. Don't worry. I brought all the sides dishes.

Show-ObjectTree

You know I love creating and using terminal user interfaces (TUIs). I recently rediscovered command on my desktop that I had completely forgotten about. I think you'll find it very useful. It is called Show-ObjectTree. The command has an alias of shot. It is part of the Microsoft.PowerShell.ConsoleGuiTools module. The module requires PowerShell 7 and runs cross-platform.

The command is designed to display an object in a tree view. You might think of this as an interactive version of Select-Object and Get-Member.

Get-Service bits | Show-ObjectTree
Show Bits Service Object
figure 1 - Show Bits Service Object

The object is collapsed by default. Click lines to expand.

Limitations

There is one requirement that isn't documented in the limited help. A command like this will run without error:

[PSCustomObject]@{
    PSTypeName = 'psFoo'
    Name       = 'Foo'
    Size       = 765432
    Version    = $PSVersionTable
    PID        = Get-Process -Id $pid | select ID, Name, WS, Path
} | Show-ObjectTree

But you won't get any output in the TUI. The object type must be defined in your PowerShell session. One option is to define a PowerShell class.

class psJeff {
    [string]$Name = $env:USERNAME
    [int64]$Size = (Get-Random -min 1KB -max 1mb)
    [hashtable]$Version = $PSVersionTable
    [object]$PID = (Get-Process -Id $pid | select-object ID, Name, WS, Path)
}

Now I can create an instance of the object and show it.

PS C:\> $obj = [psJeff]::new()
PS C:\> shot -input $obj
Showing a custom object
figure 2 - Showing a custom object

MinUi

If you want to keep things simple, you can use a minimal user interface.

Get-Process -id $pif | Show-ObjectTree -MinUI
Show-ObjectTree with minimal ui
figure 3 - Show-ObjectTree with minimal ui

I'll let you play with the filtering feature. This is a handy alternative for discovering an object's properties and related values.

PSScriptTools Update

I was very busy this month updating the PSScriptTools module with 2 major releases. In addition to cleaning up code, adding aliases, and fixing problems, I also added several tools, a few of which originated from this newsletter.

Write-PSHorizontalRule

This command is used to write a horizontal rule line in the console. The rule line is colored using ANSI. You can specify any ANSI or PSStyle foreground sequence as the style. The default is a thin line, but you can create a thick like using the LineWeight parameter. The default line length is the console width.

Optionally, you can insert a title or caption. By default, the caption will be set to the left, but you can adjust the alignment and style.

PSHorizontalRule
figure 4 - PSHorizontalRule

Show-Enum

This command is intended to make it easier to discover an enum's names and values. We explored enums recently.

 PS C:\> Show-Enum DayOfWeek

       Typename: System.DayOfWeek

    Name      Value
    ----      -----
    Sunday        0
    Monday        1
    Tuesday       2
    Wednesday     3
    Thursday      4
    Friday        5
    Saturday      6

New-ANSIHyperLink

In PowerShell 7, you can use $PSStyle.FormatHyperLink() to create a string with a hyperlink. This method is based on an underlying ANSI escape sequence. This command uses that same sequence so that you can create a hyperlinked string in Windows PowerShell. The command also makes it easier to add other styling. By default, the link will have a solid underline.

Optionally, you can use AsString to see a text version of the string with escape sequence markers.

$l = New-ANSIHyperlink -DisplayText "about Jeff" -Link "https://jdhitsolutions.github.io" -Style "`e[3;93m"
Creating an ANSI hyperlink
figure 5 - Creating an ANSI hyperlink

See the help examples for how you might leverage this command. I am using it with Get-PSScriptTools to add a link on each command that opens the corresponding online help location.

PSScriptTools help links
figure 6 - PSScriptTools help links

Get-ProcessTree

This command will display a process tree for a given process ID. The command will display a list of processes in order from parent to child. In other words, the oldest parent process will be listed first. The last process in the output will be the process you queried.

This command requires PowerShell 7.

PS C:\> Get-ProcessTree -id $pid

NPM(K)  PM(K)  WS(K) CPU(s)    Id SI ProcessName                 StartTime
------  -----  ----- ------    -- -- -----------                 ---------
   139 461996 458076  87.72 14264  1 explorer        7/28/2026 10:51:21 AM
    51 167088 172996  90.72 18684  1 WindowsTerminal 7/28/2026 10:53:03 AM
   160 175464 320320  31.67 32364  1 pwsh             7/28/2026 1:43:38 PM

Show-ProcessTree

Or you can use an ANSI-enhanced view of a process tree.

Show-ProcessTree
figure 7 - Show-ProcessTree

Show-HiddenMember

By design, PowerShell will hide parts of an object that have very little relevance to scripting or interactive PowerShell use. Often, these are .NET properties and methods that are automatically added. You can see them using Get-Member -Force. This command is designed to simplify the process.

It is expected that you will pipe an object to this command like you do with Get-Member. It is also assumed that if you pipe multiple objects they are all of the same type. Only the first object will be processed.

In most cases, you'll see things that are hidden on all objects in PowerShell.

 PS C:\> "powershell" | Show-HiddenMember

       Type: System.String

    Name                    MemberType
    ----                    ----------
    pstypenames           CodeProperty
    psadapted                MemberSet
    psbase                   MemberSet
    psextended               MemberSet
    psobject                 MemberSet
    get_Chars                   Method
    get_Length                  Method

This will be more useful for custom object types where there may be hidden property. I'm working on an update to the PSIntro module which includes a new object type with a hidden member.

PS C:\> Get-PSIntroSettings | Show-HiddenMember -MemberType Properties

   Type: PSIntroSettings

Name                    MemberType
----                    ----------
pstypenames           CodeProperty
Path                      Property

This could be a handy tool to verify that hidden properties are indeed hidden.

Format-BorderBox

Use this command to display a block of text in a colored lined border box. You can use ANSI or PSStyle to specify the line color. The default is green.

Get-WindowsVersionString -Computername Cadenza -UseStyle | Format-BorderBox -BorderColor $PSStyle.Foreground.BrightMagenta
Formatting OS information in an border box
figure 8 - Formatting OS information in an border box

PSConfEU Interview

My post event interview from PSConfEu 2026
figure 9 - My post event interview from PSConfEu 2026

I've previously shared links to the content from this year's PSConfEU. At the end of the event, I sat down with one of the organizers to chat about the event and the PowerShell community in general. You can watch at https://youtu.be/ExlRYkv0IB4. And be sure to checkout the other content from the event.

MVP Year 20

Microsoft MVP

Finally, it is Microsoft MVP renewal season. If you were on social media the last few weeks you probably saw a lot of announcements. I'm very proud to be renewed for my 20th year as a PowerShell MVP. PowerShell will be celebrating it's 20th anniversary (birthday?) this November, so yes, I have been around since the days when PowerShell only had 160+ commands., no remoting, no modules, and no PSGallery. It has been an amazing journey. Not only to see how PowerShell has grown, but the community as well. It has been my privilege to have helped people learn and expand their skills. I hope to do it for a little longer.

Scripting Challenge

Of course, the end of the month wouldn't be complete without a PowerShell scripting challenge. I think you might have fun with this one. In Windows PowerShell, we could use Get-Process and get processes from a remote computer. The connection was made using legacy remoting protocols that aren't supported in PowerShell 7. That's why you won't see a -Computername parameter in PowerShell 7.

For your challenge, I want you to write an alternative function that uses Get-CimInstance to use the Win32_Process class to get similar information but modeled after Get-Process. In other words, the function should be able to:

  • Get all processes by default
  • Get a process by name
  • Get a process by ID
  • include the user name
  • query a remote computer by name

I'll let you decide how you want to format the results. Although the more you can make the output similar to Get-Process the better.

There are differences in how processes are defined in .NET vs CIM. You'll need to keep that in mind. Don't worry about capturing FileVersionInfo or ModuleInfo like you see with Get-Process. This information shouldn't be the output of the command anyway. If you really want to be challenged, you could create separate commands to get that information.

Summary

As always, I hoped you learned a few things this month. I also hope you are trying out things I show you. The best way to learn is to do.

See you next month.

(c) 2022-2025 JDH Information Technology Solutions, Inc. - all rights reserved
Don't miss what's next. Subscribe to Behind the PowerShell Pipeline:
Older → A VHD Backup Solution

Add a comment:

Posting this comment will subscribe you to this newsletter with the email address you enter.
Share this email:
Share on LinkedIn Share on Mastodon Share on Bluesky
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.