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. The part that needs extra attention is deployment: the automatic Azure Static Web Apps build does not know about your custom PowerShell interpreter.
This article shows how to register .ps1 data loaders, build the site in GitHub
Actions where PowerShell is available, and ask Azure Static Web Apps to deploy the
already-generated files.
How Observable data loaders work
Observable Framework is a static site generator for data apps, dashboards, and reports. A page can load a CSV file like this:
| |
If movies.csv does not exist, Framework looks for a data loader with a double
extension, such as movies.csv.py or movies.csv.js. It runs the loader during the
build, saves its standard output as a static snapshot, and makes that snapshot
available to the page as movies.csv.
Framework supports several interpreters by default and lets us register additional
ones. Add PowerShell to observablehq.config.js:
| |
The pwsh executable must be installed and available on PATH wherever the site is
built.
Create a PowerShell data loader
Create src/movies.csv.ps1:
| |
The script retrieves JSON, selects the columns needed by the page, and writes CSV to
standard output. That last detail is important: standard output becomes the generated
file. When pwsh runs as an external process, PowerShell’s information, warning,
verbose, and debug streams are also written to standard output, so using them can
corrupt the CSV. Write non-fatal diagnostics directly to standard error, for example
with [Console]::Error.WriteLine('message'), and use throw when the loader should
fail.
You can test the loader independently:
| |
Then use it from src/index.md:
| |
Run the normal Framework build:
| |
Framework executes the PowerShell loader, caches its result, and includes the generated CSV in the static output.
Why the default Azure build can fail
Azure Static Web Apps normally checks out the source and invokes its automatic build environment. That works until the application requires an interpreter or native tool that the environment does not provide or configure.
Instead of teaching the automatic builder about every dependency, build the site in
an ordinary GitHub Actions step and deploy only the output directory. This also makes
the failing stage obvious: if a PowerShell loader breaks, the npm run build step
fails before deployment starts.
Keep the Azure configuration in the output
Azure looks for staticwebapp.config.json in the deployed directory. If you keep that
file at the project root, copy it after the Observable build.
For example, these scripts in package.json build the site into dist and copy the
configuration:
| |
The postbuild script runs automatically after npm run build. For a
cross-platform project, replace cp with a small Node.js script.
Build first, then deploy
The relevant part of the GitHub Actions workflow looks like this:
| |
The last four settings are the key:
app_locationpoints directly to the generateddistdirectory;output_locationis empty because no build happens inside the Azure action;skip_app_buildprevents the Azure action from invoking its automatic builder;staticwebapp.config.jsonis already insidedist.
Keep the pull-request close job and deployment token generated for your Static Web App; only replace the build-and-upload portion of the workflow.
The resulting build pipeline
The finished pipeline has a simple division of responsibility:
- GitHub Actions provides Node.js and PowerShell.
- Observable Framework runs
.ps1data loaders and produces static files. - Azure Static Web Apps deploys those files without rebuilding them.
This pattern is not limited to PowerShell. It also works when an Observable project depends on another interpreter, command-line tool, or native library that is easier to control in a dedicated build step.
For more detail, see the Observable Framework documentation for data loaders and custom interpreters, plus the Azure documentation for deploying a prebuilt application.
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
PowerShell Can Put Pictures in Your Terminal with SIXEL
PowerShell normally sends text and objects to a terminal. This experiment sends an image. 1 Out-Sixel -Path ./sixel-demo.svg …
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 moreAnalyze Dependencies with PSQuickGraph and PSGraphView
PowerShell is excellent at collecting objects. The harder question often comes one step later: how are those objects related? …
Read more