Skip to content
ConsoleMonster

Everyday PowerShell output

Enable-ConsoleFormatting makes ordinary output readable for the session: files, processes, hashtables, arrays and groups, before and after.

You do not have to change your commands to get readable output. One line turns it on for the session:

Enable-ConsoleFormatting

Files and folders, processes, services, commands, modules, event log records, IP addresses, volumes and dictionaries are then shown as ConsoleMonster tables and records when they reach the console. Objects stay the same: pipelines into other commands, Format-*, Out-String, redirected output, transcripts, jobs and remoting keep PowerShell's behaviour. Disable-ConsoleFormatting turns it off.

To keep it on in every session, print the lines for your profile and paste them in (nothing is written for you):

Enable-ConsoleFormatting -ProfileSnippet

Before and after Enable-ConsoleFormatting

Processes, files and a hashtable, first as PowerShell shows them, then with ConsoleMonster turned on for the session, followed by services grouped by status.

Enable-ConsoleFormatting 100×3924-bitFull
PowerShellWebsite/examples/demos/formatting.ps1
# Everyday commands as PowerShell shows them, then the same commands after one line: Enable-ConsoleFormatting.
$windows = $env:OS -eq 'Windows_NT'
$process = if ($windows) { @{ Name = 'svchost' } } else { @{ Id = $PID } }
# PowerShell's own output
Get-Process @process | Sort-Object CPU -Descending | Select-Object -First 8 | Out-Default
Get-ChildItem | Out-Default
@{ Domain = 'evotec.xyz'; Records = 14; DNSSEC = $false } | Out-Default
Enable-ConsoleFormatting
# The same commands now
Get-Process @process | Sort-Object CPU -Descending | Select-Object -First 8 | Out-Default
Get-ChildItem | Out-Default
@{ Domain = 'evotec.xyz'; Records = 14; DNSSEC = $false } | Out-Default
if ($windows) {
    Get-Service W* | Format-ConsoleTable -GroupBy Status -Top 6
} else {
    Get-Process @process | Format-ConsoleTable -GroupBy ProcessName -Top 6
}
Full program
# Everyday commands as PowerShell shows them, then the same commands after one line: Enable-ConsoleFormatting.
$windows = $env:OS -eq 'Windows_NT'
$process = if ($windows) { @{ Name = 'svchost' } } else { @{ Id = $PID } }
# The hidden lines only print the prompt before each command, as a terminal would.
function Write-Prompt([string] $Command) { Start-Sleep -Milliseconds 700; Write-Host "PS> $Command" -ForegroundColor Yellow; Start-Sleep -Milliseconds 400 }
Set-Location -LiteralPath (Join-Path $PSHOME 'Modules')
Write-Prompt "# PowerShell's own output"
Write-Prompt ("Get-Process $(if ($windows) { 'svchost' } else { "-Id $PID" }) | Sort-Object CPU -Descending | Select-Object -First 8")
# PowerShell's own output
Get-Process @process | Sort-Object CPU -Descending | Select-Object -First 8 | Out-Default
Write-Prompt 'Get-ChildItem'
Get-ChildItem | Out-Default
Write-Prompt '@{ Domain = ''evotec.xyz''; Records = 14; DNSSEC = $false }'
@{ Domain = 'evotec.xyz'; Records = 14; DNSSEC = $false } | Out-Default
Write-Prompt 'Enable-ConsoleFormatting'
Enable-ConsoleFormatting
Write-Prompt '# The same commands now'
Write-Prompt ("Get-Process $(if ($windows) { 'svchost' } else { "-Id $PID" }) | Sort-Object CPU -Descending | Select-Object -First 8")
# The same commands now
Get-Process @process | Sort-Object CPU -Descending | Select-Object -First 8 | Out-Default
Write-Prompt 'Get-ChildItem'
Get-ChildItem | Out-Default
Write-Prompt '@{ Domain = ''evotec.xyz''; Records = 14; DNSSEC = $false }'
@{ Domain = 'evotec.xyz'; Records = 14; DNSSEC = $false } | Out-Default
Write-Prompt $(if ($windows) { 'Get-Service W* | Format-ConsoleTable -GroupBy Status -Top 6' } else { "Get-Process -Id $PID | Format-ConsoleTable -GroupBy ProcessName -Top 6" })
if ($windows) {
    Get-Service W* | Format-ConsoleTable -GroupBy Status -Top 6
} else {
    Get-Process @process | Format-ConsoleTable -GroupBy ProcessName -Top 6
}
Start-Sleep -Milliseconds 600
Disable-ConsoleFormatting

Use it in every session

PowerShell 5.1 and 7
Install-Module ConsoleMonster -Scope CurrentUser
Enable-ConsoleFormatting -ProfileSnippet

Reference: Enable-ConsoleFormatting

Arrays in cells and groups

Format-Table beside Format-ConsoleTable -GroupBy on the same objects: roles as a list, durations as durations, statuses with their symbol, one heading per site.

Format-ConsoleTable -GroupBy Site 100×1924-bitFull
PowerShellWebsite/examples/demos/shaping.ps1
# Arrays in cells and groups: the built-in Format-Table beside Format-ConsoleTable, on the same objects.
$servers = @(
    [pscustomobject] @{ Name = 'DC01'; Site = 'Warsaw'; Roles = 'DNS', 'GC', 'PDC'; LastSync = (New-TimeSpan -Seconds 42); Status = 'Pass' }
    [pscustomobject] @{ Name = 'DC02'; Site = 'Warsaw'; Roles = 'DNS', 'GC'; LastSync = (New-TimeSpan -Minutes 42); Status = 'Warn' }
    [pscustomobject] @{ Name = 'DC03'; Site = 'Dublin'; Roles = 'DNS', 'GC', 'RID', 'Infrastructure', 'Schema', 'Naming'; LastSync = (New-TimeSpan -Seconds 64); Status = 'Pass' }
    [pscustomobject] @{ Name = 'DC04'; Site = 'Dublin'; Roles = @(); LastSync = (New-TimeSpan -Hours 4); Status = 'Fail' }
)
Write-ConsoleRule 'Format-Table'
$servers | Format-Table | Out-Host
Write-ConsoleRule 'Format-ConsoleTable -GroupBy Site'
$servers | Format-ConsoleTable -GroupBy Site

Use it in your script

PowerShell 5.1 and 7
Install-Module ConsoleMonster -Scope CurrentUser

Reference: Format-ConsoleTable

Collections in a cell are joined (DNS, GC, PDC), with a +N marker for the items that do not fit, where Format-Table shows {DNS, GC, PDC} and cuts long lists short. Durations read as 42 s or 4 h 00 m, an empty collection is a dash, and status words get their symbol and colour. -GroupBy writes a labelled heading per group, with its count.

More from the same switch

  • Enable-ConsoleFormatting -Feature ErrorView and -Feature Progress add the error view and the progress area.
  • Register-ConsoleView adds your own types: a view per type name with the columns you choose.
  • Format-ConsoleTable, Format-ConsoleList and Format-ConsoleTree give the same views on demand, with column options; see Coming from Format-Table.

Edit this page on GitHub