Skip to content

Reference

From the comment-based help of the module (Get-Help New-UDPivotReport -Full shows the same).

New-UDPivotReport

A pivot report builder for PowerShell Universal apps: readers drag fields into rows, columns, values and filters and get a table or a chart, with drill-down, templates and Excel export.

Pass the data as it comes - a DataTable from a SQL query, objects from Invoke-RestMethod or any PowerShell command. Readers build their own report: a field list with search, four zones (Rows, Columns, Values, Filters) with drag and drop and a menu on every field, sums, counts, averages and "show values as", date grouping by year, quarter, month or day, filters with value counts, table or chart (bars, lines, area, pie, heatmap), a click on a value opens the rows behind it, undo and redo, templates, and Excel (XLSX), CSV and PNG export. All of it runs in the browser (pivotkit); the server is only asked for what the event parameters do.

A view - what the report shows - is plain JSON that pivotkit checks against the data; it never runs as code. -View sets the start view, -Templates the views offered in the Templates menu, -TemplatePath reads view files from folders, and -TemplateStore keeps readers' own views and the shared ones (New-UDPivotFileTemplateStore, New-UDPivotTemplateStore) with -AdminRole for who may change shared views; -OnSaveTemplate and -OnDeleteTemplate stay for full control. Field names are matched without regard to case.

