If you’re a fan of PowerShell and need to build functional yet great-looking web applications using your PowerShell skills, PowerShell Universal may be the solution for you.
PowerShell Universal is a web-based cross-platform product for developing tools to help manage your organization using PowerShell. PowerShell Universal offers three main features:
- REST APIs to run scripts from any platform that can communicate over HTTP(s).
- Automation
- User Interfaces
It’s a one-stop shop for your automation needs! Sound interesting? If so, let’s dive in and take PowerShell Universal for a spin.
IronMan Software has sponsored this post. If you like what you see, be sure to check out the PowerShell Universal website for more details!
Installing and Launching PowerShell Universal
If you think that PowerShell (and PowerShell Universal) is just for Windows, you’re sadly mistaken. PowerShell Universal has a ton of installation methods that impressed me immediately. You can install PowerShell Universal on Windows, macOS, and Linux.
Do you have a preferred method to install software? PowerShell Universal probably has you covered. You can install PowerShell Universal via MSI, ZIP, Chocolatey, host on Internet Information Server (IIS), or even download and run it in a Docker container.
I chose to install PowerShell Universal on a Windows Server 2016 server using the MSI installation option for Windows for this review as I didn’t need to run it in any specific scenario.
Once installed (if you’re on the same machine as I was), launch PowerShell Universal by navigating to http://localhost:5000 in your web browser. You can log in with the admin user and set any password after the initial install.
Don’t worry. You have numerous options for securing access you’ll see later in this review.
After you log on, you are presented with a user-friendly interface. You’ll see that much of the functionality is grouped on the left-hand sidebar, with the three main components coming first; APIs, Automation, and User Interfaces.
Don’t Forget to Install your License
Although you’re not required to pay for and install a license, you’re missing out on many great features. PowerShell Universal provides a simple licensing plan per server you should check out to ensure you’re receiving all the features this product has to offer.
I love it when products provide free options like PowerShell Universal. You can evaluate and get to grips with how the product might benefit you before purchasing.
Installing a license is simple; just upload a text file.
Creating an API
PowerShell Universal enables you to create an API to execute your PowerShell scripts. No more having to figure out how to connect to a remote machine to run PowerShell scripts! You can now make it happen with a simple REST call.
I created a simple REST API and found it relatively easy to get started using a single PowerShell command to get some output.
Creating an endpoint is straightforward. I added the URL I’d like to use and told PowerShell Universal to run the Get-ComputerInfo
command.
You’ll see below where you can provide the PowerShell to run in a basic editor. Here is where you can paste or create your script. The editor is basic, but it does do the job.
Now the only thing left to do is call the endpoint it creates, and voila! PowerShell Universal returns the same output via JSON as you’d see if running the script locally.
Creating Scripts
Another feature that comes with PowerShell Universal is Automation. Automation generally refers to providing an interface to create scripts and an execution engine to invoke those scripts.
When creating a script within PowerShell Universal, you can assign it many different properties.
- A description to describe the purpose of the script when looking for it within PowerShell Universal.
- A timeout to ensure the script doesn’t run forever.
- A retry limit to attempt to execute the script again if it should fail.
- The number of executions PowerShell Universal will save the output for. This option is excellent for troubleshooting.
- An environment to run the script to run in.
An environment is a specific execution space your script executes in. An environment could be using a particular version of PowerShell, an area where specific modules are available and where you can specify certain variables and secrets available to the script, as you’ll see later.
- A specific user to run the script under.
When scheduling a script (shown later), you can create variables available to your scripts they can reference when necessary.
- Tags to quickly find the script in PowerShell Universal later.
- A way to disable invoking the script manually.
You’ll probably create the script in another editor like Visual Studio Code and paste it into the PowerShell Universal editor.
If you want to create scripts from within Visual Studio Code and upload directly to PowerShell Universal, PowerShell Universal provides a VS Code extension!
The output shown below is from running the Get-Service
command.
Scheduling a Script
Running scripts on a scheduled basis in Windows usually involves using Task Scheduler or another third-party product. PowerShell Universal has a built-in scheduler for running tasks to keep it as your primary execution engine.
Setting up a scheduled script is pretty easy such as using a CRON expression. PowerShell Universal provides a handy interface when creating the scheduled job. You also get a history of logs to review the script execution, unlike the task scheduler.
Working with Variables and Secrets
Within a PowerShell Universal environment, you can define specific variables only available within that environment. I liked the ability to create a secret variable that is an encrypted value such as an API key or username and password.
Secret variables are currently only available in Windows, where the values are stored outside of PowerShell Universal in the Windows Credential Manager on the PowerShell Universal host.
Building a User Interface
If you were a past user of PowerShell Universal Dashboard, you might find the Interfaces feature of PowerShell Universal familiar. PowerShell Universal Dashboard has been integrated into PowerShell Universal.
PowerShell Universal Dashboard’s dashboard technology is now integrated into PowerShell Universal that includes the ability to build interactive dashboards, user interfaces, integrate your PowerShell scripts and use data from any internal or external source.
Creating a page
The Interfaces feature starts with a single page. We’ve all probably wrestled with creating web pages and laying out elements using code at some point to build a dashboard or web page. The Pages feature within PowerShell Universal lets you create web pages by using drag and drop components. No coding required!
The elements on pages can easily interact with your scripts and REST API!
To demonstrate, I created a simple page by creating a text box, a table to display the output of an API, and an image. I was able to make this page in just a few minutes. I liked how fluid it was when moving boxes around the screen.
Displaying Data in a Chart from an API
On any page, let’s say you need to display a chart. This chart needs to show a few widgets with a couple of attributes; Name and Value. To accomplish this, I created an endpoint called widgets, populated with the following PowerShell hashtable, which converts to JSON so that PowerShell Universal could interpret the data correctly.
I added a line chart on my web page, selected the widgets API, and then positioned the chart on the web page. This, again, is a straightforward procedure to carry out with great results using minimal effort.
Displaying Data in a Table from an API
Maybe you also need to show the simple widget dataset created above in a table. Using the same API, you can represent the information in a table on a web page. You’ll see below that using the Toolbox feature; you have a few different options; Table is one of them.
Selecting Table brings up a table where you can select the API. PowerShell Universal then invokes that API and populates the table as shown below.
Once you have the table created, I confirmed that the table automatically displays the new data by adding to the data returned by the API.
Invoking a Script from a Button
The Interfaces feature can create many elements; one common element is the button. For example, perhaps you need to allow a junior admin to run a script under a different account than what the page is running under. To do this, you can create a button that runs this script.
Maybe you have a script that checks for running services on a server. You create the script in PowerShell Universal, make the secret non-admin credential and create a page with a button, as shown below.
When the junior admin clicks the button, PowerShell Universal invokes the script behind it as a non-admin account and sees the output below.
Creating a Dynamic Page
Dynamic pages are a more advanced feature in the Interfaces feature but are powerful. A Dynamic page retrieves a specific page based on the URL navigates to. This page then can access variables designated for that page and change depending on the value of those variables.
For example, I like cats, so we will use a couple of cat images to show how this works. I want to change the cat image displayed on a page depending on what URL is used to reach it. To do that, I’d create a page with a URL prefaced with custom/:
, as shown below.
When using the custom/:
preface followed by a name, that’s creating a dynamic URL variable.
When the dynamic page is created, I’ll create an image on the page using the $variable
variable, which references the URL provided.
You’ll see below that by just changing the URL, my cat page can now display different cat images! If cats aren’t your thing, imagine creating a page to view different server information just by changing the URL.
I liked this feature and can see many uses; it did take me time to get my head around the concept, and I would like to see some more examples or documentation on this subject.
Securing PowerShell Universal
Out of the box, you can log in as an admin with any password. But PowerShell Universal supports many authentication methods. These can all be configured within the PowerShell Universal console, for example, authenticating users via Azure AD authentication.
Enabling Azure AD Authentication
Azure AD authentication, in particular, requires registering an Azure AD application. The docs are pretty good about demonstrating this setup, but I feel a good step-by-step might be of value for people with less experience setting up authentication in Azure.
The following shows the settings that need to be updated from your registered application within Azure AD. The settings that you see below were taken from the application registration setup within Azure.
I had some trouble setting up PowerShell Universal using HTTPS, but they provide a hosting guide that helped. If you are evaluating this product though, you can use self-signed certificates; a self-signed certificate should not be used in a production environment.
Limiting Access Based on Azure AD Group Membership
Once you’ve set up Azure AD authentication, all of your Azure users can log in as admin. To create a better role-based access control (RBAC) solution, you can limit access based on the group.
For example, below, you can see I have two Azure AD groups. If I chose to, I could then map these groups to PowerShell Universal roles (Admin, Reader, Execute, and Operator) or even define my roles within PowerShell Universal. Then these roles can be validated when a user logons.
Conclusion
PowerShell Universal is a powerful, feature-laden product that’s worth trying out. It’s intuitive, but when I needed help, I found plenty of answers in the documentation.
If you plan on trying it out, I’d highly encourage watching some of the YouTube videos that PowerShell Universal’s creator, Adam Driscoll, has published. They do a great job at covering each feature and how you can use them.