Learn how to separate UI and data in PowerShell Universal using Apps and Endpoints to build reusable dashboards, modular web services, and cleaner automation workflows.
Read the full article
Hello,
Thanks for this blog post.
Is it a better approach to make APIs or to use Scripts for the data part of an App ?
Best regards,
Hello,
Thanks for reading, and good question.
Both have a place, because they solve different problems.
For the data an app displays, an endpoint (API) is usually the better fit.
For the actions an app triggers, a script is usually the better fit.
When to use an endpoint (API)
An endpoint answers a request and returns data, and PowerShell Universal stores no job record for it.
That suits tables, dropdowns and pages that refresh often, like the service list in the blog post.
Anything that can call a URL can also use the same data, including other apps, scripts and outside tools.
That reuse is the main benefit the article describes.
Things to watch:
Turn authentication back on before going to production, and call the endpoint with an app token. The blog turned it off only to keep the example simple.
The app reaches the endpoint over HTTP, so avoid hardcoding http://localhost:5000 if you plan to move servers or run several nodes.
When to use a script
Every time a script runs, PowerShell Universal creates a job for it.
That gives you things an endpoint does not:
a job history with the output and logs of each run,
running as another account through secret variables, which lets regular users run privileged tasks without knowing the credentials (this doesn't work when the script uses the Integrated environment),
choosing the computer or queue the job runs on, and scheduling,
progress and Read-Host prompts shown inside the app when you call it with -Integrated -Wait.
The trade-off is overhead.
If a table that refreshes on every page load is fed by a script, each refresh creates a job.
The script's job history (100 jobs by default) then fills up with those refreshes.
From an app, the documented pattern for a button that runs a script looks like this:
New-UDButton -Text 'Restart service' -OnClick {
Invoke-PSUScript -Name 'Restart-CockpitService.ps1' -Parameters @{ ServiceName = 'Spooler' } -Integrated -Wait
} -ShowLoading
A third option: a module
If your main goal is to keep the data logic out of the UI, you can also put it in a custom module (Manage > Modules > Custom Modules).
The app calls the function directly, with no HTTP round trip.
You can still publish the same function as an endpoint for outside callers:
# Cockpit.psm1
function Get-CockpitService {
# service / process / service group logic from the blog post
}
# Endpoint for external callers, same function
New-PSUEndpoint -Url '/get-service' -Module 'Cockpit' -Command 'Get-CockpitService'
# In the app
New-UDTable -Data (Get-CockpitService)
The logic lives in one place, and for each caller you choose how to expose it.
Rule of thumb
Read-only data shown in the app: an endpoint, or a module function if only the app needs it.
Actions, long-running or privileged work, or anything that needs an audit trail: a script.
Many apps use both: endpoints or modules to display data, and scripts behind the buttons.
References:
Endpoints: https://docs.devolutions.net/powershell-universal/api/endpoints
Scripts: https://docs.devolutions.net/powershell-universal/automation/scripts
Jobs (calling scripts from apps): https://docs.devolutions.net/powershell-universal/automation/jobs
Modules: https://docs.devolutions.net/powershell-universal/platform/modules
Best regards,
Patrick Ouimet