Table of Contents

Microsoft - Programming - PowerShell - Snippets - Show all properties

Output of PowerShell cmdlets often can contain properties containing values, or properties containing objects or arrays.

This page lists some snippets taken from elsewhere to fully “peel the onion” of such objects and show all values.

Display-Object

From Redgate Hub - Display-Object: a PowerShell utility Cmdlet:

<#
	.SYNOPSIS
		Displays an object's values and the 'dot' paths to them
 
	.DESCRIPTION
		A detailed description of the Display-Object function.
 
	.PARAMETER TheObject
		The object that you wish to display
 
	.PARAMETER depth
		the depth of recursion (keep it low!)
 
	.PARAMETER Avoid
		an array of names of pbjects or arrays you wish to avoid.
 
	.PARAMETER Parent
		For internal use, but you can specify the name of the variable
 
	.PARAMETER CurrentDepth
		For internal use
 
	.NOTES
		Additional information about the function.
#>
function Display-Object
{
	[CmdletBinding()]
	param
	(
		[Parameter(Mandatory = $true,
				   ValueFromPipeline = $true)]
		$TheObject,
		[int]$depth = 5,
		[Object[]]$Avoid = @('#comment'),
		[string]$Parent = '$',
		[int]$CurrentDepth = 0
	)
 
	if (($CurrentDepth -ge $Depth) -or
		($TheObject -eq $Null)) { return; } #prevent runaway recursion
	$ObjectTypeName = $TheObject.GetType().Name #find out what type it is
	if ($ObjectTypeName -in 'HashTable', 'OrderedDictionary')
	{
		#If you can, force it to be a PSCustomObject
		$TheObject = [pscustomObject]$TheObject;
		$ObjectTypeName = 'PSCustomObject'
	}#first do objects that cannot be treated as an array.
	if ($TheObject.Count -le 1 -and $ObjectTypeName -ne 'object[]') #not something that behaves like an array
	{
		# figure out where you get the names from
		if ($ObjectTypeName -in @('PSCustomObject'))
		# Name-Value pair properties created by Powershell 
		{ $MemberType = 'NoteProperty' }
		else
		{ $MemberType = 'Property' }
		#now go through the names 
		$TheObject | 
		gm -MemberType $MemberType | where { $_.Name -notin $Avoid } |
		Foreach{
			Try { $child = $TheObject.($_.Name); }
			Catch { $Child = $null } # avoid crashing on write-only objects
            $brackets=''; if ($_.Name -like '*.*'){$brackets="'"}
			if ($child -eq $null -or #is the current child a value or a null?
				$child.GetType().BaseType.Name -eq 'ValueType' -or
				$child.GetType().Name -in @('String', 'String[]'))
			{ [pscustomobject]@{ 'Path' = "$Parent.$brackets$($_.Name)$brackets"; 'Value' = $Child; } }
			elseif (($CurrentDepth + 1) -eq $Depth)
			{
				[pscustomobject]@{ 'Path' = "$Parent.$brackets$($_.Name)$brackets"; 'Value' = $Child; }
			}
			else #not a value but an object of some sort
			{
				Display-Object -TheObject $child -depth $Depth -Avoid $Avoid `
                               -Parent "$Parent.$brackets$($_.Name)$brackets" `
							   -CurrentDepth ($currentDepth + 1)
			}
 
		}
	}
	else #it is an array
	{
		if ($TheObject.Count -gt 0)
            {0..($TheObject.Count - 1) | Foreach{
			$child = $TheObject[$_];
			if (($child -eq $null) -or #is the current child a value or a null?
				($child.GetType().BaseType.Name -eq 'ValueType') -or
				($child.GetType().Name -in @('String', 'String[]'))) #if so display it 
			{ [pscustomobject]@{ 'Path' = "$Parent[$_]"; 'Value' = "$($child)"; } }
			elseif (($CurrentDepth + 1) -eq $Depth)
			{
				[pscustomobject]@{ 'Path' = "$Parent[$_]"; 'Value' = "$($child)"; }
			}
			else #not a value but an object of some sort so do a recursive call
			{
				Display-Object -TheObject $child -depth $Depth -Avoid $Avoid -parent "$Parent[$_]" `
							   -CurrentDepth ($currentDepth + 1)
			}
 
		}
	}
    else {[pscustomobject]@{ 'Path' = "$Parent"; 'Value' = $Null }}
    }
}

Example output:

  1. Copy and paste the above to a PowerShell window.
  2. Show all properties of the ScheduledDefrag scheduled task:
    Get-ScheduledTask -TaskPath "\Microsoft\Windows\Defrag\" -TaskName "ScheduledDefrag" | Display-Object
  3. Output:
    Path                                          Value
    ----                                          -----
    $.Actions.Arguments                           -c -h -o -$
    $.Actions.Execute                             %windir%\system32\defrag.exe
    $.Actions.Id
    $.Actions.PSComputerName
    $.Actions.WorkingDirectory
    $.Author                                      Microsoft Corporation
    $.Date
    $.Description                                 Met deze taak worden de lokale opslagstations geoptimaliseerd.
    $.Documentation
    $.Principal.DisplayName
    $.Principal.GroupId
    $.Principal.Id                                LocalSystem
    $.Principal.PSComputerName
    $.Principal.RequiredPrivilege
    $.Principal.UserId                            SYSTEM
    $.PSComputerName
    $.SecurityDescriptor                          D:AI(A;;FA;;;BA)(A;;FA;;;SY)(A;;FRFX;;;LS)(A;;FR;;;AU)
    $.Settings.AllowDemandStart                   True
    $.Settings.AllowHardTerminate                 True
    $.Settings.DeleteExpiredTaskAfter
    $.Settings.DisallowStartIfOnBatteries         True
    $.Settings.DisallowStartOnRemoteAppSession    False
    $.Settings.Enabled                            True
    $.Settings.ExecutionTimeLimit                 PT72H
    $.Settings.Hidden                             False
    $.Settings.IdleSettings.IdleDuration
    $.Settings.IdleSettings.PSComputerName
    $.Settings.IdleSettings.RestartOnIdle         False
    $.Settings.IdleSettings.StopOnIdleEnd         True
    $.Settings.IdleSettings.WaitTimeout
    $.Settings.MaintenanceSettings.Deadline       P1M
    $.Settings.MaintenanceSettings.Exclusive      False
    $.Settings.MaintenanceSettings.Period         P7D
    $.Settings.MaintenanceSettings.PSComputerName
    $.Settings.NetworkSettings.Id
    $.Settings.NetworkSettings.Name
    $.Settings.NetworkSettings.PSComputerName
    $.Settings.Priority                           7
    $.Settings.PSComputerName
    $.Settings.RestartCount                       0
    $.Settings.RestartInterval
    $.Settings.RunOnlyIfIdle                      False
    $.Settings.RunOnlyIfNetworkAvailable          False
    $.Settings.StartWhenAvailable                 True
    $.Settings.StopIfGoingOnBatteries             True
    $.Settings.UseUnifiedSchedulingEngine         True
    $.Settings.volatile                           False
    $.Settings.WakeToRun                          False
    $.Source                                      Microsoft Corporation
    $.TaskName                                    ScheduledDefrag
    $.TaskPath                                    \Microsoft\Windows\Defrag\
    $.Triggers
    $.URI                                         \Microsoft\Windows\Defrag\ScheduledDefrag
    $.Version

Show-AllProperties

From Please Work - HOWTO: Show absolutely All Nested Properties of a PowerShell Object in a Treeview.

Requires jsonview.exe available at CodePlex archive - JSON Viewer

# Displays all properties and sub properties of an object in a GUI
# JSON; Home; Properties; Object; GUI
# Requires -version 3
# JSONViewer Download Available At: https://jsonviewer.codeplex.com/
 
Function Show-AllProperties
{
    param
    (
        [Parameter(ValueFromPipeline=$true)] $InputObject,
        [Parameter(ValueFromPipeline=$false)]
        [ValidateRange(1,9)]
        [int]$Depth=4
    )
 
    # This specifies how many layers deep the JSON will go.  It seems that anything more than 5 can result in a signifigant performance penalty
    $JSONViewPath = "c:\bin\jsonview\jsonview.exe"
 
    if(!(Test-Path $JSONViewPath)) { Write-Error "$JSONViewPath is not found.  This is required."; break}
 
    # Need to use reserved PowerShell variable $input to bypass the "one object at a time" default processing of pipelined input
    $InputObject = $input
    $Date = Get-Date
 
    # Set the file path to the temporary file we'll save the exported JSON to so it can be loaded into jsonview.exe
    # We will constantly overwrite/reuse this file since we have no way of safely deleting it without knowing for sure it's not being used by the jsonview.exe
    $TempFilePath = $env:TEMP+"\PSjsonviewtemp.json"
 
    # Create a status bar so if the conversion takes a long time to run, the user has some kind of visual feedback it's still running  
    $Params = @{
            "Activity" = "[$Date] Converting object to JSON.  This process may take several minutes to complete." 
            "Status" = "(Note: Increasing the -depth paramater beyond 4 may result in substantially longer processing times)"
            "Id" = 1
        }
 
    Write-Progress @Params
 
    # Convert the object to JSON.  Need to use the Compress option to get around a bug when processing some Powershell Objects
    try { $JSON = $InputObject | ConvertTo-Json -Compress -Depth $Depth }
    catch { Write-Warning "This object cannot be converted to JSON. Try selecting a sub property and trying again.`n$_"; break }
    Write-Progress "Completed converting the object to JSON..." -id 1 -Completed 
 
    # Write the JSON to the temporary file and then open it with jsonview.exe
    $JSON | Out-File $TempFilePath -Force
 
    # Call the external JSON view application and pass it the file to display
    Start-Process -FilePath $JSONViewPath -ArgumentList $TempFilePath
}
 
# Set a three letter alias to make it faster to run
Set-Alias sap Show-AllProperties

Example output:

  1. Make sure c:\bin\jsonview\jsonview.exe exists, or modify this line in the above PowerShell to point to the right file:
    $JSONViewPath = "c:\bin\jsonview\jsonview.exe"
  2. Copy and paste the above to a PowerShell window.
  3. Show all properties of the ScheduledDefrag scheduled task:
    Get-ScheduledTask -TaskPath "\Microsoft\Windows\Defrag\" -TaskName "ScheduledDefrag" | Show-AllProperties
  4. Output: