Build Vega-Lite HTML Reports with PowerShell
PowerShell is good at acquiring data and turning it into objects. Vega-Lite is good at turning structured data into interactive graphics. A small function is enough to connect the two without adopting a reporting framework or opening a browser from the script.
In this article, we download the Palmer Penguins dataset, clean it with ordinary PowerShell, describe three views as one Vega-Lite specification, and save the finished report as an HTML file.
The key design choice is that Show-VegaLite doesn’t decide what to do with the HTML. It returns the document to the pipeline:
| |
That makes the renderer useful in a console script, scheduled job, CI pipeline, or notebook.
The finished report
The example produces one HTML document containing a bar chart, scatter plot, and box plot.

The charts answer progressively richer questions:
- How many complete observations are available for each species?
- How do bill length and bill depth separate the species?
- How different are the body-mass distributions?
The saved report remains interactive. Vega-Embed provides tooltips and an action menu that can export individual views.
Load and shape the data
The simplified Palmer Penguins dataset has 344 rows and eight columns. It contains categories, measurements, missing values, and several visible relationships, which makes it a useful alternative to the classic Iris dataset. The project publishes the data under CC0 and documents the original Palmer Station LTER sources.
PowerShell can download the CSV directly:
| |
The explicit casts matter. ConvertFrom-Csv initially creates strings, while Vega-Lite should receive JSON numbers for quantitative fields. Removing incomplete records keeps this example focused. A production report could retain them and add a separate data-quality summary.
Describe several charts in one specification
Vega-Lite specifications are JSON documents. PowerShell ordered hashtables and arrays let us construct the same structure while keeping the data as objects until the final serialization step.
The top-level data property makes the cleaned data available to every view. vconcat places the count chart above an hconcat containing the scatter and box plots:
| |
This is still only data. No chart process has started, and PowerShell hasn’t emitted HTML yet.
Return HTML instead of taking control
Show-VegaLite performs four operations:
- Serialize the specification with enough JSON depth for nested encodings.
- Encode that JSON as UTF-8 Base64 to avoid quoting and
</script>problems inside the page. - Create a small HTML document that loads pinned Vega, Vega-Lite, and Vega-Embed versions.
- Return the document as a string.
| |
The function doesn’t call Set-Content, Out-File, Start-Process, or a notebook-specific display command. That separation lets the caller choose the destination.
Save the report
Pipe the specification through the renderer and save the returned string:
| |
The resulting file contains the selected data and complete Vega-Lite specification. You can attach it to a ticket, publish it as a build artifact, copy it to static hosting, or open it locally.
It isn’t completely offline: the HTML contains the data and chart definition, but it loads the JavaScript runtimes from jsDelivr. A fully offline variant can download those runtime files and reference local copies, at the cost of shipping several additional assets.
Reuse the same output elsewhere
Returning HTML to the pipeline leaves room for other destinations. For example, a host that supports rich MIME output can render the same document directly:
| |
The boundary stays simple: PowerShell prepares objects, Vega-Lite describes the visualization, and the last command decides whether the result becomes a file, build artifact, web page, or interactive cell.
References
About the Author
Andrey
Developer platforms, PowerShell, Azure, and observable systems
I am a hands-on software architect with more than 20 years of experience building developer platforms, delivery automation, and production infrastructure. I work primarily with PowerShell, C#/.NET, and Azure, turning infrastructure complexity into application-centric self-service workflows using CI/CD, GitOps, Kubernetes, infrastructure as code, and observability.
I build PowerShell tools and write about Azure automation, graph-based infrastructure analysis, messaging, and data visualization. My open-source projects include PSQuickGraph, PSGraphView, ipmgmt, and pubs.
Related Articles
Run PowerShell Data Loaders on Azure Static Web Apps
Observable Framework can run PowerShell scripts during a build and expose their output to interactive pages as static data. …
Read moreReordering an Unordered Azure Service Bus Stream with PowerShell
Azure Service Bus sessions are the natural choice when a consumer must process related messages in order. But what if the …
Read moreExplore Micrograd with Verso and PowerShell
Verso is an open-source interactive notebook platform and embeddable .NET execution engine. Its language kernels include …
Read more