This page covers the view registry behind Enable-ConsoleFormatting: how to tell ConsoleMonster which columns, presenters and grouping a type gets, how to draft that from objects you already have, and how a module ships its views without depending on ConsoleMonster. Restyle any command's output walks through the same steps for one command.
Get-ContosoServer before and after its view
A module puts Contoso.Servers.consoleviews.psd1 beside its manifest: plain data naming the columns, their presenters and the grouping. The module never imports ConsoleMonster; its users get the view when they turn formatting on.
PS> Import-Module ConsoleMonster PS> Import-Module ./Contoso.Servers PS> PS> # Without views: PowerShell's own table PS> Get-ContosoServer Name Site State Uptime ---- ---- ----- ------ web01 Warsaw Running 17.04:00:00 web02 Warsaw Running 09:00:00 sql01 Warsaw Degraded 50.10:00:00 app01 Krakow Running 3.05:00:00 app02 Krakow Stopped 00:00:00 PS> PS> Enable-ConsoleFormatting PS> PS> # The module's Contoso.Servers.consoleviews.psd1 picks the columns and the groups PS> Get-ContosoServer ╭──────────────┬────────────┬───────────╮ │ Name │ Health │ Uptime │ ├─ Krakow · 2 ─┼────────────┼───────────┤ │ app01 │ ● Running │ 3 d 5 h │ │ app02 │ – Stopped │ 0 ms │ ├─ Warsaw · 3 ─┼────────────┼───────────┤ │ web01 │ ● Running │ 17 d 4 h │ │ web02 │ ● Running │ 9 h 00 m │ │ sql01 │ ▲ Degraded │ 50 d 10 h │ ╰──────────────┴────────────┴───────────╯
Import-Module ./Contoso.Servers
# Without views: PowerShell's own table
Get-ContosoServer
Enable-ConsoleFormatting
# The module's Contoso.Servers.consoleviews.psd1 picks the columns and the groups
Get-ContosoServerFull program
Import-Module ConsoleMonster
Import-Module ./Contoso.Servers
# Without views: PowerShell's own table
Get-ContosoServer
Enable-ConsoleFormatting
# The module's Contoso.Servers.consoleviews.psd1 picks the columns and the groups
Get-ContosoServer# Read by ConsoleMonster when it is loaded; plain data, no code. The module itself never imports ConsoleMonster.
@{
SchemaVersion = 1
Views = @(
@{
TypeName = 'Contoso.Server'
View = 'Table'
Property = @(
'Name'
@{ Name = 'Health'; Expression = 'State'; Presenter = 'StatusWord' }
'Uptime'
)
GroupBy = 'Site'
}
)
}function Get-ContosoServer {
<#
.SYNOPSIS
Returns the servers in the Contoso inventory as Contoso.Server objects.
#>
[CmdletBinding()]
param()
$servers = @(
@{ Name = 'web01'; Site = 'Warsaw'; State = 'Running'; Hours = 412 }
@{ Name = 'web02'; Site = 'Warsaw'; State = 'Running'; Hours = 9 }
@{ Name = 'sql01'; Site = 'Warsaw'; State = 'Degraded'; Hours = 1210 }
@{ Name = 'app01'; Site = 'Krakow'; State = 'Running'; Hours = 77 }
@{ Name = 'app02'; Site = 'Krakow'; State = 'Stopped'; Hours = 0 }
)
foreach ($server in $servers) {
[pscustomobject] @{
PSTypeName = 'Contoso.Server'
Name = $server.Name
Site = $server.Site
State = $server.State
Uptime = New-TimeSpan -Hours $server.Hours
}
}
}@{
RootModule = 'Contoso.Servers.psm1'
ModuleVersion = '1.0.0'
GUID = '5b0f7a52-6a52-4c1e-9d58-2f1f9a7c3e21'
Author = 'Contoso'
Description = 'Servers in the Contoso inventory. It knows nothing about ConsoleMonster.'
FunctionsToExport = 'Get-ContosoServer'
}// A compiled cmdlet: the current PowerShell runspace owns native commands and callbacks.
[Cmdlet(VerbsLifecycle.Invoke, "ModuleViewsExample") ]
public sealed class ModuleViewsExample : PSCmdlet {
protected override void ProcessRecord() {
InvokeCommand.InvokeScript("Import-Module ./Contoso.Servers");
ConsoleHostViews.Import(this, "./Contoso.Servers/Contoso.Servers.consoleviews.psd1");
using var output = new ConsoleDefaultOutput(
this,
new ConsoleDefaultOutputOptions { Force = true });
foreach (var row in InvokeCommand.InvokeScript("Get-ContosoServer")) { output.Write(row); }
output.Complete();
}
}Full program
using System.Management.Automation;
using ConsoleMonster.PowerShell;
// A compiled cmdlet: the current PowerShell runspace owns native commands and callbacks.
[Cmdlet(VerbsLifecycle.Invoke, "ModuleViewsExample") ]
public sealed class ModuleViewsExample : PSCmdlet {
protected override void ProcessRecord() {
InvokeCommand.InvokeScript("Import-Module ./Contoso.Servers");
ConsoleHostViews.Import(this, "./Contoso.Servers/Contoso.Servers.consoleviews.psd1");
using var output = new ConsoleDefaultOutput(
this,
new ConsoleDefaultOutputOptions { Force = true });
foreach (var row in InvokeCommand.InvokeScript("Get-ContosoServer")) { output.Write(row); }
output.Complete();
}
}Download HostExample.csproj beside the source file.
Import-Module ConsoleMonster
$moduleBinary = Split-Path (Get-Command Show-Console).DLL
dotnet build ./HostExample.csproj -c Release "-p:ConsoleMonsterModuleDirectory=$moduleBinary"
Import-Module ./bin/Release/net8.0/HostExample.dll
Invoke-ModuleViewsExampleThis is a compiled PowerShell cmdlet class. Reference the installed module’s ConsoleMonster and ConsoleMonster.PowerShell assemblies in a PowerShell module project; ProcessRecord runs on the owning pipeline thread. Download the project beside the source file and build/run it from PowerShell 7.
// A compiled cmdlet: the current PowerShell runspace owns native commands and callbacks.
[Cmdlet(VerbsLifecycle.Invoke, "ModuleViewsExample")]
public sealed class ModuleViewsExample : PSCmdlet
{
protected override void ProcessRecord()
{
InvokeCommand.InvokeScript("Import-Module ./Contoso.Servers");
ConsoleHostViews.Import(this, "./Contoso.Servers/Contoso.Servers.consoleviews.psd1");
using var output = new ConsoleDefaultOutput(
this,
new ConsoleDefaultOutputOptions().Force());
foreach (var row in InvokeCommand.InvokeScript("Get-ContosoServer"))
{
output.Write(row);
}
output.Complete();
}
}
Full program
using System.Management.Automation;
using ConsoleMonster.PowerShell;
// A compiled cmdlet: the current PowerShell runspace owns native commands and callbacks.
[Cmdlet(VerbsLifecycle.Invoke, "ModuleViewsExample")]
public sealed class ModuleViewsExample : PSCmdlet
{
protected override void ProcessRecord()
{
InvokeCommand.InvokeScript("Import-Module ./Contoso.Servers");
ConsoleHostViews.Import(this, "./Contoso.Servers/Contoso.Servers.consoleviews.psd1");
using var output = new ConsoleDefaultOutput(
this,
new ConsoleDefaultOutputOptions().Force());
foreach (var row in InvokeCommand.InvokeScript("Get-ContosoServer"))
{
output.Write(row);
}
output.Complete();
}
}
Download HostExample.csproj beside the source file.
Import-Module ConsoleMonster
$moduleBinary = Split-Path (Get-Command Show-Console).DLL
dotnet build ./HostExample.csproj -c Release "-p:ConsoleMonsterModuleDirectory=$moduleBinary"
Import-Module ./bin/Release/net8.0/HostExample.dll
Invoke-ModuleViewsExampleThis is a compiled PowerShell cmdlet class. Reference the installed module’s ConsoleMonster and ConsoleMonster.PowerShell assemblies in a PowerShell module project; ProcessRecord runs on the owning pipeline thread. Download the project beside the source file and build/run it from PowerShell 7.
Ship views with your module
# Beside YourModule.psd1:
# YourModule.consoleviews.psd1 with SchemaVersion = 1 and a Views list, as above.
# Your users:
Import-Module YourModule
Import-Module ConsoleMonster
Enable-ConsoleFormattingSee also: Register-ConsoleView
Register a view
Register-ConsoleView names a type and the columns to show for it. Once formatting is on, every object whose type names include it is shown that way when it reaches the console:
Import-Module ConsoleMonster
Enable-ConsoleFormatting
$health = @{ Name = 'Health'; Expression = { $_.State }; Presenter = 'StatusWord' }
Register-ConsoleView -TypeName Contoso.Server -Property Name, $health, Uptime -GroupBy Site
| Parameter | What it sets |
|---|---|
-TypeName | The type names the view applies to, as in $object.PSObject.TypeNames. |
-View | Table (the default), Cards, Tree, Inspector or Chart. |
-Property | The columns, as Show-ConsoleTable takes them: names, or hashtables with Name, Expression, Presenter and the other column options. |
-GroupBy | A property name or script block that puts rows under headings. |
-Title | A script block giving each object's title: a shared title heads the view, different titles group the rows. |
-Group | A group name: consecutive objects of types in the same group are shown together, as files and folders are. |
-Shaper | A script block that turns each object into what is shown instead, such as an ordered dictionary of the fields worth seeing. It applies in every ConsoleMonster command. |
-Summary | A script block that sums up the objects shown together, under the view on the console. It returns facts: strings, or hashtables with Value, Label, Caption, Presenter and Role. |
Registrations belong to the current session (runspace), and a registration takes precedence over the view ConsoleMonster ships for the same type. Unregister-ConsoleView -TypeName Contoso.Server removes it, and Enable-ConsoleFormatting -NoBuiltIn keeps only the views you registered.
Draft a view from samples
ConvertTo-ConsoleView looks at the objects piped to it and returns a ready-to-paste Register-ConsoleView script:
Get-Process | ConvertTo-ConsoleView
The draft examines the first 50 objects and chooses up to six non-empty columns, with the name or identity first. Presenters come from the same inference as the default table: status words, byte bars for sizes that vary more than tenfold, and relative dates for the last 30 days. A count of the objects, and of each status, becomes the summary; drop -Summary $summary to leave it out.
-Registerinstalls the drafted view now, and still returns the script for later editing.-AsDataFilereturns a data file instead of a script, for a module to ship.
Sample one shape of object at a time. Deserialized input (from jobs and remoting) drafts for the base type with a warning, and Select-Object output keeps its Selected. type name, also with a warning.
Ship views with a module
A module can ship its views as a data file beside its manifest, named <ModuleName>.consoleviews.psd1. The module needs no dependency on ConsoleMonster: it keeps returning ordinary typed objects, and its users get the view when they import ConsoleMonster and turn formatting on.
# Contoso.Servers.consoleviews.psd1
@{
SchemaVersion = 1
Views = @(
@{
TypeName = 'Contoso.Server'
View = 'Table'
Property = @(
'Name'
@{ Name = 'Health'; Expression = 'State'; Presenter = 'StatusWord' }
'Uptime'
)
GroupBy = 'Site'
Group = 'ContosoServers'
}
)
}
- Format. A PowerShell data file, read with
Import-PowerShellDataFile.SchemaVersionis1, and each entry inViewshas aTypeNameand optionallyView,Property,GroupBy(a property name) andGroup. Plain columns are strings; only columns with options need hashtables, and theirExpressionis a property name. - No code. The file holds no script blocks or commands. Calculated expressions, shapers and summaries belong in an explicit
Register-ConsoleViewin the session. - Discovery. ConsoleMonster finds the file for modules already loaded when formatting is enabled or a view is built, including modules imported after ConsoleMonster. Each module is inspected once per session, and discovery never imports other modules or changes their objects.
- Validation. The whole file is checked before anything is registered. A discovered file that is not valid produces a warning; an explicit import reports the error.
- Precedence. An explicit
Register-ConsoleViewwins over a discovered file, and discovery keeps existing registrations.
The module's users do the rest:
Import-Module Contoso.Servers
Import-Module ConsoleMonster
Enable-ConsoleFormatting
Get-ContosoServer
# Explicit formatting and export use the same registered columns.
Get-ContosoServer | New-ConsoleTable | Export-ConsoleFrame -Format Markdown
To load a file from another location, or reload one while working on it, import it explicitly:
Register-ConsoleView -Path ./views/Contoso.Servers.consoleviews.psd1
PowerShell's own Format-Table -View definitions stay separate and still come from .format.ps1xml files.
In C#
The data file is a PowerShell module convention. In .NET code, declare the same columns on the table:
var table = new Table { RecordViewRows = 0 };
table.AddColumn("Name");
table.AddColumn(new TableColumn("Health") { Presenter = CellPresenters.StatusWord });
table.AddValues("alpha", "Pass");
Terminal.Write(table);
Next
- Restyle any command's output: a view for another module's command, from type name to profile.
- Everyday PowerShell output: the views that ship with ConsoleMonster.
- PowerShell conventions: the column options and presenters
-Propertyaccepts.