Parameter Type Description
-Id String Component id. Default: a new GUID. Get-UDElement -Id returns the current view as .view; Set-UDElement -Id -Properties @{ view = ... } shows another view (one undo step). The browser tab keeps the reader's view under this id; without -Id the report is identified by its page, its place in the app script (line and column of the call) and its column names. Set -Id when one call builds several reports (a loop) or reports are added or removed at run time.
-Data (required) Object Rows: a DataTable (Invoke-Sqlcmd, SqlClient, ODBC), DataRows, PSCustomObjects, hashtables or a script block returning them. DBNull becomes an empty value, dates stay dates, TimeSpans become seconds. The column names are the field names the reader sees.
-View Object The view the report starts with (and goes back to with Reset): a hashtable or JSON, e.g. @{ rows = @('Team'); cols = @('Priority'); values = @(@{ field = 'Id'; agg = 'count' }) }. Keys: rows, cols (field names), values (field, agg: sum, count, average, min, max, ...; format: a format name), filters, sort, totals, display (table or chart), chart (type: bar, line, area, pie, heatmap). A saved template's view goes in as it is. Default: an empty report with the hint where to start. A view in the address bar (#pivot-=..., written by the report on every change unless -NoAddressBar, so a copied link opens the same layout) wins over it.
-SavedView Object The reader's own view stored by the app (from -OnViewChange or a "save as my default" action), a hashtable or JSON. A browser tab without a view of its own (in its address bar or its sessionStorage) starts with it; a tab that already shows a view keeps that one, so a view stored for the whole PSU session (shared by all tabs of the browser) never takes over another tab. Reset still goes back to -View. A view that does not pass ConvertFrom-UDPivotView is left out with a warning.
-Templates Object[] Views offered in the Views menu (the first three also on the empty report): a list of @{ Name = 'Tickets per team'; View = } or @{ File = }, with Scope shared ("Shared views") or user ("My views") and Deletable (a delete button when -OnDeleteTemplate is set). Without Scope a Deletable entry is the reader's own, every other one shared.
-TemplatePath String[] Folders of pivotkit view files (*.pivotkit.json, as Download view in the Views menu writes them), read on the server on every render and offered under "Shared views", read-only. Each file is checked (at most 1,000,000 characters, a view ConvertFrom-UDPivotView accepts); a broken one is left out with a warning. A module ships its views with -TemplatePath (Join-Path $PSScriptRoot 'views').
-TemplateStore Object Where readers keep their own views ("My views") and admins the shared ones. Without it nothing is written and Save is not offered (unless -OnSaveTemplate). Browser: pivotkit keeps each reader's views in the browser's localStorage (this browser and device only). A store of New-UDPivotFileTemplateStore (view files in a folder on the server) or New-UDPivotTemplateStore (your own storage: a database, Valkey, S3): the module registers the event handlers, saves a reader's views under their $User, and lets readers with a role of -AdminRole publish and delete shared views - checked on the server with $Roles of each event. In an app without sign-in the server cannot tell readers apart: their own views then stay in the browser, shared views come from the store.
-AdminRole String[] Roles ($Roles) that may publish views as shared views and delete shared views (with -TemplateStore, or -OnPublishTemplate), and that see the admin panel under the report (the view as JSON, the columns and their types, timings).
-UserName String The signed-in user the page shows views for. Default: $User of the page. Pass $User when the call runs in a script block or function defined in the app script, which does not see it (measured on PSU 2026.2.5 and 2026.3.4). The event handlers use $User of the event.
-Roles String[] The roles of the user, for -AdminRole. Default: $Roles of the page; pass $Roles where -UserName has to be passed.
-SourceId String The id of the data the report shows, written into view files and links (pivotkit asks before it loads a view made for another id). Default: -Id, or the key the module derives without one.
-SourceName String The name of that data for people (in view files and the load check). Default: -Label.
-SchemaUrl String The $schema of the view files the report writes: pivotkit's published schema by default, an https address of your own copy, or '' to leave it out. Loading never depends on it.
-FieldDefaults IDictionary Per field name, what the report knows about the field: @{ LeadHours = @{ Agg = 'average'; Format = 'number:1'; Label = 'Lead time (h)'; Description = 'Hours from created to resolved'; Href = 'https://wiki.example.org/lead-time' }; Priority = @{ Order = 'Low', 'Normal', 'High' } }. Agg and Format: what the field gets when the reader puts it into Values (format names: number, number:2, integer, percent, percent:1, currency:EUR, compact, bytes, duration:s, duration:h, date, datetime, time); DrillFormat: the format of its values in the drill-down (text shows an id as it is); Label: the name shown for the field everywhere (views keep the field name; at most 120 characters); Description: plain text behind an "i" next to the field, in its menu and on its headers (at most 1000 characters); Href: an https link shown as "Learn more" with the description; Order: the field's own order of items on Rows and Columns; Type: string, number, date or boolean, the type its column is read as. Checked on the server: text only, https links only, sizes capped.
-FieldDescriptions IDictionary A description per field name, e.g. from SQL Server column comments (Get-UDPivotSqlColumnDescription): @{ LeadHours = 'Hours from created to resolved' }. A Description in -FieldDefaults wins; empty values, $null and DBNull are left out.
-Schema Object A JSON Schema of a row, or an OpenAPI 3 / Swagger 2 document with -SchemaName: a hashtable or object, JSON text, a file path, or an https URL (fetched on the server with a timeout of 15 seconds, at most 1 MB, kept 10 minutes per runspace; the browser never fetches it). The report reads titles (labels), descriptions, externalDocs links (https), types and enums (orders) of the row's properties with pivotkit-core's fieldDefaultsFromSchema; -FieldDefaults and -FieldDescriptions win over it. At most 1 MB and 64 levels.
-SchemaName String The schema of a row in an OpenAPI document: a name in components.schemas (definitions in Swagger 2) or a local reference such as #/components/schemas/Ticket.
-ChartOptions Object Plain JSON merged over the chart's Apache ECharts option (a hashtable or JSON text, at most 64 KB), e.g. @{ legend = @{ top = 0 }; grid = @{ left = 80 } }; it wins over the view's chart settings. pivotkit leaves out options that are markup or addresses (formatter strings, rich, link, image).
-Tips String[] The tips above the result: On (default), Off (none, and no switch in Options), or the ids of the tips allowed (showAs, chartOverTime, pieSlices, pieColumns, chartDates, chartTrend, chartSeries, textValue, dateUngrouped, manyColumns, afterDrag, values, saveTemplate, menus, cells; the notices filterEmpty, top and chartCapped always show). Dismissed tips are remembered per report in the browser's localStorage.
-FieldInfo String On or Off: the "i" with the field descriptions. Without it the reader switches it in Options.
-ZoneInfo String On or Off: the "i" next to the zone titles that explains each zone. Without it the reader switches it in Options.
-SettingInfo String On or Off: the "i" next to settings that need explaining (totals, Show as, export formats, chart labels). Without it the reader switches it ("Show explanations" in Options, Help).
-FieldList String Open or Collapsed: how the field list starts on a wide report (collapsed: a rail of about 40 pixels). Without it the reader's last choice decides.
-Grow String On or Off: whether the report grows past -Height to keep its result readable (the page scrolls) or stays inside it (the table scrolls). Default: Off, since the report always has a height; a card of a fixed size keeps the whole report.
-Label String The name screen readers hear for the report (its region landmark). Several reports on one page need one name each. Default: "Pivot report".
-Labels Hashtable Single texts of the report in your own words, merged over the language -Locale picked: @{ zones = @{ values = 'Kennzahlen' }; core = @{ grandTotal = 'Summe' } }. The keys are the ones of pivotkit-react's LABELS.
-Locale String Language and formats: numbers, dates and sorting, and the labels (de-* German, others English). Default: en-US. The report never uses the browser's or the server's locale on its own, so a report looks the same for every reader; pass de-DE for German.
-TimeZone String The zone dates with an offset (DateTimeOffset, a DateTime of kind Local or Utc) are shown in, as an IANA name (Europe/Berlin) or UTC. Dates without an offset - what SQL returns for datetime columns - are shown as they are. Default: the server's time zone.
-Theme String Auto (follows the app's light/dark switch, default), Light or Dark.
-Height String Height of the report, e.g. 640px, 80vh or 640 (pixels); the table and the field list scroll inside it. Default: one screen, the window's height minus 180 pixels for PSU's app bar and a page title, between 600 and 1400 pixels, so the whole report is on screen when the page loads; in a window narrower than 640 pixels (a phone) almost the whole window, since the zones stack above the table there.
-FileName String Name of exported files without the extension. Default: pivot.
-NoAddressBar SwitchParameter Keeps the reader's view out of the address bar; the browser tab then keeps it in sessionStorage only (a reload and the light/dark switch still keep it, a copied link does not carry it). By default the view, filter values included, is written into the address (#pivot-=...), so it also ends up in the browser history, in copied links and in the page address PSU sends with its requests. Use it for reports whose filter values are sensitive.
-NoDrillDown SwitchParameter No panel with the source rows when a value is clicked (-OnCellClick still runs).
-ClassName String CSS class of the outer element.
-Style Hashtable CSS styles of the outer element, e.g. @{ maxWidth = '1200px' }.
-OnViewChange Endpoint Runs on the server after the reader changed the view (once the reader paused for 0.6 seconds). $EventData: view (the view as an object), json (the same as JSON text, to store).
-OnCellClick Endpoint Runs on the server when the reader clicks a value or a chart point. $EventData: row, col (the key paths), rowFields, colFields, filter (one @{ field; value } per level, rows first), valueField, value, text (as shown), count (source rows behind the value) and rows (the first 100 of them).
-OnSaveTemplate Endpoint Shows Save as (and Save on a loaded view of the reader's own) in the Views menu and runs when the reader saves. $EventData: name, view, json, scope (user). Save and a confirmed Save as send a name the reader's views already have: replace that view (an upsert by name, the same characters in the same case), never add a second one. The template appears in the menu (deletable) once the script block finished without an error; throw, or return @{ error = 'message' }, to refuse - the reader sees the message.
-OnDeleteTemplate Endpoint Runs when the reader deletes a deletable template (after confirming in the menu). $EventData: name, scope (user or shared). Throw, or return @{ error = 'message' }, to refuse.
-OnPublishTemplate Endpoint With -AdminRole: "Publish as shared view" on the reader's own views and Save on a shared view, for readers with one of the roles. $EventData: name, view, json. A name the shared views have replaces that view (an upsert by name). Check $Roles in it again: the browser only hides the button.

New-UDPivotReportPlaceholder

A placeholder in the pivot report's own look, for New-UDDynamic -LoadingComponent: it shows the report's frame while the server builds the data.

PSU renders a component only once its properties have arrived, and the report's properties hold all of its rows: with thousands of rows the page stays empty until the server has converted and sent them. Put the report into New-UDDynamic and this placeholder into its -LoadingComponent:

New-UDDynamic `-Id` 'tickets-report' `-LoadingComponent` {
    New-UDPivotReportPlaceholder `-Height` 640px
} `-Content` {
    New-UDPivotReport `-Id` 'tickets' `-Data` $tickets `-Height` 640px
}

The placeholder comes with the page and shows pivotkit's own skeleton of the report: the field list, the toolbar, the zones and table rows as grey bars, in the report's colours (light, dark, a corporate design from the app's stylesheet); the bars pulse unless the reader asked for reduced motion. Screen readers hear "Loading the report". It also makes the browser load the module's code at once, while the server is still working on the data.

Give it the -Height, -Theme, -Locale and -Label of the report, so nothing moves when the report replaces it.

Parameter Type Description
-Id String Component id. Default: a new GUID.
-Height String Height, as -Height of New-UDPivotReport (e.g. 640px, 80vh or 640). Default: the report's default height.
-Theme String Auto (follows the app's light/dark switch, default), Light or Dark.
-Locale String The language of the text screen readers hear: German for de-*, English otherwise. Default: en-US.
-Label String The name screen readers hear for it, as -Label of the report.
-ClassName String CSS class of the outer element.
-Style Hashtable CSS styles of the outer element, e.g. @{ maxWidth = '1200px' }.

ConvertFrom-UDPivotView

Checks a pivot view (a report layout) and returns it as a clean object or as compact JSON.

A view is the report as JSON: the fields on Rows, Columns, Values and Filters, sorting, totals, the chart. Views come from the browser ($EventData of -OnViewChange and -OnSaveTemplate), from files or from a database, so treat them as untrusted input: this function is the check before a view is stored or used.

It accepts a JSON string, a hashtable or a PSCustomObject. The view goes through one round trip ConvertTo-Json/ConvertFrom-Json (nothing is evaluated) and must be a JSON object of at most -MaxLength characters and at most eight levels deep. Only the keys of a pivotkit view are kept (version, rows, cols, values, filters, derived, sort, totals, collapsed, display, chart, formatting); rows and cols must be lists of at most 64 field names, values, filters, derived and sort lists of at most 64 objects, display "table" or "chart". Anything else throws an error that says what is wrong. The report itself checks every field name and setting against the data again (pivotkit-core's normalize) and drops what does not fit.

Parameter Type Description
-InputObject (required) Object The view: a JSON string, a hashtable or a PSCustomObject (e.g. $EventData.view).
-MaxLength Int32 The longest view accepted, in characters of compact JSON. Default: 65536.
-AsJson SwitchParameter Return the view as compact JSON (for a file or a database column) instead of an object.

ConvertFrom-UDPivotViewFile

Reads a pivotkit view file (or a saved view { name, view }) and returns its name, description, source and checked view.

A view file is the JSON pivotkit's Views menu downloads (Download view, Copy view as JSON) and a template store keeps: format "pivotkit-view", formatVersion 1, name, description, source and the view. This function reads one as untrusted input: at most 1,000,000 characters and 16 levels, parsed without evaluating anything; a newer formatVersion or view version is refused (saving it again would lose what the newer version added); the name becomes plain text of 1 to 120 characters; the view goes through ConvertFrom-UDPivotView. An object { name, view } (a saved view as an app keeps it) is read as well; a bare view needs -Name.

Parameter Type Description
-InputObject (required) Object The view file: JSON text, a hashtable or an object.
-Name String The name of a view file that has none (a bare view), such as the file's name.

ConvertTo-UDPivotViewFile

A view as a pivotkit view file: the JSON pivotkit's Views menu loads and a template store keeps.

Checks the view with ConvertFrom-UDPivotView and writes the envelope in pivotkit's key order ($schema, format, formatVersion, name, description, createdAt, generator, source, extensions, view) with a two-space indent and a trailing newline.

Parameter Type Description
-View (required) Object The view (JSON text, a hashtable or an object).
-Name (required) String The view's name (1 to 120 characters of plain text).
-Description String More about it, at most 2000 characters.
-SourceId String The id of the data the view was made for (New-UDPivotReport -SourceId, default its -Id).
-SourceName String The name of that data, for people.
-SchemaUrl String The $schema of the file: pivotkit's schema by default, your own copy, or '' to leave it out.
-CreatedAt Nullable1` When it was written (UTC). Without it the file is the same bytes for the same view.

New-UDPivotFileTemplateStore

A template store that keeps the readers' views as view files in a folder on the server.

For New-UDPivotReport -TemplateStore. Every signed-in reader saves views under "My views" and sees them on every device; views in the shared folder are listed for everyone under "Shared views", and only readers with a role of New-UDPivotReport -AdminRole publish or delete them.

Layout below -Path: users// holds a reader's own views, shared/ the shared ones, each view a pivotkit view file -.pivotkit.json (the files Download view in the Views menu writes; shared/ also works as a -TemplatePath). Writes go to a new file that then replaces the old one, under a lock per folder, so two saves at the same moment never leave half a file or lose the count. -MaxUserViews and -MaxSharedViews cap the number of views per folder.

Without -Path the store lies next to the PSU repository ($Repository), never inside it: a repository synced with git would pick the files up. On several PSU nodes (high availability) a local folder is per node: use a shared folder, or a store on a database (New-UDPivotTemplateStore).

Parameter Type Description
-Path String The folder. Default: pivot-views next to the repository folder ($Repository of the app, else $env:Data__RepositoryPath).
-MaxUserViews Int32 The most views a reader keeps. Default: 50.
-MaxSharedViews Int32 The most shared views. Default: 200.

New-UDPivotTemplateStore

A template store on your own storage (a database, Valkey or Redis, S3): you write how a view is stored, the module does the rest.

For New-UDPivotReport -TemplateStore. The module decides who may do what (the signed-in user, -AdminRole for shared views, checked on the server), checks every name and view, applies the limits and writes the view file; the script blocks only store and load. Each gets one argument, $Request:

  • Get: Scope ('user' or 'shared'), User (the user name; $null for shared), UserKey (a hash of the user name, safe in a key or file name). Return the stored views: view file texts (the Json of a save), objects with Json and FileName (where it is stored), or objects with Name and View. The module checks each one again.
  • Save: Scope, User, UserKey, Name (checked), FileName, Key ('users//' or 'shared/'), Json (the view file to store) and View (the checked view). Store it under FileName, replacing what is there: for a name the scope has (the same characters in the same case, as pivotkit compares names) the module passes the FileName of that view, so a save replaces it; for a new name -.pivotkit.json that no stored view has.
  • Delete: Scope, User, UserKey, Name, FileName, Key.
  • Publish (optional): as Save with Scope 'shared' and User the publisher. Without it, publishing calls Save with Scope 'shared'.

Throw to refuse: the reader sees the message. The script blocks run in the runspace of the app script that defined them and do not see $User or $Roles: use $Request. PSU runs event handlers in runspaces of their own, so a script block needs every module and variable it uses (Import-Module inside it).

Parameter Type Description
-Get (required) ScriptBlock Returns the views of one scope (and user).
-Save (required) ScriptBlock Stores one view.
-Delete (required) ScriptBlock Removes one view.
-Publish ScriptBlock Stores a shared view, when that differs from Save with Scope 'shared'.
-MaxUserViews Int32 The most views a reader keeps. Default: 50.
-MaxSharedViews Int32 The most shared views. Default: 200.

Invoke-UDPivotTemplateRequest

Saves, publishes or deletes a view for the report's event handlers; decides on the server who may do it.

New-UDPivotReport -TemplateStore registers event handlers that call this function with the $EventData of the report and the $User and $Roles PSU sets for the event. A reader saves and deletes their own views; publishing and deleting shared views needs a role of -AdminRole, checked here with the event's $Roles - never with anything the browser sends. Returns nothing on success, @{ error = '...' } when it refuses (the report shows the text).

Parameter Type Description
-Key (required) String The key of the report's store (Register-UDPivotTemplateStore).
-Action (required) String Save, Publish or Delete.
-EventData Object The report's $EventData: name, view, scope.
-UserName String $User of the event.
-Roles String[] $Roles of the event.

Get-UDPivotSqlColumnDescription

The column descriptions of a SQL Server table or view (extended property MS_Description), as the hashtable -FieldDescriptions of New-UDPivotReport takes.

Reads sys.extended_properties for the columns of one table or view (class 1, major_id the object, minor_id the column) with the property name MS_Description - what SQL Server Management Studio writes as a column's Description - and returns column name to text, in column order. Columns without a description are left out.

Pass an open connection (-Connection: System.Data.SqlClient, Microsoft.Data.SqlClient or any ADO.NET connection to SQL Server; it stays open) or a connection string (-ConnectionString: the function opens and closes a connection with Microsoft.Data.SqlClient when that is loaded, for example by the SqlServer module, else with System.Data.SqlClient, which PowerShell 7 ships). The table name goes to SQL Server as a parameter of OBJECT_ID(), never into the query text. The account sees only the descriptions of objects it has permissions on; an unknown table gives an empty result.

Parameter Type Description
-Connection (required) IDbConnection An open ADO.NET connection to the database that holds the table.
-ConnectionString (required) String A connection string to the database that holds the table.
-Table (required) String The table or view, as OBJECT_ID() takes it: dbo.Tickets, [sales].[Order Lines] or Tickets (the user's default schema).
-PropertyName String The extended property to read. Default: MS_Description.
-TimeoutSec Int32 Command timeout in seconds. Default: 30.