# Table of Contents
- [System Events | PowerShell Universal](#system-events-powershell-universal)
- [Queues | PowerShell Universal](#queues-powershell-universal)
- [Schedules | PowerShell Universal](#schedules-powershell-universal)
- [Jobs | PowerShell Universal](#jobs-powershell-universal)
- [Terminals | PowerShell Universal](#terminals-powershell-universal)
- [About | PowerShell Universal](#about-powershell-universal)
- [Dashboards | PowerShell Universal](#dashboards-powershell-universal)
- [Components | PowerShell Universal](#components-powershell-universal)
- [Dashboards | PowerShell Universal](#dashboards-powershell-universal)
- [Triggers | PowerShell Universal](#triggers-powershell-universal)
- [Examples | PowerShell Universal](#examples-powershell-universal)
- [Error Boundary | PowerShell Universal](#error-boundary-powershell-universal)
- [HTML | PowerShell Universal](#html-powershell-universal)
- [Feedback | PowerShell Universal](#feedback-powershell-universal)
- [Data Display | PowerShell Universal](#data-display-powershell-universal)
- [Dynamic Regions | PowerShell Universal](#dynamic-regions-powershell-universal)
- [Data Visualization | PowerShell Universal](#data-visualization-powershell-universal)
- [Custom Components | PowerShell Universal](#custom-components-powershell-universal)
- [Surfaces | PowerShell Universal](#surfaces-powershell-universal)
- [Element | PowerShell Universal](#element-powershell-universal)
- [Navigation | PowerShell Universal](#navigation-powershell-universal)
- [Utilities | PowerShell Universal](#utilities-powershell-universal)
- [Inputs | PowerShell Universal](#inputs-powershell-universal)
- [Layout | PowerShell Universal](#layout-powershell-universal)
- [Sessions | PowerShell Universal](#sessions-powershell-universal)
- [Pages | PowerShell Universal](#pages-powershell-universal)
- [Styles | PowerShell Universal](#styles-powershell-universal)
- [Marketplace | PowerShell Universal](#marketplace-powershell-universal)
- [Custom Variable Scopes | PowerShell Universal](#custom-variable-scopes-powershell-universal)
- [Alerts | PowerShell Universal](#alerts-powershell-universal)
- [Scheduled Endpoints | PowerShell Universal](#scheduled-endpoints-powershell-universal)
- [Role Based Access | PowerShell Universal](#role-based-access-powershell-universal)
- [Cascading Style Sheets | PowerShell Universal](#cascading-style-sheets-powershell-universal)
- [Button | PowerShell Universal](#button-powershell-universal)
- [Migrating From Universal Dashboard 2.9 | PowerShell Universal](#migrating-from-universal-dashboard-2-9-powershell-universal)
- [Card | PowerShell Universal](#card-powershell-universal)
- [iFrame | PowerShell Universal](#iframe-powershell-universal)
- [Image | PowerShell Universal](#image-powershell-universal)
- [Interaction | PowerShell Universal](#interaction-powershell-universal)
- [Bar Chart | PowerShell Universal](#bar-chart-powershell-universal)
- [Pages | PowerShell Universal](#pages-powershell-universal)
- [Liquid Chart | PowerShell Universal](#liquid-chart-powershell-universal)
- [Line Chart | PowerShell Universal](#line-chart-powershell-universal)
- [Paragraph | PowerShell Universal](#paragraph-powershell-universal)
- [Themes | PowerShell Universal](#themes-powershell-universal)
- [About Desktop Mode | PowerShell Universal](#about-desktop-mode-powershell-universal)
- [Statistic | PowerShell Universal](#statistic-powershell-universal)
- [File Associations | PowerShell Universal](#file-associations-powershell-universal)
- [Form | PowerShell Universal](#form-powershell-universal)
- [Table | PowerShell Universal](#table-powershell-universal)
- [Variables | PowerShell Universal](#variables-powershell-universal)
- [Hotkeys | PowerShell Universal](#hotkeys-powershell-universal)
- [Pages | PowerShell Universal](#pages-powershell-universal)
- [Protocol Handlers | PowerShell Universal](#protocol-handlers-powershell-universal)
- [Modules | PowerShell Universal](#modules-powershell-universal)
- [Cache | PowerShell Universal](#cache-powershell-universal)
- [Notifications | PowerShell Universal](#notifications-powershell-universal)
- [Monitoring | PowerShell Universal](#monitoring-powershell-universal)
- [Published Folders | PowerShell Universal](#published-folders-powershell-universal)
- [Templates | PowerShell Universal](#templates-powershell-universal)
- [Translations | PowerShell Universal](#translations-powershell-universal)
- [User Sessions | PowerShell Universal](#user-sessions-powershell-universal)
- [Variables | PowerShell Universal](#variables-powershell-universal)
- [About | PowerShell Universal](#about-powershell-universal)
- [API | PowerShell Universal](#api-powershell-universal)
- [Command Line Options | PowerShell Universal](#command-line-options-powershell-universal)
- [Feature Flags | PowerShell Universal](#feature-flags-powershell-universal)
- [Environments | PowerShell Universal](#environments-powershell-universal)
- [Hosting | PowerShell Universal](#hosting-powershell-universal)
- [Git | PowerShell Universal](#git-powershell-universal)
- [High Availability | PowerShell Universal](#high-availability-powershell-universal)
- [Azure | PowerShell Universal](#azure-powershell-universal)
- [IIS | PowerShell Universal](#iis-powershell-universal)
- [Login Page | PowerShell Universal](#login-page-powershell-universal)
- [Management API | PowerShell Universal](#management-api-powershell-universal)
- [Persistence | PowerShell Universal](#persistence-powershell-universal)
- [App Settings | PowerShell Universal](#app-settings-powershell-universal)
- [Security | PowerShell Universal](#security-powershell-universal)
- [Access Controls | PowerShell Universal](#access-controls-powershell-universal)
- [Best Practices | PowerShell Universal](#best-practices-powershell-universal)
- [App Tokens | PowerShell Universal](#app-tokens-powershell-universal)
- [Client Certificate | PowerShell Universal](#client-certificate-powershell-universal)
- [OpenID Connect | PowerShell Universal](#openid-connect-powershell-universal)
- [PowerShell Protect | PowerShell Universal](#powershell-protect-powershell-universal)
- [SAML2 | PowerShell Universal](#saml2-powershell-universal)
- [Running as a Service Account | PowerShell Universal](#running-as-a-service-account-powershell-universal)
- [WS-Federation | PowerShell Universal](#ws-federation-powershell-universal)
- [Repository | PowerShell Universal](#repository-powershell-universal)
- [Best Practices | PowerShell Universal](#best-practices-powershell-universal)
- [Debugging Scripts | PowerShell Universal](#debugging-scripts-powershell-universal)
- [Editor | PowerShell Universal](#editor-powershell-universal)
- [Hangfire | PowerShell Universal](#hangfire-powershell-universal)
- [Logging | PowerShell Universal](#logging-powershell-universal)
- [Profiling | PowerShell Universal](#profiling-powershell-universal)
- [Visual Studio Code Extension | PowerShell Universal](#visual-studio-code-extension-powershell-universal)
- [About | PowerShell Universal](#about-powershell-universal)
- [Extension Changelog | PowerShell Universal](#extension-changelog-powershell-universal)
- [Additional Resources | PowerShell Universal](#additional-resources-powershell-universal)
- [Installation | PowerShell Universal](#installation-powershell-universal)
- [Get Started | PowerShell Universal](#get-started-powershell-universal)
- [Docker | PowerShell Universal](#docker-powershell-universal)
- [Upgrading | PowerShell Universal](#upgrading-powershell-universal)
- [System Requirements | PowerShell Universal](#system-requirements-powershell-universal)
- [Licensing | PowerShell Universal](#licensing-powershell-universal)
- [Supported Browsers | PowerShell Universal](#supported-browsers-powershell-universal)
- [Examples | PowerShell Universal](#examples-powershell-universal)
- [Active Directory | PowerShell Universal](#active-directory-powershell-universal)
- [Visual Studio Code Extension | PowerShell Universal](#visual-studio-code-extension-powershell-universal)
- [Hyper-V | PowerShell Universal](#hyper-v-powershell-universal)
- [Custom Status Codes | PowerShell Universal](#custom-status-codes-powershell-universal)
- [APIs | PowerShell Universal](#apis-powershell-universal)
- [Apps | PowerShell Universal](#apps-powershell-universal)
- [Active Directory Tree View | PowerShell Universal](#active-directory-tree-view-powershell-universal)
- [Export-CSV Download | PowerShell Universal](#export-csv-download-powershell-universal)
- [Dynamic Select Dropdown | PowerShell Universal](#dynamic-select-dropdown-powershell-universal)
- [Textbox Length Validation | PowerShell Universal](#textbox-length-validation-powershell-universal)
- [Tree View Font Size | PowerShell Universal](#tree-view-font-size-powershell-universal)
- [SQL Data Grid | PowerShell Universal](#sql-data-grid-powershell-universal)
- [Extension Changelog | PowerShell Universal](#extension-changelog-powershell-universal)
- [What's New in v5? | PowerShell Universal](#what-s-new-in-v5-powershell-universal)
- [Changelog | PowerShell Universal](#changelog-powershell-universal)
- [Video Library | PowerShell Universal](#video-library-powershell-universal)
- [Get Started | PowerShell Universal](#get-started-powershell-universal)
- [Additional Resources | PowerShell Universal](#additional-resources-powershell-universal)
- [Installation | PowerShell Universal](#installation-powershell-universal)
- [Docker | PowerShell Universal](#docker-powershell-universal)
- [Uninstall | PowerShell Universal](#uninstall-powershell-universal)
- [Upgrade | PowerShell Universal](#upgrade-powershell-universal)
- [Downgrade | PowerShell Universal](#downgrade-powershell-universal)
- [Migrate and Restore | PowerShell Universal](#migrate-and-restore-powershell-universal)
- [Licensing | PowerShell Universal](#licensing-powershell-universal)
- [System Requirements | PowerShell Universal](#system-requirements-powershell-universal)
- [Supported Browsers | PowerShell Universal](#supported-browsers-powershell-universal)
- [Release Support Policy | PowerShell Universal](#release-support-policy-powershell-universal)
- [About | PowerShell Universal](#about-powershell-universal)
- [OpenAPI | PowerShell Universal](#openapi-powershell-universal)
- [Event Hubs | PowerShell Universal](#event-hubs-powershell-universal)
- [Endpoints | PowerShell Universal](#endpoints-powershell-universal)
- [Error Handling | PowerShell Universal](#error-handling-powershell-universal)
- [Security | PowerShell Universal](#security-powershell-universal)
- [Rate Limiting | PowerShell Universal](#rate-limiting-powershell-universal)
- [Email Protection | Cloudflare](#email-protection-cloudflare)
---
# System Events | PowerShell Universal

System Events in the Admin Console
System events subscribe to WMI events within Windows and run scripts. You can then take action by running scripts.
[](https://docs.powershelluniversal.com/v3/automation/system-events#defining-a-system-event)
Defining a System Event
-------------------------------------------------------------------------------------------------------------------------
To define a system event, you can use the `New-PSUSystemEvent` cmdlet within the `systemEvents.ps1` file. The following example triggers the `systemEvent.ps1` script when a `pwsh.exe` process is started.
Copy
New-PSUSystemEvent -Script "systemEvent.ps1" -Environment "Default" -Credential "Default" -Type "Create" -Condition "TargetInstance isa `"Win32_Process`" and TargetInstance.Name = `"pwsh.exe`"" -Name "PowerShell Started"
[](https://docs.powershelluniversal.com/v3/automation/system-events#accessing-event-data)
Accessing Event Data
-------------------------------------------------------------------------------------------------------------------
When a script is executed, you will receive a `$TargetInstance` parameter. This contains the WMI object that caused the event to trigger.
Copy
param($TargetInstance)
New-BurntToastNotification -Text "PowerShell Started! $TargetInstance"
[PreviousSchedules](https://docs.powershelluniversal.com/v3/automation/schedules)
[NextTerminals](https://docs.powershelluniversal.com/v3/automation/terminals)
Last updated 3 years ago
---
# Queues | PowerShell Universal
You can assign computers to queues by using application settings. By default, every computer is assigned to the default queue and a queue specific to the computer itself. When you assign a computer to a custom queue, that queue will be available in the admin console and you can use the queue for ad-hoc script execution and schedules.
Queues with no active computers will queue jobs indefinitely.
[](https://docs.powershelluniversal.com/v3/automation/queues#configure-a-queue)
Configure a Queue
------------------------------------------------------------------------------------------------------
To a configure a computer to a specific queue, use the UniversalAutomation \\ Queues setting.
###
[](https://docs.powershelluniversal.com/v3/automation/queues#appsettings.json)
appsettings.json
Assign a machine to a queue using an appsettings.json file.
Copy
"UniversalAutomation": {
"Queues": ["windows7"],
}
###
[](https://docs.powershelluniversal.com/v3/automation/queues#environment-variable)
Environment Variable
Assign a machine to a queue using an environment variable.
Copy
$ENV:UniversalAutomation__Queues = "windows7"
[](https://docs.powershelluniversal.com/v3/automation/queues#using-a-custom-queue)
Using a Custom Queue
------------------------------------------------------------------------------------------------------------
Custom queues will be available within the Computer drop down in the script Run dialog, and trigger, script and schedule properties.
[PreviousTriggers](https://docs.powershelluniversal.com/v3/automation/triggers)
[NextAbout](https://docs.powershelluniversal.com/v3/userinterfaces/about)
Last updated 2 years ago
---
# Schedules | PowerShell Universal
Schedules can be assigned to scripts and allow you to define frequency and other parameters for a script such as run as credentials.
Schedules are stored in the `schedules.ps1` configuration file.
[](https://docs.powershelluniversal.com/v3/automation/schedules#scheduling-a-job)
Scheduling a Job
-------------------------------------------------------------------------------------------------------
To schedule a job, you can do so from the Automation / Schedules page and by clicking the New Schedule button. You can also schedule a script by click the Schedule option from the script's page.
Schedules can be defined based on simple selections like Every Minute or Every Hour or you can define CRON expressions yourself for more configurable schedules. You can also run One Time schedules that run once at a later date.
You can also define which user the scheduled job will run under as well as which PowerShell version to use.

Create a Schedule
###
[](https://docs.powershelluniversal.com/v3/automation/schedules#simple-schedules)
Simple Schedules
Simple schedules are really just helpers for various standard CRON schedules. When you select one, it will define a CRON schedule for your script.

###
[](https://docs.powershelluniversal.com/v3/automation/schedules#cron)
CRON
CRON schedules use CRON expressions to define schedules. PowerShell Universal takes advantage of Chronos. For examples of valid expressions, [click here](https://github.com/HangfireIO/Cronos)
.

###
[](https://docs.powershelluniversal.com/v3/automation/schedules#one-time)
One Time
One time schedules will run once in the future. You can select the time and day of when they will run.

###
[](https://docs.powershelluniversal.com/v3/automation/schedules#continuous)
Continuous
Continuous schedules will run over and over again. You can define a delay between each scheduled job run.

[](https://docs.powershelluniversal.com/v3/automation/schedules#parameters)
Parameters
-------------------------------------------------------------------------------------------
Schedules support setting parameters for scripts. For example, if you have a script that accepts a parameter, you can choose to pass a value to the parameter during the schedule.
Copy
param($UserName)
$UserName
Within the modal for defining the schedule, you will have the option to set the parameter value.

When editing schedules from PowerShell, you can define the parameters on the `New-PSUSchedule` cmdlet. This cmdlet accepts dynamic parameters so that you can pass the values in for your schedule.
Copy
New-PSUSchedule -Script "MyScript.ps1" -Cron '* * * * *' -UserName 'adam'
[](https://docs.powershelluniversal.com/v3/automation/schedules#environments)
Environments
-----------------------------------------------------------------------------------------------
When creating a schedule, you have the option to specify the [environment](https://docs.powershelluniversal.com/v3/config/environments)
for your job to run. By default, it will use the default environment. You can define an environment in the UI by using the Environment drop down. You can define an environment using the `-Environment` parameter in `New-PSUSchedule`.
Copy
New-PSUSchedule -Script "MyScript.ps1" -Cron '* * * * *' -Environment '7.1'
[](https://docs.powershelluniversal.com/v3/automation/schedules#run-as)
Run As
-----------------------------------------------------------------------------------
You can define which user to run the schedule as by using the Run As selector in the UI. The Run As selector contains a list of PSCredential [variables](https://docs.powershelluniversal.com/v3/platform/variables)
you have defined. You will need to define a PSCredential variable before the Run As selector is visible. By default, scheduled jobs will run under the credentials of the user that is running PowerShell Universal.
You can define a Run As user in a script by using the `-Credential` parameter. The value should be the name of the variable that contains your credential.
Copy
New-PSUSchedule -Script "MyScript.ps1" -Cron '* * * * *' -Credential 'MyUser'
[](https://docs.powershelluniversal.com/v3/automation/schedules#computer)
Computer
---------------------------------------------------------------------------------------
You can select the computer or computers to run the schedule on. By default, schedules will run on any available computer. If you select All Computers, the schedule will run on all computers connect to the PSU cluster. If you select a specific computer, the schedule will run on only that computer.
Copy
New-PSUSchedule -Script "MyScript.ps1" -Cron '* * * * *' -Computer 'PSUNODE1'
[](https://docs.powershelluniversal.com/v3/automation/schedules#conditions)
Conditions
-------------------------------------------------------------------------------------------
Conditions can be defined that determine whether a schedule should be run. This is useful if you are using the same repository scripts for multiple environments. Currently, conditions cannot be defined within the admin console. Conditions are passed the current script and schedule as parameters. The condition scriptblock is run within the integrated environment.
The condition needs to return true or false. Below is an example of a condition where the schedule will only run if there is an environment variable named `Slot` that contains the value `production`.
Copy
New-PSUSchedule -Script "MyScript.ps1" -Cron '* * * * *' -Condition {
$ENV:Slot -eq 'production'
}
[](https://docs.powershelluniversal.com/v3/automation/schedules#pausing-schedules)
Pausing Schedules
---------------------------------------------------------------------------------------------------------
You can pause a schedule by setting the Paused property. When a schedule is paused, it will not run. This is useful to stop a schedule from running but not delete it.
[](https://docs.powershelluniversal.com/v3/automation/schedules#time-out)
Time Out
---------------------------------------------------------------------------------------
You can set a time out for scheduled jobs. The time out is the number of minutes before the scheduled job is canceled.
[](https://docs.powershelluniversal.com/v3/automation/schedules#random-delay)
Random Delay
-----------------------------------------------------------------------------------------------
The Random Delay property causes a schedule to start anywhere between 0 and 60 seconds from the scheduled time. This is useful when running many schedules at the same time. For example, if you had 10 schedules that start at midnight, you may want to set a random delay to limit resource contention on the PowerShell Universal service.
[](https://docs.powershelluniversal.com/v3/automation/schedules#api)
API
-----------------------------------------------------------------------------
* [New-PSUSchedule](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUSchedule.txt)
* [Get-PSUSchedule](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUSchedule.txt)
* [Remove-PSUSchedule](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-PSUSchedule.txt)
[PreviousJobs](https://docs.powershelluniversal.com/v3/automation/jobs)
[NextSystem Events](https://docs.powershelluniversal.com/v3/automation/system-events)
Last updated 2 years ago
---
# Jobs | PowerShell Universal
Jobs are the result of running a script. Jobs are retained based on the script and server level settings.
[](https://docs.powershelluniversal.com/v3/automation/jobs#viewing-jobs)
Viewing Jobs
------------------------------------------------------------------------------------------
Jobs can be viewed by clicking the Automation / Jobs page. Click the View button to navigate to the job. Jobs in progress can also been cancelled.

Job Output
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#view-job-output)
View Job Output
Standard PowerShell streams such as information, host, error, warning and verbose are shown within the output pane.

Standard Output
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#view-job-pipeline-output)
View Job Pipeline Output
Storing large amounts of pipeline output can negatively affect performance. You can discard pipeline output by setting the Discard Pipeline setting on scripts.
Pipeline output for jobs is also stored within PowerShell Universal. Any object that is written to the pipeline is stored as CliXml and available for view within the Pipeline Output tab.
You can expand the tree view to see the objects and properties from the pipeline.

Pipeline Output
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#viewing-errors)
Viewing Errors
Any errors written to the error stream will be available on the Error tab within the job page.

Errors
[](https://docs.powershelluniversal.com/v3/automation/jobs#feedback)
Feedback
----------------------------------------------------------------------------------
Some jobs will require feedback. Any script that contains a `Read-Host` call will wait until there is user interaction with that job. The job will be in a Waiting for Feedback state, and you can respond to that feedback by click the Response to Feedback button on the job page.

Waiting for Feedback
To accept a `SecureString` with a password input field, you can use the `-AsSecureString` parameter of `Read-Host`.
[](https://docs.powershelluniversal.com/v3/automation/jobs#invoking-jobs-from-powershell)
Invoking Jobs from PowerShell
----------------------------------------------------------------------------------------------------------------------------
You can use `Invoke-PSUScript` to invoke jobs from the command line. You will need a valid [App Token](https://docs.powershelluniversal.com/v3/config/security#app-tokens)
to do so. Parameters are defined using dynamic parameters on the `Invoke-PSUScript` cmdlet.
Copy
Invoke-PSUScript -Script 'Script1.ps1' -RequiredParameter 'Hello'
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#call-scripts-from-scripts)
Call Scripts from Scripts
You can also call UA scripts from UA scripts. When running a job in UA, you don't need to define an app token or the computer name manually. These will be defined for you. You can just call `Invoke-PSUScript` within your script to start another script. Both jobs will be shown in the UI. If you want to wait for the script to finish, use `Wait-PSUJob`.
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#waiting-for-a-script-to-finished)
Waiting for a Script to Finished
You can use the `Wait-PSUJob` cmdlet to wait for a job to finish. Pipe the return value of `Invoke-PSUScript` to `Wait-UAJob` to wait for the job to complete. `Wait-PSUJob` will wait indefinitely unless the `-Timeout` parameter is specified.
Copy
Invoke-PSUScript -Script 'Script1.ps1' -RequiredParameter 'Hello' | Wait-PSUJob
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#return-pipeline-data)
Return Pipeline Data
You can use the `Get-PSUJobPipelineOutput` cmdlet to return the pipeline output that was produced by a job. This pipeline output will be deserialized objects that were written to the pipeline during the job. You can access this data from where you have access to the PowerShell Universal Management API.
Copy
Get-PSUJobPipelineOutput -JobId 10
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#returning-the-last-jobs-output)
Returning the last job's output
It may be required to return the output from a script's last job run. In order to do this, you will need to use a combination of cmdlets to retrieve the script, the last job's ID and then return the pipeline or host output.
Copy
$Job = Get-PSUScript -Name 'Script.ps1' | Get-PSUJob -OrderDirection Descending -First 1
Get-PSUJobPipelineOutput -Job $Job
Get-PSUJobOutput -Job $Job
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#invoke-a-script-and-wait-for-output)
Invoke a Script and Wait for Output
The following example invokes a script, stores the job object in a `$job` variable, waits for the job to complete and then returns the pipeline and host output.
Copy
Invoke-PSUScript -Script 'Script1.ps1' -RequiredParameter 'Hello' | Tee-Object -Variable job | Wait-PSUJob
$Pipeline = Get-PSUJobPipelineOutput -Job $Job
$HostOutput = Get-PSUJobOutput -Job $Job
# Access the actual string returned by the job
# $HostOutput may be an array
$HostOutput.Data
If you are using PowerShell Universal 2.4 or later, you can use the `-Wait` parameter of `Invoke-PSUScript` to achieve this.
Copy
$Pipeline = Invoke-PSUScript -Script 'Script1.ps1' -RequiredParameter 'Hello' -Wait
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#integrated-mode)
Integrated Mode
The integrated mode allows calling these cmdlets from within PowerShell Universal without an App Token or Computer Name. It uses the internal RPC channel to communicate.
You can set the `-Integrated` parameter to switch to integrated mode. This parameter does not work outside of PowerShell Universal.
Copy
Invoke-PSUScript -Script 'Script.ps1' -Integrated
The following cmdlets support integrated mode.
* Get-PSUScript
* Invoke-PSUScript
* Get-PSUJob
* Get-PSUJobOutput
* Get-PSUJobPipelineOutput
* Get-PSUJobFeedback
* Set-PSUJobFeedback
* Wait-PSUJob
[](https://docs.powershelluniversal.com/v3/automation/jobs#invoking-jobs-with-rest)
Invoking Jobs with REST
----------------------------------------------------------------------------------------------------------------
You can call jobs over REST using the management API for PowerShell Universal. You will need a valid app token to invoke jobs.
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#call-scripts-with-rest)
Call Scripts with REST
To call a script, you call an HTTP POST to the script endpoint with the ID of the script you wish to execute.
Copy
Invoke-RestMethod http://localhost:5000/api/v1/script/7 -Method POST -Body "" -Headers @{ Authorization = "Bearer appToken" } -ContentType 'application/json'
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#providing-parameters)
Providing Parameters
You can provide parameters to the job via a query string. Parameters will be provided to your script as strings.
Copy
$Parameters = @{
Uri = "http://localhost:5000/api/v1/script/path/PNP.ps1?Server=tester&Domain=test"
Method = "POST"
Headers = @{Authorization = "Bearer $Apptoken"}
ContentType = 'application/json'
Body = '{}'
}
Invoke-RestMethod @Parameters
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#setting-the-environment)
Setting the Environment
You can set the environment by pass in the environment property to the job context. The property must be the name of an environment defined within your PSU instance.
Copy
$JobContext = @{
Environment = "PowerShell 7"
} | ConvertTo-Json
Invoke-RestMethod http://localhost:5000/api/v1/script/7 -Method POST -Body $JobContext -Headers @{ Authorization = "Bearer appToken" } -ContentType 'application/json'
###
[](https://docs.powershelluniversal.com/v3/automation/jobs#setting-the-run-as-account)
Setting the Run As account
You can set the run as account by passing in the name of a PSCredential variable to the Credential property.
Copy
$JobContext = @{
Credential = "MyUser"
} | ConvertTo-Json
Invoke-RestMethod http://localhost:5000/api/v1/script/7 -Method POST -Body $JobContext -Headers @{ Authorization = "Bearer appToken" } -ContentType 'application/json'
[](https://docs.powershelluniversal.com/v3/automation/jobs#variables-defined-in-jobs)
Variables Defined in Jobs
--------------------------------------------------------------------------------------------------------------------
Variables defined in jobs can be found on the [variables page](https://docs.powershelluniversal.com/v3/platform/variables#scripts)
.
[](https://docs.powershelluniversal.com/v3/automation/jobs#experimental-feature-job-run-id)
Experimental Feature: Job Run ID
---------------------------------------------------------------------------------------------------------------------------------
The default behavior for PowerShell Universal is to track jobs based on an autoincrementing int64-based ID. Every time a new job is run, the job is one higher in ID than the last. Because of this behavior, it is easy to guess other job IDs and can potentially lead to a security risk.
In order to avoid this issue, you can enable the `JobRunID` experimental feature. Although internally the system still creates jobs with ascending numeric IDs, you cannot access jobs based on those IDs. Instead, a new field called `RunID` is used. `RunID` utilizes a `GUID` rather than an ID for look ups. This greatly reduces the ability for an attacker to guess a job ID.
You will need to enable this feature to use it.
Copy
Set-PSUSetting -ExperimentalFeature ([PowerShellUniversal.ExperimentalFeatures]::JobRunId)
[](https://docs.powershelluniversal.com/v3/automation/jobs#api)
API
------------------------------------------------------------------------
* [Invoke-PSUScript](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Invoke-PSUScript.txt)
* [Get-PSUJob](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUJob.txt)
* [Get-PSUJobFeedback](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUJobFeedback.txt)
* [Get-PSUJobOutput](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUJobOutput.txt)
* [Get-PSUJobPipelineOutput](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUJobPipelineOutput.txt)
* [Wait-PSUJob](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Wait-PSUJob.txt)
[PreviousParameters](https://docs.powershelluniversal.com/v3/automation/scripts/parameters)
[NextSchedules](https://docs.powershelluniversal.com/v3/automation/schedules)
Last updated 2 years ago
---
# Terminals | PowerShell Universal
Terminals require a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
Terminals are in-browser PowerShell consoles that you can execute arbitrary commands within. Terminals are configured to target an environment that you select and can optionally us Run As credentials to run as other users. The history of terminals is maintained within the PowerShell Universal database. You can reconnect to disconnected terminals as long as they haven't timed out.
Terminal configurations are stored in `terminals.ps1`
[](https://docs.powershelluniversal.com/v3/automation/terminals#configure-a-terminal)
Configure A Terminal
---------------------------------------------------------------------------------------------------------------
You can configure a new terminal by navigating to Automation \\ Terminals and clicking Create New Terminal. You'll be able to select the environment and credential to run the terminal as.

Terminals Page
[](https://docs.powershelluniversal.com/v3/automation/terminals#use-a-terminal)
Use a Terminal
---------------------------------------------------------------------------------------------------
To use a terminal, click the Open Terminal button for the terminal you wish to launch. Depending on your configuration, this may start a new PowerShell process based on the environment you selected.

Open Terminal
Once the terminal has launched, you'll be able to issue commands.

Run Commands in a Terminal
###
[](https://docs.powershelluniversal.com/v3/automation/terminals#stop-a-terminal)
Stop a Terminal
To stop a terminal, you can navigate to the terminal instances tab on the Terminals page. Click the trash can to stop the terminal.

Stop a Terminal
###
[](https://docs.powershelluniversal.com/v3/automation/terminals#reconnect-to-a-terminal)
Reconnect to a Terminal
If you navigate away from PowerShell Universal, the terminal will go idle. You can reconnect to a terminal by clicking the Open Terminal button for the idle terminal instance.

Reconnect to a Terminal
Terminals will time out automatically after 5 minutes. You can customize the timeout by setting the `-IdleTimeout` parameter of `New-PSUTerminal`.
[](https://docs.powershelluniversal.com/v3/automation/terminals#history)
History
-------------------------------------------------------------------------------------
Terminal history can be enabled per terminal configuration.

When terminal history is enabled, you will be able to view the history of all commands that were executed within the terminal. Click the View Command History button for the instance in question.

You will be able to review what the command was that ran, when it was ran, who started the terminal and what the output of the command was.

[PreviousSystem Events](https://docs.powershelluniversal.com/v3/automation/system-events)
[NextTriggers](https://docs.powershelluniversal.com/v3/automation/triggers)
Last updated 2 years ago
---
# About | PowerShell Universal
PowerShell Universal provides two ways of creating User Interfaces: Dashboards and Pages. Dashboards are highly interactive interfaces authored in PowerShell. Pages are simple drag and drop interfaces that can call scripts and APIs.
[](https://docs.powershelluniversal.com/v3/userinterfaces/about#dashboards)
Dashboards
-------------------------------------------------------------------------------------------

Dashboard Editor
Dashboards offer a higher level of customization, interactivity and complexity. They are developed using the PowerShell Universal Dashboard module.
Some examples of interfaces you can create:
* Wizard-like input forms with validation and custom step logic
* Highly interactive tables that can sort, filter, export and page directly from a SQL server
* Continuously updating charts that monitor server performance or resource usage
* Web pages that behave much like desktop applications with feedback like modals, notifications and interaction between controls.
[](https://docs.powershelluniversal.com/v3/userinterfaces/about#pages)
Pages
---------------------------------------------------------------------------------

Page Editor
Pages provide a basic method of creating user interfaces with a drag and drop designer. The controls are more limited, and the logic of your interface is limited to scripts or APIs that you have created with PowerShell Universal.
Some examples of interfaces you can create:
* Simple forms that accept various parameters, return output and display progress
* Charts that display data generated from APIs or scripts
* Simple tables that sort, page and export data generated by scripts or APIs.
[](https://docs.powershelluniversal.com/v3/userinterfaces/about#which-do-i-use)
Which do I use?
----------------------------------------------------------------------------------------------------
This will depend on your use case. Pages are much easier to get started with and do not have the learning curve of dashboards. Dashboards are much more robust but will require learning a new PowerShell module to create them.
If you are looking to expose simple forms that perform actions, return simple results and display data that has been generated in scripts, then Pages will be for you.
If you are looking to create a web interface that is similar to Windows Forms or WPF, then Dashboards are likely what you will want to use.
Note, you can [embed Dashboards in Pages](https://docs.powershelluniversal.com/v3/userinterfaces/pages/iframe#embed-a-dashboard-in-a-page)
.
[PreviousQueues](https://docs.powershelluniversal.com/v3/automation/queues)
[NextDashboards](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards)
Last updated 3 years ago
---
# Dashboards | PowerShell Universal
Dashboards are individual websites created with Universal Dashboard. You can define settings for a dashboard and start and stop the dashboard from within the Universal administrative interface.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#adding-a-dashboard)
Adding a Dashboard
----------------------------------------------------------------------------------------------------------------
Dashboards can be added to Universal using the Add Dashboard button from the Dashboard / Dashboards page.
**Name**
Name is displayed throughout the UI and returned from the Universal cmdlets.
**Base URL**
The base URL is the URL that you will access to view this dashboard. This URL needs to be unique within this instance. You can specify the `/` root URL if you wish. You will have to visit `/admin` to login to the administrative page if you set the dashboard to the root URL.
**File Name**
The full file name to the dashboard file. This file needs to return a dashboard using New-UDDashboard.
**Environment**
The [environment](https://docs.powershelluniversal.com/v3/config/environments)
to run the dashboard within.
**Authentication**
Enables authentication for the dashboard.
**Roles**
Defines the role that is required to access the dashboard.
**AutoStart**
Determines whether the dashboard should start (or restart) when the server starts or changes are made to the dashboard files.

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#starting-and-stopping-dashboards)
Starting and Stopping Dashboards
--------------------------------------------------------------------------------------------------------------------------------------------
Similar to jobs, dashboards run in separate PowerShell processes. You can start and stop a dashboard process by clicking the Start or Stop button from the Dashboards page.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#viewing-diagnostic-information)
Viewing Diagnostic Information
----------------------------------------------------------------------------------------------------------------------------------------
You can view diagnostic information for a dashboard by clicking the Info button on the Dashboards page. This will show your start information for the dashboard as well as any error that were encountered when starting the dashboard.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#viewing-the-dashboard)
Viewing the Dashboard
----------------------------------------------------------------------------------------------------------------------
You can view the dashboard by clicking the View button. This will take you to the Base URL for the dashboard.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#executing-commands-with-the-dashboard)
Executing Commands with the Dashboard
------------------------------------------------------------------------------------------------------------------------------------------------------
On the dashboard information page, click on the Console tab to view the UD console. The console allows you to run scripts from within the UD runspace so you can better debug the state of your script. You can evaluate variables and run commands that are available to the dashboard. You will be running in the context of your user in regards to the runspace but the process will be running as the service account user.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#persistent-runspaces)
Persistent Runspaces
--------------------------------------------------------------------------------------------------------------------
Persistent runspaces allow you to maintain runspace state within your dashboard endpoints. This is important for users that perform some sort of initialization within their endpoints that they do not want to execute on subsequent calls.
By default, runspaces will be reset after each execution. This will cause variables, modules and functions defined during the execution of an endpoint.
To enable persistent runspaces, you will need to configure an [environment](https://docs.powershelluniversal.com/v3/config/environments)
for your API. Set the `-PersistentRunspace` parameter to enable this feature. This is configured in the `environments.ps1` script.
Copy
New-PSUEnvironment -Name 'Env' -Path 'powershell.exe' -PersistentRunspace
You will need to ensure that the environment is used by the dashboard.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#automatically-granting-app-tokens)
Automatically Granting App Tokens
----------------------------------------------------------------------------------------------------------------------------------------------
You can automatically grant app tokens to users that visit dashboards. This is useful if you want to invoke the management API for PowerShell Universal from within a dashboard. Your dashboard will need to have authentication enabled and you will have to use the `-GrantAppToken` switch parameter on `New-PSUDashboard`.
Copy
New-PSUDashboard -Name 'Dashboard' -BaseUrl '/' -Framework "UniversalDashboard:Latest" -Authenticated -GrantAppToken
From within your dashboard, you can now invoke the management API without having to worry about app token management. The API will be invoked in the context of the user that is visiting the dashboard.
Copy
New-UDDashboard -Title "Hello, World!" -Content {
New-UDButton -Text 'Job' -OnClick {
Invoke-UAScript -Name 'Test.ps1'
}
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#disable-error-toasts)
Disable Error Toasts
--------------------------------------------------------------------------------------------------------------------
By default, dashboards will display a toast message when an error is generated within an endpoint script. To avoid this behavior, you can use the `-DisableErrorToast` parameter of `New-UDDashboard`
Copy
New-PSUDashboard -Name 'Dashboard' -BaseUrl '/' -Framework "UniversalDashboard:Latest" -Authenticated -DisableErrorToast
Copy
New-UDDashboard -Title "Hello, World!" -Content {
New-UDButton -Text 'Job' -OnClick {
throw "Exception
}
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#disable-startup-logging)
Disable Startup Logging
--------------------------------------------------------------------------------------------------------------------------
When starting a dashboard, information about the variables and modules is displayed within the dashboard log. If you wish to suppress this information, you can use the `-DisableStartupLogging` parameter.
Copy
New-PSUDashboard -Name 'Dashboard' -BaseUrl '/' -Framework "UniversalDashboard:Latest" -DisableStartupLogging
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards#variables-available-in-dashboards)
Variables Available in Dashboards
----------------------------------------------------------------------------------------------------------------------------------------------
Built-in variables are listed on the [variables page.](https://docs.powershelluniversal.com/v3/platform/variables#dashboards)
[PreviousAbout](https://docs.powershelluniversal.com/v3/userinterfaces/about)
[NextDashboards](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards)
Last updated 3 years ago
---
# Components | PowerShell Universal
A Universal Dashboard website is composed of components. In addition to the core component, you can also extend Universal Dashboard with a large set of community created components.
There are two non-framework components that are built into PSU. These include the Nivo charts library as well as the UDMap component. Additional components can be downloaded from the [UD Marketplace](https://marketplace.universaldashboard.io/)
.
External components are distributed as PowerShell modules and can be used in a dashboard by using `Import-Module`.
When building a dashboard, you can simply call the PowerShell cmdlets within your dashboard script to create a new component.
Copy
New-UDDashboard -Title 'Dashboard' -Content {
New-UDTypography -Text 'Hello, world!'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components#adding-components-to-dashboards)
Adding Components to Dashboards
-----------------------------------------------------------------------------------------------------------------------------------------------------
You can add component modules by clicking the Components button on the Dashboard page and then adding the components. This list will also include components downloaded from the Marketplace.

Add Components to a Dashboard
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components#component-storage)
Component Storage
-------------------------------------------------------------------------------------------------------------------------
Each version of PowerShell Universal includes some built in components. These components are included in the local installation directory. During start up, they are deployed to the assets folder. By default, this folder is `%ProgramData%\PowerShellUniversal\Dashboard\Components` .
You can change the assets folder by updating appsettings.json.
Copy
"UniversalDashboard": {
"AssetsFolder": "%ProgramData%\\PowerShellUniversal\\Dashboard",
},
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components#manual-component-installation)
Manual Component Installation
You can manually install components into the assets folder by including the appropriate folder structure and files. All components need to be valid PowerShell modules.
Each component should be in a folder with the module name and an additional folder with the version.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components#including-components-in-the-repository)
Including Components in the Repository
You can also include components within the code Repository. By including them in the repository, they will be downloaded when using [git sync](https://docs.powershelluniversal.com/v3/config/git)
. This functionality is only enabled when git sync is enabled.
After a git pull is performed on the remote repository, Components will be automatically loaded and available within the Components page within PowerShell Universal. The structure and layout of the components folder is the same as the main assets folder.

[PreviousExamples](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples)
[NextPages](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages)
Last updated 3 years ago
---
# Dashboards | PowerShell Universal
Dashboards can contain one or more pages. The simplest dashboard will contain a single page with some content. You can call any PowerShell cmdlet that is available on your machine to populate your dashboard.
Here's an example of simple dashboard that displays some text.
Copy
New-UDDashboard -Title 'My New Dashboard' -Content {
New-UDTypography -Text 'Hello!'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#new-uddashboard)
New-UDDashboard
------------------------------------------------------------------------------------------------------------------------------
The top-level cmdlet for dashboards is `New-UDDashboard`. You need to call it when returning a dashboard. You can use it with or without pages.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#content)
Content
The content of the dashboard is a series of components to display on the page. It's a script block that will return all the components in the order they will be rendered on the page. You can use the Grid component to layout items and display things like text with typography.
Copy
New-UDDashboard -Title 'My New Dashboard' -Content {
New-UDTypography -Text 'Hello!'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#header-customization)
Header Customization
You can customize the header of the dashboard using several parameters.
To change the navigation layout, use the `-Navigation` and `-NavigationLayout` parameters.
Copy
New-UDDashboard -Content {
} -Navigation (
New-UDList -Children {
New-UDListItem -Label "Home"
New-UDListItem -Label "Getting Started" -Children {
New-UDListItem -Label "Installation" -OnClick {}
New-UDListItem -Label "Usage" -OnClick {}
New-UDListItem -Label "FAQs" -OnClick {}
New-UDListItem -Label "System Requirements" -OnClick {}
New-UDListItem -Label "Purchasing" -OnClick {}
}
}
) -NavigationLayout permanent
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#components)
Components
--------------------------------------------------------------------------------------------------------------------
Components are the individual widgets that you can place on you dashboard. There are components for displaying data, taking user input, adding text and images and more. Components can be downloaded as PowerShell modules and added to your dashboard.
Components are be caused using the standard verb-name syntax for any PowerShell cmdlet.
Copy
New-UDPage -Content {
New-UDTextbox
}
Learn more about [components here](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#components)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#pages)
Pages
----------------------------------------------------------------------------------------------------------
You can specify multiple pages within a dashboard. Each page defines a route. As for v3, all pages are dynamic. PowerShell will execute on each page load to render the new page. Since UD is a single page application, the web browser does not need to refresh the entire web page when navigating between the different dashboard pages.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'My Home Page' -Content {}
$Pages += New-UDPage -Name 'Diagnostics' -Content {}
New-UDDashboard -Pages $Pages -Title 'Dashboard'
Learn more about [Pages here](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#pages)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#built-in-variables)
Built-in Variables
------------------------------------------------------------------------------------------------------------------------------------
Built-in variables can be found on the [variables page](https://docs.powershelluniversal.com/v3/platform/variables#dashboards)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#debugging)
Debugging
------------------------------------------------------------------------------------------------------------------
You can also use the [Debugging Tools](https://docs.powershelluniversal.com/v3/development/debugging-scripts#integrated-debugger)
with dashboards.
When building a dashboard, you will likely run into issues with cmdlet calls or syntax. Dashboards will auto reload as you make changes to the dashboard files. If a dashboard fails to start, you can navigate to the admin page, click Dashboards and click the Info button next to your dashboard.
The Log tab will show all the logging coming from the PowerShell execution from within in your dashboard. This should allow you to easily see errors and warnings coming from your dashboard.
You can use `Write-Debug` to add additional log messages to your dashboard. To enable debug logging, you will have to set the `$DebugPreference` variable at the top of your dashboard script.
Copy
$DebugPreference = 'Continue'
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards#menu)
Menu
--------------------------------------------------------------------------------------------------------
You can customize the dashboard menu by using the `-Menu` parameter.
Copy
New-UDDashboard -Title 'Dashboard' -Content {
} -Menu {
New-UDMenuItem -Text 'Profile' -OnClick {
Show-UDModal -Content {
New-UDTypography -Text 'Welcome to your profile!'
}
}
}
[PreviousDashboards](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards)
[NextExamples](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples)
Last updated 2 years ago
---
# Triggers | PowerShell Universal
Triggers require a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
Triggers allow for automation jobs to be started when certain events happen within PowerShell Universal. For example, this allows you to take action when jobs complete, the server starts or dashboards stop. Triggers are useful for assigning global error handling or sending notifications when certain things happen.

Triggered jobs will not cause additional triggers to start. Triggers are stored in the `triggers.ps1`.
[](https://docs.powershelluniversal.com/v3/automation/triggers#trigger-events)
Trigger Events
--------------------------------------------------------------------------------------------------
The following types of events can be assigned a trigger.
* Job Started
* Job Completed
* Job Requesting Feedback
* Job Failed
* Dashboard Started
* Dashboard Stopped
* Server Started
* Server Stopping
* User Login
* Use of a Revoked App Token
* PowerShell Protect Event
* API Authentication Failed
* API Error
* New User Login
* Git Sync
* License Expired
* License Expiring
###
[](https://docs.powershelluniversal.com/v3/automation/triggers#new-user-login)
New User Login
The user login event takes place when a user accesses PowerShell Universal. The script will receive a `$User`parameter with user information.
Copy
@{
Name = "username"
Roles = @()
}
###
[](https://docs.powershelluniversal.com/v3/automation/triggers#user-login)
User Login
The user login event takes place when a user accesses PowerShell Universal. The script will receive a `$data` parameter with user information. The data structure is shown below.
Copy
@{
UserName = 'username'
RemoteIpAddress = ''
LocalPort = ''
RemotePort = ''
}
###
[](https://docs.powershelluniversal.com/v3/automation/triggers#use-of-a-revoked-app-token)
Use of a Revoked App Token
The app token event takes place when a revoked app token is used. The script will receive a `$data` parameter that contains the contents of the app token as a string.
###
[](https://docs.powershelluniversal.com/v3/automation/triggers#git-sync)
Git Sync
This trigger occurs when a git sync is run. This trigger will fire for both successful and unsuccessful git syncs.
You will receive the following object in the `$data` parameter.
Copy
public class GitStatus
{
public long Id { get; set; }
public string CommitId { get; set; }
public DateTime Timestamp { get; set; }
public TimeSpan SyncTime { get; set; }
public int Changes { get; set; }
public string Location { get; set; }
public string Remote { get; set; }
public GitStatusResult Result { get; set; }
public string ResultMessage { get; set; }
public string ComputerName { get; set; }
}
[](https://docs.powershelluniversal.com/v3/automation/triggers#global-triggers)
Global Triggers
----------------------------------------------------------------------------------------------------
Global triggers will start the assigned script whenever the event type is invoked.
For example, the `Script.ps1` will be run whenever any job is run.
Copy
New-PSUTrigger -Name 'Trigger' -EventType JobStarted -TriggerScript Script.ps1
[](https://docs.powershelluniversal.com/v3/automation/triggers#resource-triggers)
Resource Triggers
--------------------------------------------------------------------------------------------------------
Resource triggers will start the assigned script when the event takes place on the selected resource.
For example, the `Script.ps1` will be run whenever the `Dashboard` is stopped.
Copy
New-PSUTrigger -Name 'Trigger' -EventType DashboardStopped -TriggerScript Script.ps1 -Dashboard 'Dashboard'
[](https://docs.powershelluniversal.com/v3/automation/triggers#event-metadata)
Event Metadata
--------------------------------------------------------------------------------------------------
Whenever a job is started from a trigger, it will be provided with metadata about object that caused the event to trigger.
Triggers related to jobs will be provided a `$Job` parameter.
Copy
param($Job)
$Job
Triggers related to dashboards will be provided a `$Dashboard` parameter.
Copy
param($Dashboard)
$Dashboard
Triggers related to the server status will not receive a parameter.
[](https://docs.powershelluniversal.com/v3/automation/triggers#conditions)
Conditions
------------------------------------------------------------------------------------------
Using the `-Condition` parameter of `New-PSUTrigger`, you can determine whether or not a trigger should be run based on local conditions on the server. Return `$true` or `$false` from the condition.
For example, you can disable a trigger if the `Environment` environment variable is not set to `production`.
Copy
New-PSUTrigger -Condition {
$Env:Environment -eq 'production'
}
[](https://docs.powershelluniversal.com/v3/automation/triggers#api)
API
----------------------------------------------------------------------------
* [New-PSUTrigger](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUTrigger.txt)
* [Remove-PSUTrigger](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-PSUTrigger.txt)
* [Set-PSUTrigger](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSUTrigger.txt)
* [Get-PSUTrigger](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUTrigger.txt)
[PreviousTerminals](https://docs.powershelluniversal.com/v3/automation/terminals)
[NextQueues](https://docs.powershelluniversal.com/v3/automation/queues)
Last updated 2 years ago
---
# Examples | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples#display-processes)
Display Processes
-----------------------------------------------------------------------------------------------------------------------
This example displays processes in a table.
Copy
New-UDDashboard -Title 'Processes' -Content {
$Processes = Get-Process | Select-Object Id, Name
New-UDTable -Columns @(
New-UDTableColumn -Property 'Id' -Title 'Id'
New-UDTableColumn -Property 'Name' -Title 'Name'
) -Data $Processes -ShowPagination
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples#file-system-browser)
File System Browser
---------------------------------------------------------------------------------------------------------------------------
Create a file system browser with a dynamic tree view.
Copy
New-UDDashboard -Title 'Processes' -Content {
Get-PSDrive -PSProvider 'FileSystem' | ForEach-Object {
New-UDTreeView -Node { New-UDTreeNode -Name $_.Name -Id "$($_.Name):\" } -OnNodeClicked {
Get-ChildItem $EventData.Id | ForEach-Object {
New-UDTreeNode -Name $_.Name -Id $_.FullName -Leaf:$(-not $_.PSIsContainer)
}
}
}
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples#create-user-form)
Create User Form
---------------------------------------------------------------------------------------------------------------------
This example shows how to create a local user account.
Copy
New-UDDashboard -Title 'New User' -Content {
New-UDForm -Content {
New-UDTextbox -Id 'UserName' -Label "User Name"
New-UDTextbox -Id 'Password' -Label 'Password' -Type 'password'
} -OnSubmit {
$Password = $EventData.Password | ConvertTo-SecureString -AsPlainText
New-LocalUser -Name $EventData.UserName -Password $Password
Show-UDToast "New user $($EventData.UserName) was created!"
}
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/examples#clock)
Clock
-----------------------------------------------------------------------------------------------
This example shows how to create a clock component in PowerShell Universal Dashboard.
Copy
New-UDDashboard -Title 'Clock' -Content {
New-UDDynamic -Id 'clock' -Content {
(Get-Date).ToString('T')
} -AutoRefresh -AutoRefreshInterval 1
New-UDButton -Text 'Toggle Clock' -OnClick {
Set-UDElement -Id 'clock' -Properties @{
autoRefresh = -not( (Get-UDElement -Id 'clock').AutoRefresh)
}
}
}

[PreviousDashboards](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/building-dashboards)
[NextComponents](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components)
Last updated 2 years ago
---
# Error Boundary | PowerShell Universal
The `New-UDErrorBoundary` component is used for isolating portions of a dashboard to contain components that may throw an error. Many Universal Dashboard components use the error boundary component internally.
If you'd like to isolate a portion of your dashboard to prevent the entire page from failing to load, you can use the following syntax.
Copy
New-UDErrorBoundary -Content {
throw "Oh no!"
}
If any error is thrown from the content, you will see an error such as thing.

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/error-boundary#api)
API
------------------------------------------------------------------------------------------------------------
[**New-UDErrorBoundary**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDErrorBoundary.txt)
[PreviousElement](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element)
[NextHTML](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/html)
Last updated 3 years ago
---
# HTML | PowerShell Universal
You can define static HTML using `New-UDHtml`. This cmdlet does not create React components but rather allows you to define static HTML. Any valid HTML string is supported.
The following creates an unordered list.
Copy
New-UDHtml -Markup "
First
Second
Third
"
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/html#api)
API
--------------------------------------------------------------------------------------------------
[**New-UDHtml**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDHtml.txt)
[PreviousError Boundary](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/error-boundary)
[NextCustom Components](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/custom-components)
Last updated 3 years ago
---
# Feedback | PowerShell Universal
[Backdrop](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/backdrop)
[Modal](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/modal)
[Progress](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/progress)
[Skeleton](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/skeleton)
[PreviousMap](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-visualization/map)
[NextBackdrop](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/backdrop)
Last updated 3 years ago
---
# Data Display | PowerShell Universal
[Alert](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/alert)
[Badge](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/badge)
[Chip](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/chip)
[Data Grid](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/data-grid)
[Date and Time](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/date-and-time)
[Icon](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/icon)
[List](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/list)
[Markdown](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/markdown)
[Table](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/table)
[Timeline](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/timeline)
[Tooltip](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/tooltip)
[Tree View](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/tree-view)
[Typography](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/typography)
[PreviousBuilding Custom JavaScript Components](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/custom-components/building-custom-components)
[NextAlert](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/alert)
Last updated 3 years ago
---
# Dynamic Regions | PowerShell Universal
`New-UDDynamic` allows you to define a dynamic region. Pages themselves are dynamic in nature. This means that every time a page is loaded, it runs the PowerShell for that page. Sometimes, you may want to reload a section of a page rather than the whole page itself. This is when you will want to use dynamic regions.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions#basic-dynamic-region)
Basic Dynamic Region
-----------------------------------------------------------------------------------------------------------------------------------------------
This dynamic region reloads when the button is clicked.
Copy
New-UDDashboard -Title "Hello, World!" -Content {
New-UDDynamic -Id 'date' -Content {
New-UDTypography -Text "$(Get-Date)"
}
New-UDButton -Text 'Reload Date' -OnClick { Sync-UDElement -Id 'date' }
}

Reload on button click
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions#arguments-list)
Arguments List
-----------------------------------------------------------------------------------------------------------------------------------
An array of arguments may be passed to the dynamic region.
Note that the arguments are static and do not change when Sync-UDElement is invoked.
Copy
New-UDDynamic -Id 'dynamic_01' -Content {
New-UDTypography -Text "This is an $($ArgumentList[0])
an $($ArgumentList[1]) in a UDDynamic"
} -ArgumentList @('example of', 'arguments list')

utilizing the arguments list
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions#auto-refresh)
Auto Refresh
-------------------------------------------------------------------------------------------------------------------------------
Dynamic regions enable the ability to auto refresh components after a certain amount of time. The entire region's script block will be run when autorefreshing.
If you have multiple related components that use the same data, consider putting them in the same dynamic region to improve performance.
Copy
New-UDDynamic -Id 'date' -Content {
New-UDTypography -Text "$(Get-Date)" -Variant h3
New-UDTypography -Text "$(Get-Random)" -Variant h3
} -AutoRefresh -AutoRefreshInterval 1

Auto refresh dynamic region
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions#loading-component)
Loading Component
-----------------------------------------------------------------------------------------------------------------------------------------
Sometimes refreshing a dynamic component may take some time. For example, if you are querying another service's REST API or a data. Dynamic regions support configuration of the component that shows when the region is reloading. By default, nothing is shown. This can be any Universal Dashboard component.
Copy
New-UDDynamic -Content {
Start-Sleep -Seconds 3
New-UDTypography -Text "Done!"
} -LoadingComponent {
New-UDProgress -Circular
}

Loading component for dynamic region
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions#api)
API
-------------------------------------------------------------------------------------------------------------
[New-UDDynamic](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDDynamic.txt)
[PreviousPages](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages)
[NextElement](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element)
Last updated 2 years ago
---
# Data Visualization | PowerShell Universal
[Charts](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-visualization/charts)
[Image](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-visualization/image)
[Map](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-visualization/map)
[PreviousTypography](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/typography)
[NextCharts](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-visualization/charts)
Last updated 3 years ago
---
# Custom Components | PowerShell Universal
Components in PowerShell Universal Dashboard are exposed as functions. You can combine built in components to produce your own custom components.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/custom-components#example-people-picker)
Example: People Picker
----------------------------------------------------------------------------------------------------------------------------------------------------

People Picker
The below example creates a `New-UDPeoplePicker` component from existing UD components. You can use the `New-UDPeoplePicker` component in your dashboards. This function can either be defined within your dashboard directly or within a [Module](https://docs.powershelluniversal.com/v3/platform/modules)
.
This example users a published folder of avatars.
Copy
function Get-User {
1..100 | ForEach-Object {
[PSCustomObject]@{
UserName = "User$_"
First = "Bill"
Last = $_
Avatar = (Get-ChildItem "$Repository\Avatars" | Get-Random).Name
}
}
}
function New-UDPeoplePicker {
$Session:Users = [System.Collections.Generic.List[object]]::new()
New-UDAutocomplete -OnLoadOptions {
Get-User | Where-Object { $_.UserName -like "*$UserName*" } | Select-Object -First 5 -ExpandProperty 'UserName' | ConvertTo-Json
} -OnChange {
$Session:Users.Add((Get-User | Where-Object { $_.UserName -eq $EventData })) | Out-Null
Sync-UDElement -Id 'users'
}
New-UDDynamic -Id 'users' -Content {
New-UDList -Children {
$Session:Users | ForEach-Object {
New-UDListItem -Label $_.UserName -SubTitle "$($_.First) $($_.Last)" -AvatarType 'Avatar' -SecondaryAction {
$UserName = $_.UserName
New-UDIconButton -Icon (New-UDIcon -Icon 'Trash') -OnClick {
$RemoveUser = $Session:Users | Where-Object { $_.UserName -eq $UserName }
$Session:Users.Remove($RemoveUser)
Sync-UDElement -Id 'users'
}
} -Source "/avatars/$($_.Avatar)"
}
}
}
}
New-UDDashboard -Title 'PowerShell Universal' -Content {
New-UDPeoplePicker
}
[PreviousHTML](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/html)
[NextBuilding Custom JavaScript Components](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/custom-components/building-custom-components)
Last updated 2 years ago
---
# Surfaces | PowerShell Universal
[AppBar](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/appbar)
[Card](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/card)
[Paper](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/paper)
[Expansion Panel](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/expansion-panel)
[PreviousTransitions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/utilities/transitions)
[NextAppBar](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/appbar)
Last updated 3 years ago
---
# Element | PowerShell Universal
The `New-UDElement` cmdlet allows you to create custom React elements within your dashboard. Similar to `New-UDHtml`, you can define HTML elements using `New-UDElement`. Unlike, `New-UDHtml`, you can update elements, set auto refresh and take advantage of the React component system.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#create-an-element)
Create an Element
---------------------------------------------------------------------------------------------------------------------------------
You need to specify the `-Tag` and `-Content` when creating an element. The below example creates a div tag.
Copy
New-UDElement -Tag 'div' -Content { 'Hello' }
You can nest components within each other to create HTML structures. For example, you could create an unordered list with the following example.
Copy
New-UDElement -Tag 'ul' -Content {
New-UDElement -Tag 'li' -Content { 'First' }
New-UDElement -Tag 'li' -Content { 'Second' }
New-UDElement -Tag 'li' -Content { 'Third' }
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#setting-attributes)
Setting Attributes
-----------------------------------------------------------------------------------------------------------------------------------
You can select attributes of an element (like HTML attributes) by using the `-Attributes` parameter. This parameter accepts a hashtable of attribute name and values. The below example creates red text.
Copy
New-UDElement -Tag 'div' -Content { 'Hello' } -Attributes @{
style = @{
color = 'red'
}
}
You can wrap any component with New-UDElement and add an event handler.
Copy
New-UDElement -Tag div -Content {
New-UDIcon -Icon "user"
} -Attributes @{
onClick = {
Show-UDToast "Nice!"
}
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#auto-refreshing-elements)
Auto Refreshing Elements
-----------------------------------------------------------------------------------------------------------------------------------------------
You can define the `-AutoRefresh`, `-RefreshInterval` and `-Endpoint` parameters to create an element the refreshes on a certain interval. The below example creates an element that refreshes every second and displays the current time.
Copy
New-UDElement -Tag 'div' -Endpoint {
Get-Date
} -AutoRefresh -RefreshInterval 1
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#setting-element-properties-dynamically)
Setting Element Properties Dynamically
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
You can use the `Set-UDElement` cmdlet to set element properties and content dynamically. The following example sets the content of the element to the current time.
Copy
New-UDElement -Tag 'div' -Id 'myElement' -Content { }
New-UDButton -Text 'Click Me' -OnClick {
Set-UDElement -Id 'myElement' -Content { Get-Date }
}
You can also set attributes by using the `-Properties` parameter of `Set-UDElement`. The following example sets the current time and changes the color to red.
Copy
New-UDElement -Tag 'div' -Id 'myElement' -Content { }
New-UDButton -Text 'Click Me' -OnClick {
Set-UDElement -Id 'myElement' -Content { Get-Date } -Properties @{ Attributes = @{ style = @{ color = "red" } } }
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#adding-child-elements)
Adding Child Elements
-----------------------------------------------------------------------------------------------------------------------------------------
You can add child elements using `Add-UDElement`. The following example adds child list items to an unordered list.
Copy
New-UDElement -Tag 'ul' -Content {
} -Id 'myList'
New-UDButton -Text 'Click Me' -OnClick {
Add-UDElement -ParentId 'myList' -Content {
New-UDElement -Tag 'li' -Content { Get-Date }
}
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#clearing-child-elements)
Clearing Child Elements
---------------------------------------------------------------------------------------------------------------------------------------------
You can clear the child elements of an element by using `Clear-UDElement`. The following example clears all the list items from an unordered list.
Copy
New-UDElement -Tag 'ul' -Content {
New-UDElement -Tag 'li' -Content { 'First' }
New-UDElement -Tag 'li' -Content { 'Second' }
New-UDElement -Tag 'li' -Content { 'Third' }
} -Id 'myList'
New-UDButton -Text 'Click Me' -OnClick {
Clear-UDElement -Id 'myList'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#forcing-an-element-to-reload)
Forcing an Element to Reload
-------------------------------------------------------------------------------------------------------------------------------------------------------
You can force an element to reload using `Sync-UDElement`. The following example causes the div to reload with the current date.
Copy
New-UDElement -Tag 'div' -Endpoint {
Get-Date
} -Id 'myDiv'
New-UDButton -Text 'Click Me' -OnClick {
Sync-UDElement -Id 'myDiv'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#removing-an-element)
Removing an Element
-------------------------------------------------------------------------------------------------------------------------------------
You can remove an element by using `Remove-UDElement`.
Copy
New-UDElement -Tag 'div' -Endpoint {
Get-Date
} -Id 'myDiv'
New-UDButton -Text 'Click Me' -OnClick {
Remove-UDElement -Id 'myDiv'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/element#api)
API
-----------------------------------------------------------------------------------------------------
* [**Get-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-UDElement.txt)
\*\*\*\*
* [**Set-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-UDElement.txt)
* [**Remove-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-UDElement.txt)
* [**Add-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Add-UDElement.txt)
* [**Clear-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Clear-UDElement.txt)
* [**Sync-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Sync-UDElement.txt)
* \*\*\*\*[**Select-UDElement**](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Select-UDElement.txt)
* * *
[PreviousDynamic Regions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions)
[NextError Boundary](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/error-boundary)
Last updated 2 years ago
---
# Navigation | PowerShell Universal
[Drawer](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/drawer)
[Link](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/link)
[Menu](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/menu)
[Stepper](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/stepper)
[Tabs](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/tabs)
[PreviousUpload](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/upload)
[NextDrawer](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/drawer)
Last updated 3 years ago
---
# Utilities | PowerShell Universal
[Protect Section](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/utilities/protect-section)
[Transitions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/utilities/transitions)
[PreviousStack](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/stack)
[NextProtect Section](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/utilities/protect-section)
Last updated 3 years ago
---
# Inputs | PowerShell Universal
[Autocomplete](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/automcomplete)
[Button](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/button)
[Checkbox](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/checkbox)
[Code Editor](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/code-editor)
[Date Picker](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/date-picker)
[Editor](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/editor)
[Floating Action Button](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/floating-action-button)
[Form](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/form)
[Radio](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/radio)
[Rating](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/rating)
[Select](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/select)
[Slider](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/slider)
[Switch](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/switch)
[Textbox](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/textbox)
[Time Picker](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/time-picker)
[Transfer List](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/transfer-list)
[Upload](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/upload)
[PreviousSkeleton](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/skeleton)
[NextAutocomplete](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/inputs/automcomplete)
Last updated 3 years ago
---
# Layout | PowerShell Universal
[Grid Layout](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/grid-layout)
[Grid](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/grid)
[Hidden](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/hidden)
[Stack](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/stack)
[PreviousTabs](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/navigation/tabs)
[NextGrid Layout](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/layout/grid-layout)
Last updated 3 years ago
---
# Sessions | PowerShell Universal
Universal Dashboard maintains sessions for users within each dashboard. There are several locations you can configure user session information.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions#dashboard-session-setting)
Dashboard Session Setting
---------------------------------------------------------------------------------------------------------------------------------------
Session settings for a dashboard are using the web server session setting by default. You can set the dashboard session timeout for an individual dashboard by using the `-SessionTimeout` of `New-PSUDashboard`. The timeout value is in minutes.
Copy
New-PSUDashboard -Name 'dashboard' -BaseUrl / -Framework UniversalDashboard:Latest -SessionTimeout 30
Dashboard sessions are sliding and will not expire while the window is open and active. Some browsers will pause tabs which will cause the session to expire after the time out.
Restarting a dashboard will cause all sessions to disconnect.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions#web-server-session-setting)
Web Server Session Setting
-----------------------------------------------------------------------------------------------------------------------------------------
The web server will maintain a session for the user. The session is sliding and will not expire while the window is open and active. Some browsers will pause tabs which will cause the session to expire after the time out.
The default value for the web server session timeout is 25 minutes. You can change the web server session setting by updating the `appsettings.json` file.
Copy
"SessionTimeout": 25
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions#dashboard-idle-timeout)
Dashboard Idle Timeout
---------------------------------------------------------------------------------------------------------------------------------
In addition to dashboard session timeout, you can also timeout the dashboard when it is idle. Even if the window is open, if the user does not click, type or move the mouse for the idle timeout period, the window will time out. This functionality is disabled by default.
You can set the idle timeout in minutes by setting the `-IdleTimeout` parameter of `New-PSUDashboard` cmdlet.
Copy
New-PSUDashboard -Name 'dashboard' -BaseUrl / -Framework UniversalDashboard:Latest -IdleTimeout 30
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions#iis-timeouts)
IIS Timeouts
-------------------------------------------------------------------------------------------------------------
IIS can cause timeouts of sessions in numerous ways. You will need to configure your application pool settings to avoid recycling which will cause all dashboard sessions to be removed.
Within the advanced settings dialog for the application pool, you can set the recycling settings accordingly.

Figure shows the recommended recycling settings for IIS
[PreviousScheduled Endpoints](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/scheduled-endpoints)
[NextThemes](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes)
Last updated 2 years ago
---
# Pages | PowerShell Universal
A dashboard can consist of one or more pages. A page can have a particular name and URL. You can define a URL that accepts one or more variables in the URL to define a dynamic page.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#creating-a-new-page)
Creating a new page
-----------------------------------------------------------------------------------------------------------------------------------
Within the dashboard editor, expand the Pages navigation menu and click New Page.

New Page Button
You can edit a page by clicking the link in the menu. The code editor will switch to the page's content.

A page editor
To reference the page in your dashboard, use `Get-UDPage`.

Using a page in a dashboard
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#basic-page)
Basic Page
-----------------------------------------------------------------------------------------------------------------
A basic page can be defined using the `New-UDPage` cmdlet. You could navigate to this page by visiting the `/dashboard` URL of your dashboard.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Dashboard' -Content {
New-UDTypography -Text 'Dashboard'
}
New-UDDashboard -Title 'Pages' -Pages $Pages
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#dashboard-with-multiple-pages)
Dashboard with Multiple Pages
-------------------------------------------------------------------------------------------------------------------------------------------------------
Dashboards can have multiple pages and those pages can be defined by passing an array of UDPages to `New-UDDashboard`
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Dashboard One' -Content {
New-UDTypography -Text 'Dashboard Two'
}
$Pages += New-UDPage -Name 'Dashboard Two' -Content {
New-UDTypography -Text 'Dashboard Two'
}
New-UDDashboard -Title 'Pages' -Pages $Pages
You may want to organize your dashboard into multiple PS1 files. You can do this using pages.
Copy
$UDScriptRoot = $PSScriptRoot
$Pages = @()
$Pages += New-UDPage -Name 'Dashboard One' -Content {
. "$UDScriptRoot\db1.ps1"
}
$Pages += New-UDPage -Name 'Dashboard Two' -Content {
. "$UDScriptRoot\db2.ps1"
}
New-UDDashboard -Title 'Pages' -Pages $Pages
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#page-with-a-custom-url)
Page with a Custom URL
-----------------------------------------------------------------------------------------------------------------------------------------
A page can have a custom URL by using the `-Url` parameter. You could navigate to this page by visiting the `/db` URL of your dashboard.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Dashboard' -Url '/db' -Content {
New-UDTypography -Text 'Dashboard'
}
New-UDDashboard -Title 'Pages' -Pages $Pages
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#page-with-variables-in-url)
Page with Variables in URL
-------------------------------------------------------------------------------------------------------------------------------------------------
You can define a page with variables in the URL to create pages that adapt based on that URL.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Dashboard' -Url '/db/:user' -Content {
New-UDTypography -Text 'Dashboard for user: $User'
}
New-UDDashboard -Title 'Pages' -Pages $Pages
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#query-string-parameters)
Query string parameters
Query string parameters are passed to pages and other endpoints as variables.
For example, if you visited a page with the following query string parameter: `http://localhost:5000/dashboard/Page1?test=123`
You would then have access to a `$Test` variable that contained the value `123`.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#role-based-access)
Role-Based Access
-------------------------------------------------------------------------------------------------------------------------------
This feature requires a [license](https://docs.powershelluniversal.com/v3/licensing)
.
You can prevent users from accessing pages based on their role by using the `-Role` parameter of pages. You can configure roles and role policies on the [Security page](https://docs.powershelluniversal.com/v3/config/security#policy-assignment)
.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Administrators' -Content {
New-UDTypography -Text 'Dashboard for user: $User'
} -Role 'Administrator'
$Pages += New-UDPage -Name 'Operators' -Content {
New-UDTypography -Text 'Dashboard for user: $User'
} -Role 'Operator'
New-UDDashboard -Title 'Pages' -Pages $Pages
The following options are available for customizing the header.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#position)
Position
Use the `-HeaderPosition` parameter to adjust the behavior of the header.
* absolute\\fixed - Remains at the top of the page, even when scrolling
* relative - Remains at the top of the page. Not visible when scrolling.
Copy
New-UDPage -HeaderPosition fixed -Content {
New-UDElement -tag div -Attributes @{
style = @{
height = '150vh'
}
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#colors)
Colors
You can adjust the colors of the header by specifying the `-HeaderColor` and `-HeaderBackgroundColor` parameters. These colors will override the theme colors.
Copy
New-UDPage -Name 'Home' -Content {
} -HeaderColor 'black' -HeaderBackgroundColor 'white'
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#navigation)
Navigation
-----------------------------------------------------------------------------------------------------------------
You can customize the navigation of a page using the `-Navigation` and `-NavigationLayout` parameters. Navigation is defined using the [List](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/data-display/list#list)
component. Navigation layouts are either permanent or temporary.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#custom-navigation)
Custom Navigation
Custom navigation can be defined with a list. List items can include children to create drop down sections in the navigation.
Copy
$Navigation = @(
New-UDListItem -Label "Home"
New-UDListItem -Label "Getting Started" -Children {
New-UDListItem -Label "Installation" -Href '/Installation'
New-UDListItem -Label "Usage" -Href '/Usage'
New-UDListItem -Label "FAQs" -Href '/faqs'
New-UDListItem -Label "System Requirements" -Href'/requirements'
New-UDListItem -Label "Purchasing" -Href '/purchasing'
}
)
$Pages = @()
$Pages += New-UDPage -Name 'Installation' -Content {
New-UDTypography -Text "Installation"
}
$Pages += New-UDPage -Name 'Usage' -Content {
New-UDTypography -Text "Usage"
}
New-UDDashboard -Title "Hello, World!" -Pages $Pages -NavigationLayout permanent -Navigation $Navigation

Custom navigation
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#dynamic-navigation)
Dynamic Navigation
Dynamic navigation can be used to execute scripts during page load to determine which navigation components to show based on variables like the user, IP address or roles.
You can generate dynamic navigation by using the `-LoadNavigation` parameter. The value of the parameter should be a script block to execute when loading the navigation.
Copy
$Navigation = {
New-UDListItem -Label "Home - $(Get-Date)"
New-UDListItem -Label "Getting Started" -Children {
New-UDListItem -Label "Installation" -Href '/installation'
New-UDListItem -Label "Usage" -Href '/usage'
New-UDListItem -Label "FAQs" -Href '/faqs'
New-UDListItem -Label "System Requirements" -Href'/requirements'
New-UDListItem -Label "Purchasing" -Href '/purchasing'
}
}
$Pages = @()
$Pages += New-UDPage -Name 'Test' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout permanent -LoadNavigation $Navigation
$Pages += New-UDPage -Name 'Test2' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout permanent -LoadNavigation $Navigation
New-UDDashboard -Title "Hello, World!" -Pages $Pages
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#layouts)
Layouts
The permanent layout creates a static navigation drawer on the left hand side of the page. It cannot be hidden by the user.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Test' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout permanent
$Pages += New-UDPage -Name 'Test2' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout permanent
New-UDDashboard -Title "Hello, World!" -Pages $Pages

Permanent navigation drawer
The temporary layout creates a navigation drawer that can be opened using a hamburger menu found in the top left corner. This is the default setting.
Copy
$Pages = @()
$Pages += New-UDPage -Name 'Test' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout temporary
$Pages += New-UDPage -Name 'Test2' -Content {
New-UDTypography -Text "Hello"
} -NavigationLayout temporary
New-UDDashboard -Title "Hello, World!" -Pages $Pages

Temporary navigation drawer
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#horizontal-navigation)
Horizontal Navigation

Horizontal Navigation
You can use `New-UDAppBar` with a blank page to create horizontal navigation.
Copy
New-UDDashboard -Title 'PowerShell Universal' -Pages @(
New-UDPage -Name 'Page' -Content {
New-UDAppBar -Children {
New-UDTypography -Text "Title" -Variant h4 -Style @{
marginRight = "50px"
}
New-UDMenu -Variant text -Text "Settings" -Children {
New-UDMenuItem -Text 'Item 1' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 2' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 3' -OnClick { Invoke-UDRedirect "/item1" }
}
New-UDMenu -Variant text -Text "Options" -Children {
New-UDMenuItem -Text 'Item 1' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 2' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 3' -OnClick { Invoke-UDRedirect "/item1" }
}
New-UDMenu -Variant text -Text "Tools" -Children {
New-UDMenuItem -Text 'Item 1' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 2' -OnClick { Invoke-UDRedirect "/item1" }
New-UDMenuItem -Text 'Item 3' -OnClick { Invoke-UDRedirect "/item1" }
}
} -DisableThemeToggle
} -Blank
)
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#logo)
Logo
-----------------------------------------------------------------------------------------------------
You can display a logo in the navigation bar by using the `-Logo` parameter.
First, setup a [published folder](https://docs.powershelluniversal.com/v3/platform/published-folders)
to host your logo.

Published assets folder
Now, when creating your page, you can specify the path to the logo.
Copy
New-UDPage -Name 'Home' -Logo '/assets/favicon.png' -Content {
}
The logo will display in the top left corner.

Logo
To customize the style of your logo, you can use a [cascading style sheet](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/cascading-style-sheets)
and target the `ud-logo` element ID.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#header-content)
Header Content
-------------------------------------------------------------------------------------------------------------------------
You can define custom content to include in the header by using the `-HeaderContent` parameter.
Copy
$Page = New-UDPage -Name 'Home' -Content {
} -HeaderContent {
New-UDButton -Icon (New-UDIcon -Icon Users) -Text 'User'
}
New-UDDashboard -Title "Dashboard" -Pages $Page

Button in Header
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#dynamic-page-title)
Dynamic Page Title
---------------------------------------------------------------------------------------------------------------------------------
Page titles are static by default, but you can override this behavior by using `-LoadTitle`. It will be called when the page is loaded. This is useful when defining pages in multilingual dashboards.
Copy
New-UDPage -Name "Home" -LoadTitle { "Current Time" + (Get-Date) } -Content { }
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#static-pages)
Static Pages
---------------------------------------------------------------------------------------------------------------------
Static pages allow for better performance by not executing PowerShell to load the content of the page. This can be useful when displaying data that does not require dynamic PowerShell execution. The page content is constructed when the dashboard is started.
Copy
New-UDPage -Name 'Static Page' -Content {
New-UDTypography (Get-Date)
} -Static
Static pages do not have access to user specific data. This includes variables such as:
* $Headers
* $User
* $Roles
You can still include dynamic regions within pages. These dynamic regions will have access to user data. Reloading the below example will update the date and time listed in the page.
Copy
New-UDPage -Name 'Static Page' -Content {
New-UDDynamic -Content {
New-UDTypography (Get-Date)
}
} -Static
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/pages#api)
API
---------------------------------------------------------------------------------------------------
[New-UDPage](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDPage.txt)
[PreviousComponents](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components)
[NextDynamic Regions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/dynamic-regions)
Last updated 2 years ago
---
# Styles | PowerShell Universal
You can apply styles to individual components within Universal Dashboard by using the `UDStyle` component. This component will need to be added to your dashboard and is part of the core components included with PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/styles#applying-a-style)
Applying a Style
--------------------------------------------------------------------------------------------------------------------------
To apply a style to a component or a set of components, you call the `New-UDStyle` cmdlet, specify a CSS style and then include the components you wish to style within the `-Content` script block.
Copy
New-UDStyle -Style '
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: white;
}
.card {
background-color: green !important;
}' -Content {
New-UDCard -Title 'Test' -Content {
"Hello"
}
}

UDStyled card
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/styles#overriding-built-in-styles)
Overriding Built in Styles
----------------------------------------------------------------------------------------------------------------------------------------------
Each Material UI component has a set of built in classes that you can override using `New-UDStyle`. To determine the class names that you need to override, you can view the API documentation for the component you are trying to modify on the Material UI site. For example, here is a listing of the Alert component's CSS [class names](https://material-ui.com/api/alert/#css)
.
When using a success alert, you will have the `.MuiAlert-standardSuccess` class applied to your component. You can override this default style like this.
Copy
New-UDStyle -Style '.MuiAlert-standardSuccess { background-color: red !important; } ' -Content {
New-UDAlert -Text "Hello"
}
The resulting alert will be red instead of the default green.

Alert with Red Background
[PreviousCascading Style Sheets](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/cascading-style-sheets)
[NextCustom Variable Scopes](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes)
Last updated 3 years ago
---
# Marketplace | PowerShell Universal
The [Universal Dashboard Marketplace](https://marketplace.universaldashboard.io/)
is a PowerShell Gallery module aggregator. It synchronizes with the PowerShell Gallery on an hourly basis to find modules that can be used with Universal Dashboard.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace#installing-components-from-the-gallery)
Installing Components from the Gallery
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace#automatic-install-from-the-marketplace)
Automatic Install from the Marketplace
Within PowerShell Universal, you can access the Universal Dashboard Marketplace by navigating to the Dashboards page and clicking the Marketplace button in the top right.

Once installed, the component will be listed on the Dashboard Components page. You can access this by clicking Dashboards and then the Components button in the top right.

To add the component to a dashboard, navigate to the Dashboard Details and then click the Add Component button.

The drawer will show which components are already added and which components can be added. Click the add button to activate the component for the dashboard.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace#manual-install-from-the-powershell-gallery)
Manual Install from the PowerShell Gallery
You can install any of the components from the Marketplace by using the `Install-Module` or `Save-Module` cmdlets provided by `PowerShellGet`. Since the components are just listed on the PowerShell Gallery, you'll be able to use their module name during install.
Copy
Install-Module UniversalDashboard.Helmet
Depending on how the components were installed, you may need to import the module in your dashboard file.
Copy
import-Module UniversalDashboard.Helmet
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace#publishing-to-the-universal-dashboard-marketplace)
Publishing to the Universal Dashboard Marketplace
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
You can follow the directions on the [Building Custom Components](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/custom-components/building-custom-components#publishing-to-the-marketplace)
page on how to publish components to the Universal Dashboard Marketplace.
[PreviousInteraction](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction)
[NextRole Based Access](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access)
Last updated 3 years ago
---
# Custom Variable Scopes | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes#custom-variable-scopes)
Custom Variable Scopes
-----------------------------------------------------------------------------------------------------------------------------------------------
Universal Dashboard exposes two custom variable scopes using custom providers. These providers allow you to store your variables in scopes that make sense for a web application. The cache scope is used to store variables that can be used within any endpoint inside a dashboard. The session scope is used to store variables that can be used for a single user's session of the dashboard.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes#cache-scope)
Cache Scope
Cache scope is used to store a variable that will be available in any endpoint. Cache scope is useful for storing data that may be shown in more than one control or may be time consuming to look up. This could be helpful for querying machine performance counters (e.g. Active Directory, Azure).
Just like any other scope, cache variables are defined with a prefix and a colon separator.
Copy
$Cache:Computers = Get-ADComputer
Once assigned, the `$Cache:Computer` variable is available within any endpoint.
Copy
New-UDMonitor -Title Computers -Endpoint {
$Cache:Computers.Length | Out-UDMonitorData
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes#page-scope)
Page Scope
Page scope stores variables in per browser tab or window. If a new tab is opened or the current one is closed, the state will be removed.
Copy
New-UDForm -Content {
New-UDTextbox -Id 'Name'
} -OnSubmit {
$Page:Name = $EventData.Name
Sync-UDElement -Id 'Name'
}
New-UDDynamic -Content {
New-UDTypography $Page:Name
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes#session-scope)
Session Scope
Session scope is used to store a variable per session. A session is established when a user's browser first visit a dashboard. A cookie is stored in the user's browser that dictates that it is part of the session. Sessions have an idle timeout of 25 minutes.
Just like any other scope, cache variables are defined with a prefix and a colon separator.
Copy
New-UDCheckbox -Label "Show chart" -OnChange {
$Session:ShowChart = $EventData
}
Once assigned, the `$Session:ShowChart` variable is available in dashboard endpoints. Session variables are not available in REST API endpoints or scheduled endpoints.
Copy
New-UDColumn -Endpoint {
if ($Session:ShowChart) {
New-UDChart ...
}
}
Once a session is terminated, the session variables are cleared.
[PreviousStyles](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/styles)
[NextMigrating From Universal Dashboard 2.9](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9)
Last updated 2 years ago
---
# Alerts | PowerShell Universal

An information alert.

An error alert.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/alerts#properties)
Properties
--------------------------------------------------------------------------------------------------
Property
Description
Available Since
Id
The ID of this component.
2.2.0
Message
The message to display within the alert.
2.2.0
Description
The description text to display within the alert.
2.2.0
Type
The type of alert to display. Supports Success, Info, Warning, and Error
2.2.0
[PreviousPages](https://docs.powershelluniversal.com/v3/userinterfaces/pages)
[NextBar Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart)
Last updated 3 years ago
---
# Scheduled Endpoints | PowerShell Universal
We recommend you consider [Scheduled jobs](https://docs.powershelluniversal.com/v3/automation/schedules)
over scheduled endpoints for jobs that require tracking of output, input, history or complex scheduling rules.
Scheduled endpoints allow you to run PowerShell script blocks on a schedule within your dashboards. Scheduled endpoints are more light weight than scheduled jobs but do not provide the same level of functionality. They do not track any history, the output is not logged and the schedules are not visible within the UI.
Scheduled endpoints are useful when loading and caching data that you will only use in your dashboard. Data stored within the dashboard cache is not shared across PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/scheduled-endpoints#scheduling-an-endpoint)
Scheduling an Endpoint
--------------------------------------------------------------------------------------------------------------------------------------------
The below is an example of scheduling an endpoint that runs every 10 seconds and stores information in a cache variable. This type of configuration increases performance of the dashboard for end users since the cache data is returned rather than calling Get-Process with each load of the dashboard.
Copy
$EndpointSchedule = New-UDEndpointSchedule -Every 10 -Second
New-UDEndpoint -Schedule $EndpointSchedule -Endpoint {
$Cache:Processes = Get-Process | Select-Object Name,ID
} | Out-Null
New-UDDashboard -Title 'Test' -Content {
New-UDTable -Data $Cache:Processes
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/scheduled-endpoints#caching-server-wide-data)
Caching Server-Wide Data
You can also use the [server-wide data](https://docs.powershelluniversal.com/v3/platform/cache)
caching features in dashboards. This means that you will be able to access that data throughout PowerShell Universal scripts. In your dashboard, you can load the cache with the scheduled endpoint.
Copy
$EndpointSchedule = New-UDEndpointSchedule -Every 10 -Second
New-UDEndpoint -Schedule $EndpointSchedule -Endpoint {
$Processes = Get-Process | Select-Object Name,ID
Set-PSUCache -Name 'Processes' -Value $Processes
} | Out-Null
New-UDDashboard -Title 'Test' -Content {
}
You can then use the cache data in your API.
Copy
New-PSUEndpoint -Url '/process' -Method Get -Endpoint {
Get-PSUCache -Name 'Processes'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/scheduled-endpoints#api)
API
------------------------------------------------------------------------------------------------------
* [New-UDEndpoint](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDEndpoint.txt)
* [New-UDEndpointSchedule](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-UDEndpointSchedule.txt)
[PreviousRole Based Access](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access)
[NextSessions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions)
Last updated 3 years ago
---
# Role Based Access | PowerShell Universal
This feature requires a [license](https://docs.powershelluniversal.com/v3/licensing)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access#dashboard-roles)
Dashboard Roles
----------------------------------------------------------------------------------------------------------------------------
When dashboard authentication is enabled, you can define the role that a user must be a part of in order to access the dashboard. Roles are configured on the Settings Security page or from within the `roles.ps1` configuration file.

If a user attempts to visit a dashboard that they do not have access to, they will be presented with a Not Authorized page.

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access#pages-roles)
Pages Roles
--------------------------------------------------------------------------------------------------------------------
You can also show or hide pages based on roles. To define a role for a page, use the `-Role` parameter of `New-UDPage`. Only users of the specified role will have access to this page.
Copy
New-UDPage -Role 'Administrators' -Content {
New-UDTypography -Text 'Admins only'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access#usdroles-variable)
$Roles Variable
------------------------------------------------------------------------------------------------------------------------------
In addition to dashboard and page roles, you can also check with roles a user is a part of by using the `$Roles` variable that is available within Dashboards. This variable contains an array of the roles that are assigned to the user.
For example, you could show the `Restart-Computer` button to only Administrators.
Copy
if ($Roles -contains "Administrator") {
New-UDButton -Text 'Restart Server' -OnClick {
Restart-Computer
}
}
[PreviousMarketplace](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace)
[NextScheduled Endpoints](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/scheduled-endpoints)
Last updated 3 years ago
---
# Cascading Style Sheets | PowerShell Universal
You can use a cascading style sheet (CSS) by add a `.css` file to a published folder and then passing it to the `-Stylesheets` parameter for `New-UDDashboard`.
For example, the `dashboard.ps1` file would look like this.
Copy
New-UDDashboard -Title "Server Monitor" -Content {
} -Stylesheets @("/assets/theme.css")
You could then setup a published folder to provide the assets route. This is what the contents of `publishedFolders.ps1` will look like.
Copy
New-PSUPublishedFolder -RequestPath "/assets" -Path "C:\assets"
Within the `C:\assets` folder, you can place any assets you'd like to access on the `/assets` route.

Assets folder
You can then create a style sheet to manipulate whatever portion of the dashboard you'd like.
Copy
.ud-dashboard > div {
background-image: url("/assets/image.jpeg");
}
This produces a dashboard with a background image of Austin the dog sleeping in a pile of dirt.

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/cascading-style-sheets#determining-the-correct-class-names)
Determining the Correct Class Names
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Every Material UI component has a series of global class names that you can use to apply styles throughout your dashboard. To determine the correct class names, you can view the a particular component's API documentation. There is a list of the global class names that apply to that component.
For example, here is the [CSS documentation for the Alert component](https://material-ui.com/api/alert/#css)
.
Within your CSS file, you can use these class names to override styles throughout your dashboard. If you wanted to set all success alerts to have a red background, you could create a CSS file like this.
Copy
.MuiAlert-standardSuccess { background-color: red !important; }
[PreviousThemes](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes)
[NextStyles](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/styles)
Last updated 3 years ago
---
# Button | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button#invoke-a-script-with-a-button)
Invoke a Script with a Button
----------------------------------------------------------------------------------------------------------------------------------------
You can invoke a script with a button. This will allow you to specify arguments, environment and run as credentials for the script.
Set the target of the button to script and select the script you would like to use. You can then select the environment and run as credentials. Finally, specify parameters to pass to the script.

Clicking the button will run the script and show a toast notification after the click.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button#invoke-an-api-with-a-button)
Invoke an API with a Button
------------------------------------------------------------------------------------------------------------------------------------
Set the target to API and select the endpoint that you want to invoke. The endpoint must be a POST endpoint. Parameters can be specified. Parameters will be passed as part of a JSON object.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button#customize-the-button)
Customize the Button
----------------------------------------------------------------------------------------------------------------------
Buttons support customizing the text and icon shown within the button.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button#properties)
Properties
--------------------------------------------------------------------------------------------------
Property
Description
Available Since
Id
The ID of this component
2.2.0
Target Type
The type of target. Supports Script and API.
2.2.0
Target
The script or API to invoke.
2.2.0
Run As
The run as credential to use when invoking a script. Not used for APIs.
2.2.0
Environment
The environment to run the script within. Not used for APIs.
2.2.0
Parameters
Name value pairs of parameters. For scripts, they are passed as parameters. For APIs, they are passed as a single JSON object.
2.2.0
Text
The text to display within the button
2.2.0
Icon
The icon to display within the button
2.2.0
Toast on Success
Shows a success toast message when the button successfully calls the target.
2.2.0
Toast on Error
Shows a failure toast message when the button fails to call the target.
2.2.0
[PreviousBar Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart)
[NextCard](https://docs.powershelluniversal.com/v3/userinterfaces/pages/card)
Last updated 3 years ago
---
# Migrating From Universal Dashboard 2.9 | PowerShell Universal
PowerShell Universal Dashboard v2.9 is a PowerShell module that allows you to create dashboard with PowerShell script. It is the predecessor to PowerShell Universal. The technology the enabled UD has been migrated into PowerShell Universal. You should be able to run the same PowerShell scripts in PowerShell Universal that you would in Universal Dashboard with some minor modifications.
When looking at the [Universal Dashboard v2 documentation](https://docs.universaldashboard.io/)
, you can click the link at the top of each page to take you to the corresponding documentation for PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#migrating-from-universal-dashboard-to-powershell-universal)
Migrating from Universal dashboard to PowerShell Universal
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#no-need-to-call-start-uddashboard)
No need to call Start-UDDashboard
In Universal, all you need to do is return the result of New-UDDashboard from your script. There is no need to call Start-UDDashboard. The configuration of the webserver is taken place using the PSU `appsetting.json` file.
Copy
New-UDDashboard -Title 'My dashboard' -Content {
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#no-need-to-call-new-udendpointinitialization)
No need to call New-UDEndpointInitialization
This cmdlet has been removed from Universal Dashboard. There is no longer a need to call it.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#scheduled-endpoints)
Scheduled Endpoints
You do not need to pass the value of a scheduled endpoint to anything. You can just call `New-UDEndpoint` with a endpoint schedule and it will automatically be registered with PSU.
Copy
$Schedule = New-UDEndpointSchedule -Every 10 -Minute
$Endpoint = New-UDEndpoint -Schedule $Schedule -Endpoint {}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#rest-apis)
REST APIs
To learn more about APIs, [click here](https://docs.powershelluniversal.com/v3/api/about)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#authentication-and-authorization)
Authentication and Authorization
Authentication and authorization are now handled by PSU and there is no need to configure UD login pages. Authentication and authorization are configured with the PSU `appsettings.json` file. Dashboard's themselves can be either authenticated or not authenticated. A license is required to enable authenticated dashboards.
To enable role-based access controls, you can assign roles to pages and use the automatic `$Roles` variable to check which roles the user is a part of. The `$User` variable will provide the name of the user.
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#authorization-policies)
Authorization Policies
Authorizations policies in Universal work very similar to the ones in Universal Dashboard, you will define them using the `New-PSURole` cmdlet. When you define the role, you have the option to define a policy that will assign that role automatically to a user.
For example, let's adjust a claims policy from Universal Dashboard for Universal.
**Universal Dashboard**
Copy
$AuthorizationPolicy = New-UDAuthorizationPolicy -Name "Policy" -Endpoint {
param($User)
$User.HasClaim("group", "administrator")
}
**Universal**
Copy
New-PSURole -Name 'User' -Policy {
param($User)
$User.Claims | Where-Object { $_.Type -eq 'group' -and $_.Value -eq 'administrator' }
}
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#enforcing-roles)
Enforcing Roles
Much like the `Get-UDAuthorizationPolicy` cmdlet in Universal Dashboard, you also have access to the assigned roles for users in Universal. Simply check the `$Roles` variable to see which roles the user has.
Copy
PS C:\Users\adamr> $Roles = @('Administrator')
PS C:\Users\adamr> if ($Roles -contains 'Administrator') { $true }
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#published-folders)
Published Folders
[Click here](https://docs.powershelluniversal.com/v3/platform/published-folders)
to learn more about Published Folders in PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#migrating-to-universal-dashboard-v3)
Migrating to Universal Dashboard v3
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This section contains migration information for upgrading from UDv2 to UDv3. They are vastly different frameworks and will require rewriting your dashboard. Many of the concepts are the same.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#pages)
Pages
Pages have a different behavior in v3. All pages are dynamic pages. This means that you don't have to worry about whether a page will be generated at run time or doing start up. Pages are always generated during runtime.
If you have a page such as this one:
Copy
New-UDPage -Url "/myPage/:owner" -Endpoint {
param($owner)
}
You can convert it to a v3 page by changing the syntax to:
Copy
New-UDPage -Name 'myPage' -Url "/myPage/:owner" -Content {
param($owner)
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#new-udtable-formerly-udgrid-and-udtable)
New-UDTable (formerly UDGrid and UDTable)
Rather than having two cmdlets for tables (New-UDTable and New-UDGrid). The New-UDTable in v3 provides the ability to display data in a table, filter, page, and sort it. It supports both client and server-side processing.
You can view examples of the [table on GitHub](https://github.com/ironmansoftware/universal-dashboard/blob/master/src/v3/example/pages/data-display/table.ps1)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#new-uddynamic)
New-UDDynamic
Unlike in v3, components do not have `-Endpoint` and `-Content` parameters. Each component will instead simply have a `-Content` parameter. To achieve dynamic sections of a page, you can instead use the `New-UDDynamic` cmdlet. This cmdlets let you define an entire section of a page as dynamic. It also provides auto refresh functionality so you can refresh sections of a page all at once.
Copy
New-UDDynamic -Content {
New-UDTypography -Text (Get-Date)
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#new-udgrid)
New-UDGrid
New-UDGrid allows you to define a grid layout using the Material UI library. You use this single cmdlet to define rows and columns within your dashboard.
You can view examples of the [grid on GitHub](https://github.com/ironmansoftware/universal-dashboard/blob/master/src/v3/example/pages/layout/grid.ps1)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#new-udform-formerly-udinput)
New-UDForm (formerly UDInput)
`New-UDInput` has been replaced by `New-UDForm`. The UDForm component allows far more configuration that UDInput did. You will use the standard controls like UDTextbox, UDCheckbox, and UDSelect instead of New-UDInputField. This means that there are a single set of input cmdlets to use for UD.
All of the input control examples can be [found on GitHub](https://github.com/ironmansoftware/universal-dashboard/tree/master/src/v3/example/pages/inputs)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#navigation)
Navigation
Instead of using New-UDSideNav, you will now use a combination of New-UDAppbar and New-UDDrawer. When New-UDAppBar is used with the default position, it will overlay the AppBar at the top of the page. You can then specify a drawer to customize the navigation experience within your dashboard.
You can see examples of how to do [navigation on GitHub](https://github.com/ironmansoftware/universal-dashboard/blob/master/src/v3/example/pages/surfaces/appbar.ps1)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#nivo-and-sparklines-are-now-open-source)
Nivo and Sparklines are now open source
The Nivo and sparklines controls are now open source and on the Universal Dashboard repository. You can now use them without purchasing a license.
For more examples of Nivo and sparklines controls, [see GitHub](https://github.com/ironmansoftware/universal-dashboard/tree/master/src/v3/example/pages/charts)
.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9#map-is-now-open-source)
Map is now open source
The map control is also open source and on GitHub.
You can find examples [on GitHub](https://github.com/ironmansoftware/universal-dashboard/blob/master/src/v3/example/pages/data-display/map.ps1)
.
[PreviousCustom Variable Scopes](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/custom-variable-scopes)
[NextPages](https://docs.powershelluniversal.com/v3/userinterfaces/pages)
Last updated 3 years ago
---
# Card | PowerShell Universal
Cards contain a title and content text.

A simple card on a page.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/card#data-source)
Data Source
--------------------------------------------------------------------------------------------------
You can load data from an API endpoint or job. The data properties will be available as variables within your text.
For example, if you may have an endpoint that returns data like the following.
Copy
@{
FirstName = "Adam"
LastName = "Driscoll"
}
You could then use the following variables within the title and content text.
Copy
Hello, $FirstName $LastName!
[PreviousButton](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button)
[NextForm](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form)
Last updated 3 years ago
---
# iFrame | PowerShell Universal
Available in PowerShell Universal 2.5 or later.
Iframes provide the ability to nest another website within the page. The is especially useful if you wish to embed a dashboard within a page.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/iframe#embed-a-dashboard-in-a-page)
Embed a Dashboard in a Page
------------------------------------------------------------------------------------------------------------------------------------
To embed a dashboard in a page, assume we have a dashboard that is defined such as this. This dashboard returns a table of services. It uses the `-Blank` parameter on `New-UDPage` to remove the header. This dashboard is configured with a base URL of `/embed`
Copy
New-UDDashboard -Title "Services" -Pages @(
New-UDPage -Name 'Table' -Content {
New-UDTable -Data (Get-Service)
} -Blank
)
Add a new IFrame component to the page and within the properties of the page, set the URL to the base URL of the dashboard.

When the page loads, it will load the dashboard and display it within the page.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/iframe#limitations)
Limitations
When you embed multiple dashboards within a page they will be treated an individual dashboards and will not communicate event handling code. This means that display toasts and modals will appear within the IFrame and not in the parent code.
[PreviousForm](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form)
[NextImage](https://docs.powershelluniversal.com/v3/userinterfaces/pages/image)
Last updated 3 years ago
---
# Image | PowerShell Universal
Images are simple components that just display an image on the page.
Property
Description
Available Since
Id
The ID of this component
2.2.0
URL
The URL of the component. This can be a relative URL to an image stored in a Published Folder.
2.2.0
[PreviousiFrame](https://docs.powershelluniversal.com/v3/userinterfaces/pages/iframe)
[NextLine Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart)
Last updated 3 years ago
---
# Interaction | PowerShell Universal
Universal Dashboard enables the ability to create interactive websites with PowerShell. There are several cmdlets that have been implemented to provide feedback to the user, update components and read the state of components.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#clipboard)
Clipboard
----------------------------------------------------------------------------------------------------------
You can set string data into the user's clipboard with `Set-UDClipboard`.
Copy
New-UDButton -Text 'Clipboard' -OnClick {
Set-UDClipboard -Data 'Hello, there!'
}
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#api)
API
* [Set-UDClipboard](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-UDClipboard.txt)
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#downloads)
Downloads
----------------------------------------------------------------------------------------------------------
You can start a download within the user's browser by using `Start-UDDownload`. Due to security of web browsers, the user will need to take an action (like click a button) to allow the download to take place. `Start-UDDownload` is not suited for large file downloads.
Copy
New-UDButton -Text 'Download' -OnClick {
Start-UDDownload -StringData 'Hello, World!'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#event-handlers)
Event Handlers
--------------------------------------------------------------------------------------------------------------------
Many components support event handlers in the form of script blocks. You may also see these referred to as endpoints as that is what they were called in Universal Dashboard v2. These event handlers allow you to invoke PowerShell scripts when certain actions take place on the page.
For example, you may have a button click that calls an event handler. This button will show a toast when clicked. You can include any valid PowerShell cmdlet within the event handler code.
Copy
New-UDButton -Text 'Click Me' -OnClick {
Show-UDToast 'Hello!'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#variable-scope)
Variable Scope
Variables are automatically scoped into event handlers. You will be able to access variables that you define outside of the variable within the event handler.
Copy
$MyVariable = "Hello!"
New-UDButton -Text 'Click Me' -OnClick {
Show-UDToast $MyVariable
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#event-data)
Event Data
Some event handlers handlers will provide data as a string or as a hashtable. This depends on the event handler you are using. For example, the `New-UDButton` `-OnClick` event handler does not provide any data. On the other hand, the `New-UDSelect` `-OnChange` will provider event data.
You can access the event data by using the `$Body` variable to access the data as a string (sometimes formatted as JSON) or as a hashtable by using the `$EventData` variable.
Copy
New-UDSelect -Option {
New-UDSelectOption -Name 'One' -Value 1
New-UDSelectOption -Name 'Two' -Value 2
New-UDSelectOption -Name 'Three' -Value 3
} -OnChange { Show-UDToast -Message $EventData }
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#forms)
Forms
--------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#submit-a-form)
Submit a Form
You can force a form to submit using the `Invoke-UDForm` cmdlet. You can optionally chose to enforce validation by including the `-Validate` parameter.
Copy
New-UDForm -Id 'form' -Content {
New-UDTextbox -Id 'Text' -Label 'Submit Me'
} -OnSubmit {
Show-UDToast "Hello!"
}
New-UDButton -Text "Submit Form" -OnClick {
Invoke-UDForm -Id 'form'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#validate-a-form)
Validate a Form
You can force a form to validate by using `Test-UDForm`.
Copy
New-UDForm -Id 'form' -Content {
New-UDTextbox -Id 'Text' -Label 'Submit Me'
} -OnSubmit {
Show-UDToast "Hello!"
} -OnValidate {
New-UDValidationResult
}
New-UDButton -Text "Submit Form" -OnClick {
Test-UDForm -Id 'form'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#javascript)
JavaScript
------------------------------------------------------------------------------------------------------------
You can invoke JavaScript from PowerShell by using the `Invoke-UDJavaScript` cmdlet.
Copy
New-UDButton -Text 'Alert Me' -OnClick {
Invoke-UDJavaScript -JavaScript 'alert("Hello!")'
}
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#api-1)
**API**
* [Invoke-UDJavaScript](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Invoke-UDJavaScript.txt)
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#toast)
Toast
--------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#show-a-toast)
Show a toast
You can use the `Show-UDToast` cmdlet to create a toast message that will appear on the end user's webpage. It happens over a websocket and will show the toast immediately as it is called.
Copy
Show-UDToast -Message 'Hello, World!'
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#show-as-toast-with-an-icon)
Show as toast with an Icon
Toasts support icons as strings. You can use all the FontAwesome v5 icons.
Copy
Show-UDToast -Icon "Ad" -Message "Test"
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#hide-a-toast)
Hide a toast
Hides a toast based on the specified ID.
Copy
Show-UDToast -Message 'Hello, World!' -Id 'Toast' -Duration 30000
New-UDButton -Text 'Click' -OnClick {
Hide-UDToast -Id 'Toast'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#api-2)
API
* [Show-UDToast](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Show-UDToast.txt)
* [Hide-UDToast](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Hide-UDToast.txt)
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#redirect)
Redirect
--------------------------------------------------------------------------------------------------------
You can redirect users to different pages using the `Invoke-UDRedirect` cmdlet. It happens over a websocket and will redirect as soon as the cmdlet is called.
Copy
Invoke-UDRedirect http://www.ironmansoftware.com
`Invoke-UDRedirect` will automatically redirect to pages in the dashboard when using a relative path.
Copy
Invoke-UDRedirect '/page1'
If you'd like to redirect to a local path outside of the dashboard, you can use the `-Native` parameter.
Copy
Invoke-UDRedirect '/publishedFolder/test.txt' -Native
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#api-3)
API
* [Invoke-UDRedirect](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Invoke-UDRedirect.txt)
You can open a modal using the `Show-UDModal` cmdlet. It will open as soon as you call it. You can include whatever components you like within the modal.
Read more about [Modals here](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/feedback/modal)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#managing-component-state)
Managing Component State
----------------------------------------------------------------------------------------------------------------------------------------
You can manage component state dynamically by using the UDElement commands.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#getting-component-state)
Getting Component State
You can receive the state of an element using `Get-UDElement` . The state will be returned as a hashtable. This is primarily useful for input components.
Copy
$Value = (Get-UDElement -Id 'txtExample').value
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#setting-component-state)
Setting Component State
Alternatively, you can set component state using `Set-UDElement` . You will need to specify an ID and a hashtable of properties to set on the component. All built in components support Set-UDElement.
Copy
New-UDTextbox -Id 'textbox'
New-UDButton -Text 'Click' -OnClick {
Set-UDElement -Id 'textbox' -Properties @{
Value = 'My Value'
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#removing-a-component)
Removing a Component
You can remove components from the page using `Remove-UDElement` . The component will no longer appear on the page.
Copy
Remove-UDComponent -Id 'txtExample'
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#adding-a-component)
Adding a component
Add a child component to an existing parent component.
Copy
New-UDElement -Id 'myDiv' -Tag div
New-UDButton -Text 'Click' -OnClick {
Add-UDElement -ParentId 'myDiv' -Content {
New-UDTypography -Text 'Hi'
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#clear-a-component)
Clear a component
You can remove all the children components from an component by using `Clear-UDElement`.
Copy
New-UDElement -Id 'myDiv' -Tag div
New-UDButton -Text 'Click' -OnClick {
Add-UDElement -ParentId 'myDiv' -Content {
New-UDTypography -Text 'Hi'
}
Add-UDElement -ParentId 'myDiv' -Content {
New-UDTypography -Text 'Hi'
}
Add-UDElement -ParentId 'myDiv' -Content {
New-UDTypography -Text 'Hi'
}
}
New-UDButton -Text 'Clear' -OnClick {
Clear-UDElement -Id 'myDiv'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#reloading-a-component)
Reloading a Component
Some components support reloading. You can trigger a reload of a component using `Sync-UDElement`.
Copy
New-UDDynamic -Id 'reloadMe' -Content {
Get-Date
}
New-UDButton -Text 'Reload' -OnClick {
Sync-UDElement -Id 'reloadMe'
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#select-a-component)
Select a component
You can select a component with `Select-UDElement`.
Copy
New-UDElement -Id 'txt' -Tag input -Properties @{ type = text }
New-UDButton -Text 'Select' -OnClick {
Select-UDElement -Id 'txt' -ScrollToElement
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#powershell-host-integration)
PowerShell Host Integration
----------------------------------------------------------------------------------------------------------------------------------------------
Dashboards integrate directly with the PowerShell host to provide features based on standard cmdlets.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#read-host)
Read-Host
Using the `Read-Host` cmdlet will cause a dialog to show on the user's dashboard. The text entered will be returned by the cmdlet.
Copy
$Text = Read-Host 'Enter Some Text'
Show-UDToast $Text

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#get-credential)
Get-Credential
Using `Get-Credential` will cause a dialog to show that accepts a username and password. A `PSCredential` object will be returned from the cmdlet.
Copy
Get-Credential -UserName "adam"

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#write-progress)
Write-Progress
Cmdlets that use the progress stream or the use of the `Write-Progress` cmdlet will result in a progress dialog being shown. The popup will show the activity, percent completed and current operation.
Copy
1..100 | ForEach-Object {
Write-Progress -PercentComplete $_ -Activity 'Processing...' -CurrentOperation "User $_"
Start-Sleep -Milliseconds 500
}

You can disable the Write-Progress integration by setting the `$ProgressPreference` to `SilentlyContinue`.
Copy
$ProgressPreference = 'SilentlyContinue'
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#prompt-for-choice)
Prompt For Choice
You can use the `$Host.UI.PromptForChoice` function to display a multi-select dialog.
Copy
$Title = "Welcome"
$Info = "Just to Demo Prompt for Choice"
$options = [System.Management.Automation.Host.ChoiceDescription[]] @("Power", "Shell", "Quit")
[int]$defaultchoice = 2
$opt = $host.UI.PromptForChoice($Title , $Info , $Options, $defaultchoice)
switch ($opt) {
0 { Show-UDToast "Power" }
1 { Show-UDToast "Shell" }
2 { Show-UDToast "Good Bye!!!" }
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/interaction#api-4)
API
------------------------------------------------------------------------------------------------
* [Get-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-UDElement.txt)
* [Set-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-UDElement.txt)
* [Clear-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Clear-UDElement.txt)
* [Remove-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-UDElement.txt)
* [Sync-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Sync-UDElement.txt)
* [Select-UDElement](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Select-UDElement.txt)
[PreviousExpansion Panel](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/components/surfaces/expansion-panel)
[NextMarketplace](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/marketplace)
Last updated 2 years ago
---
# Bar Chart | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart#about)
About
-------------------------------------------------------------------------------------------
Bar charts can retrieve output from scripts and APIs to display the data in a chart.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart#display-data-from-an-api)
Display Data from an API
You will need to return an array of JSON objects from your API in order to use a bar chart. An example would be returning a list of hashtables serialized to JSON.
Copy
@(
@{
Name = "Name1"
Value = Get-Random
}
@{
Name = "Name2"
Value = Get-Random
}
@{
Name = "Name3"
Value = Get-Random
}
) | ConvertTo-Json
In this example, you would configure the data source to an API and select your API endpoint. You would then specify Name as the Y axis and Value as the X axis.


The resulting chart contains the data from the API. Each time the page is loaded, the API is called.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart#display-data-from-a-script)
Display Data from a Script
You will need to return PSCustomObjects, objects or hashtables from your script in order to display a chart from a script.
Copy
@(
@{
Name = "Name1"
Value = Get-Random
}
@{
Name = "Name2"
Value = Get-Random
}
@{
Name = "Name3"
Value = Get-Random
}
)
You will need to set the data source to script and select the script you want to retrieve data for.

You will need to set the Y and X axis to the properties of the object returned from the script.

The chart will appear on the page like this. Loading the page will not call the script again. It will load the result of the last time the script ran.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/bar-chart#properties)
Properties
-----------------------------------------------------------------------------------------------------
Property
Description
Available Since
Id
The ID of this component
2.2.0
X Axis Field
The field to use as the X Axis for data within the chart.
2.2.0
Y Axis Field
The field to use as the Y Axis for data within the chart.
2.2.0
Data Source Type
Whether to use a script or API as a data source.
2.2.0
Data Source
The script or API to use as data for the chart.
2.2.0
Color
The bar color to use for the chart.
2.2.0
Scrollbar
Whether to display a scrollbar when there are many items in the chart.
2.2.0
[PreviousAlerts](https://docs.powershelluniversal.com/v3/userinterfaces/pages/alerts)
[NextButton](https://docs.powershelluniversal.com/v3/userinterfaces/pages/button)
Last updated 3 years ago
---
# Pages | PowerShell Universal
Pages allow you to create basic websites that do not require any coding of the user interface. You can drag and drop UI components on to the designer and set properties of each component. Components can interact with APIs and Scripts that are defined within Universal.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#adding-a-page)
Adding a Page
-------------------------------------------------------------------------------------------------
To add a page, navigate to User Interfaces \\ Pages within the admin console. Click the Create New Page button to create a page.
The name of the page will also be the URL used to access the page.

Pages can take advantage of role based access. You can turn on authentication for a page and limit the access to the page to users based on role. This feature requires a license.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#editing-a-page)
Editing a Page
---------------------------------------------------------------------------------------------------
To edit the content of the page, you can view the page as an administrator. When you view the page, you will have access to an edit button for managing the components and layout of the page.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#adding-a-component)
Adding a Component
-----------------------------------------------------------------------------------------------------------
To add a component, click the Toolbox button and select the component to add. Properties for a component can be set by clicking the properties button on the component and editing the required and optional properties.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#layouts)
Layouts
-------------------------------------------------------------------------------------
Layouts are setup by resizing and dragging components around the designer surface. Layouts are responsive. If you want to setup layouts for smaller screens, reduce the width of your window and setup a new layout.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#invoking-scripts-and-apis)
Invoking Scripts and APIs
-------------------------------------------------------------------------------------------------------------------------
Certain components can interact with scripts or API endpoints. These include buttons, forms, statistics and tables. You can configure the script or API that is invoked as well as the parameters that are passed to those targets.
This example uses a script to populate a table.

This example invokes a script when a button is clicked.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#grouping-pages)
Grouping Pages
---------------------------------------------------------------------------------------------------
Grouping pages will create nested navigation within the page section. Select a group in the page properties. Matching pages will be displayed in that group.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#page-urls)
Page URLs
-----------------------------------------------------------------------------------------
By default, the page URL will be the Name of the page. So for example, if the page's name was Services the URL will be `/Services`.
You can customize the URL in the page properties.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#default-url)
Default URL
You can change the default URL of the PowerShell Universal instance by setting the page URL to `/` . When users login or visit the server name directly, they will not be directed to `/admin` but rather the page defined with `/`.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages#configuration-files)
Configuration Files
-------------------------------------------------------------------------------------------------------------
Pages are stored as XML. Unlike dashboards, they do not allow for direct programmatic configuration. The layout and components are static but can interact with APIs and scripts.
Copy
All
[PreviousMigrating From Universal Dashboard 2.9](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/migrating-from-universal-dashboard-2.9)
[NextAlerts](https://docs.powershelluniversal.com/v3/userinterfaces/pages/alerts)
Last updated 3 years ago
---
# Liquid Chart | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/liquid-chart#display-a-chart-from-an-api)
Display a chart from an API
------------------------------------------------------------------------------------------------------------------------------------------
An API that provides data to a chart needs to return a single number between 0.0 and 1.00.
This example returns a random percentage.
Copy
(1..100 | Get-Random) / 100
Select an API from the list of available APIs.

The liquid chart will display the value.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/liquid-chart#display-a-chart-from-a-script)
Display a chart from a Script
----------------------------------------------------------------------------------------------------------------------------------------------
You can display a liquid chart with data from a script. You should return a single value between 0.0 and 1.00.
This script we are executing in this example returns a random percentage.
Copy
(1..100 | Get-Random) / 100
Select the script as the data source.

The chart will display based on the data returned.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/liquid-chart#properties)
Properties
--------------------------------------------------------------------------------------------------------
Properties
Description
Available Since
Id
The ID of this component
2.2.0
Data Source Type
The data source type for this chart. Accepts scripts or APIs.
2.2.0
Data Source
The data source for this chart.
2.2.0
Color
The color of the chart.
2.2.0
[PreviousLine Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart)
[NextParagraph](https://docs.powershelluniversal.com/v3/userinterfaces/pages/paragraph)
Last updated 3 years ago
---
# Line Chart | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart#about)
About
--------------------------------------------------------------------------------------------
Line charts can retrieve output from scripts and APIs to display the data in a chart.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart#display-data-from-an-api)
Display Data from an API
You will need to return an array of JSON objects from your API in order to use a bar chart. An example would be returning a list of hashtables serialized to JSON.
Copy
@(
@{
Name = "Name1"
Value = Get-Random
}
@{
Name = "Name2"
Value = Get-Random
}
@{
Name = "Name3"
Value = Get-Random
}
) | ConvertTo-Json
In this example, you would configure the data source to an API and select your API endpoint.

You would then specify Name as the X axis and Value as the Y axis.

The resulting chart contains the data from the API. Each time the page is loaded, the API is called.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart#display-data-from-an-api-1)
Display Data from a Script
You will need to return PSCustomObjects, objects or hashtables from your script in order to display a chart from a script.
Copy
@(
@{
Name = "Name1"
Value = Get-Random
}
@{
Name = "Name2"
Value = Get-Random
}
@{
Name = "Name3"
Value = Get-Random
}
)
You will need to set the data source to script and select the script you want to retrieve data for.

You will need to set the Y and X axis to the properties of the object returned from the script.
The chart will appear on the page like this. Loading the page will not call the script again. It will load the result of the last time the script ran.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/line-chart#properties)
Properties
------------------------------------------------------------------------------------------------------
Property
Description
Available Since
Id
The ID of this component
2.2.0
X Axis Field
The field to use as the X Axis for data within the chart.
2.2.0
Y Axis Field
The field to use as the Y Axis for data within the chart.
2.2.0
Data Source Type
Whether to use a script or API as a data source.
2.2.0
Data Source
The script or API to use as data for the chart.
2.2.0
Color
The bar color to use for the chart.
2.2.0
[PreviousImage](https://docs.powershelluniversal.com/v3/userinterfaces/pages/image)
[NextLiquid Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/liquid-chart)
Last updated 3 years ago
---
# Paragraph | PowerShell Universal

Paragraphs display text with different styles depending on properties.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/paragraph#properties)
Properties
-----------------------------------------------------------------------------------------------------
Property
Description
Available Since
ID
The ID of this component
2.2.0
Value
The text to display within the paragraph.
2.2.0
Code
Whether to display as code.
2.2.0
Copyable
Whether the text is copyable
2.2.0
Type
The type of text to display. Supports Default, Secondary, Success, Warning, and Danger
2.2.0
[PreviousLiquid Chart](https://docs.powershelluniversal.com/v3/userinterfaces/pages/liquid-chart)
[NextStatistic](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic)
Last updated 3 years ago
---
# Themes | PowerShell Universal
Universal Dashboard v3 is built on Material UI. Material UI provides a [built-in theme system](https://material-ui.com/customization/theming/)
that UD now takes advantage of. You can utilize this theme system by providing a hashtable of options to the `New-UDDashboard` 's `-Theme` parameter.
Here's an example of changing the theme's main color.
Copy
$Theme = @{
palette = @{
primary = @{
main = '#111111'
}
}
}
New-UDDashboard -Theme $Theme -Title 'Hello' -Content {
New-UDButton -Text "Test " -OnClick {
Show-UDToast -Message 'HEllo'
}
}
Note that when specifying keys that require a number, ensure that the key is specified as a string.
Copy
grey = @{
'50' = '#fafafa'
'100' = '#f5f5f5'
'200' = '#eeeeee'
'300' = '#e0e0e0'
'400' = '#bdbdbd'
'500' = '#9e9e9e'
'600' = '#757575'
'700' = '#616161'
'800' = '#424242'
'900' = '#212121'
A100 = '#d5d5d5'
A200 = '#aaaaaa'
A400 = '#303030'
A700 = '#616161'
contrastThreshold = '3'
getContrastText = 'f E()'
augmentColor = 'f B()'
tonalOffset = '0.2'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#setting-the-default-theme)
Setting the default theme
-------------------------------------------------------------------------------------------------------------------------------------
You can set the default theme to either Light or Dark using the `-DefaultTheme` parameter.
Copy
New-UDDashboard -Title 'Hello' -Content {
New-UDButton -Text "Test " -OnClick {
Show-UDToast -Message 'HEllo'
}
} -DefaultTheme dark
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#changing-the-background-color)
Changing the background color
---------------------------------------------------------------------------------------------------------------------------------------------
You can change the page background color by setting the background default color. To adjust the header background color, set the primary main color.
Copy
$Theme = @{
palette = @{
primary = @{
main = '#876a38'
}
background = @{
default = '#876a38'
}
}
}
New-UDDashboard -Theme $Theme -Title 'Hello' -Content {
New-UDButton -Text 'Hello'
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#supporting-dark-and-light-palettes)
Supporting dark and light palettes
-------------------------------------------------------------------------------------------------------------------------------------------------------
To support dark and light palettes, you can define a dark and light sections in your hashtable. They have the same properties as a theme.
Copy
$Theme = @{
light = @{
palette = @{
primary = @{
main = "#fff"
}
}
}
dark = @{
palette = @{
primary = @{
main = "#333"
}
}
}
}
New-UDDashboard -Theme $Theme -Title 'Hello' -Content {
New-UDButton -Text 'Hello'
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#changing-the-font-size)
Changing the font size
-------------------------------------------------------------------------------------------------------------------------------
To change the font size, set the typography fontSize property.
Copy
$Theme = @{
typography = @{
fontSize = 20
}
}
New-UDDashboard -Theme $Theme -Title 'Hello' -Content {
New-UDButton -Text 'Hello'
}

[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#changing-default-button-colors)
Changing default button colors
-----------------------------------------------------------------------------------------------------------------------------------------------
Copy
$Theme = @{
palette = @{
grey = @{
'300' = '#000'
}
}
}
New-UDDashboard -Theme $Theme -Title 'Hello' -Content {
New-UDButton -Text 'Small Button'
}

For a full list of options available for the theme system, you can look at the [default theme for Material UI](https://material-ui.com/customization/default-theme/)
.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#component-overrides)
Component Overrides
-------------------------------------------------------------------------------------------------------------------------
You can override any component CSS value using the theme engine. In order to override a component's base theming, you will need to identify the CSS class name applied to that element.
To identify a component's CSS classes, use the developer tools of your browser. Right click on the component you wish to style and click Inspect Element.
This will highlight the HTML elements that make up that component. In the image below, you will see we have numerous CSS classes being applied such as:
* MuiButtonBase-root
* MuiButton-root
* MuiButton-label
* MuiTouchRipple-root

In order to override these various elements, you will need to add an `overrides` key to your theme.
Copy
$Theme = @{
overrides = @{
}
}
Next, you'll need to add keys to the overrides for each element you wish to modify. Notice that I have not included the portion of the class name after the hyphen.
Copy
$Theme = @{
overrides = @{
MuiButton = @{
}
}
}
Now, add the subitems you wish to modify to the class name.
Copy
$Theme = @{
overrides = @{
MuiButton = @{
root = @{
}
label = @{
}
}
}
}
The last step is to define the CSS properties you wish to apply to elements that use these classes.
Copy
$Theme = @{
overrides = @{
MuiButton = @{
root = @{
padding = 20
}
label = @{
fontSize = 40
}
}
}
}
For more examples, look at the Onepirate and Paperbase themes below that include many component overrides.
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#example-themes)
Example Themes
---------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#sand)
Sand

Sand Theme
Copy
$Theme = @{
palette = @{
primary = @{
light = '#ffe8d6'
main = '#ddbea9'
dark = '#cb997e'
}
secondary = @{
light = '#b7b7a4'
main = '#a5a58d'
dark = '#6b705c'
}
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#compliment)
Compliment

Copy
$Theme = @{
palette = @{
primary = @{
light = '#e9c46a'
main = '#2a9d8f'
dark = '#264653'
}
secondary = @{
light = '#e9c46a'
main = '#f4a261'
dark = '#e76f51'
}
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#pastel)
Pastel

Copy
$Theme = @{
palette = @{
primary = @{
light = '#ffcdb2'
main = '#ffb4a2'
dark = '#e5989b'
}
secondary = @{
light = '#e5989b'
main = '#b5838d'
dark = '#6d6875'
}
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#onepirate)
Onepirate

Based on the Material UI theme, [Onepirate](https://material-ui.com/store/previews/onepirate/)
.
Copy
$Theme = @{
palette = @{
primary = @{
light = '#69696a'
main = '#28282a'
dark = '#1e1e1f'
}
secondary = @{
light = '#fff5f8'
main = '#ff3366'
dark = '#e62958'
}
warning = @{
main = '#ffc071'
dark = '#ffb25e'
}
error = @{
xLight = '#ffebee'
main = '#f44336'
dark = '#d32f2f'
}
success = @{
xLight = '#e8f5e9'
main = '#4caf50'
dark = '#388e3c'
}
}
typography = @{
fontFamily = "'Work Sans', sans-serif"
fontSize = 14
fontWeightLight = 300
fontWeightRegular = 400
fontWeightMedium = 700
fontFamilySecondary = "'Roboto Condensed', sans-serif"
h1 = @{
letterSpacing = 0
fontSize = 60
}
h2 = @{
fontSize = 48
}
h3 = @{
fontSize = 42
}
h4 = @{
fontSize = 36
}
h5 = @{
fontSize = 20
fontWeight = 100
}
h6 = @{
fontSize = 18
}
subtitle1 = @{
fontSize = 18
}
body = @{
fontSize = 16
}
body2 = @{
fontSize = 14
}
}
overrides = @{
MuiButton = @{
root = @{
borderRadius = 0
fontWeight = 300
fontFamily = "'Roboto Condensed', sans-serif"
padding = 10
fontSize = 14
boxShadow = 'none'
}
}
MuiInput = @{
root = @{
padding = 0
backgroundColor = 'white'
'label + &' = @{
marginTop = 3
}
}
input = @{
fontSize = 16
padding = 16
border = '1px solid #e9ddd0'
'&:focus' = @{
borderColor = '#ff3366'
}
}
'underline:after' = @{
borderBottom = 'none'
}
}
MuiInputLabel = @{
root = @{
fontSize = 18
}
}
MuiFormControl = @{
root = @{
border = 'none'
}
}
MuiCard = @{
root = @{
boxShadow = 'none'
}
}
MuiPaper = @{
root = @{
backgroundColor = '#fff5f8'
}
rounded = @{
borderRadius = 0
}
}
}
}
The dashboard used to generate the above image is included below.
Copy
New-UDDashboard -Theme $theme -Title "Onepirate" -Content {
New-UDTypography -Text 'Upgrade your Sundays' -Variant h2 -Align Center
New-UDTypography -Text 'Enjoy secret offers up to -70% off the best luxury hotels every Sunday.' -Variant h5 -Align Center
New-UDElement -Tag div -Attributes @{
style = @{
textAlign = 'center'
}
} -Content {
New-UDButton -Text 'Register' -Color secondary
}
New-UDCard -Title 'SIGN UP' -Content {
New-UDForm -Content {
New-UDTextbox -Label 'EMAIL ADDRESS'
} -OnSubmit {
}
} -Elevation 0
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes#paperbase)
Paperbase

Paperbase in Universal Dashboard
Based on the Material UI theme, [Paperbase](https://material-ui.com/store/previews/paperbase/)
.
Copy
$Theme = @{
palette = @{
primary = @{
light = '#63ccff'
main = '#009be5'
dark = '#006db3'
}
}
typography = @{
h5 = @{
fontWeight = 500
fontSize = 26
letterSpacing = 0.5
}
}
shape = @{
borderRadius = 8
}
mixins = @{
toolbar = @{
minHeight = 48
}
}
overrides = @{
MuiDrawer = @{
paper = @{
backgroundColor = '#081627'
}
}
MuiButton = @{
label = @{
textTransform = 'none'
}
contained = @{
boxShadow = 'none'
'&:active' = @{
boxShadow = 'none'
}
}
}
MuiTabs = @{
root = @{
marginLeft = 1
}
indicator = @{
height = 3
borderTopLeftRadius = 3
borderTopRightRadius = 3
backgroundColor = '#000'
}
}
MuiTab = @{
root = @{
textTransform = 'none'
margin = '0 16px'
minWidth = 0
padding = 0
}
}
MuiIconButton = @{
root = @{
padding = 1
}
}
MuiTooltip = @{
tooltip = @{
borderRadius = 4
}
}
MuiDivider = @{
root = @{
backgroundColor = 'rgb(255,255,255,0.15)'
}
}
MuiListItemButton = @{
root = @{
'&.Mui-selected' = @{
color = '#4fc3f7'
}
}
}
MuiListItemText = @{
primary = @{
color = 'rgba(255, 255, 255, 0.7) '
fontSize = 14
fontWeight = 500
}
}
MuiListItemIcon = @{
root = @{
color = 'rgba(255, 255, 255, 0.7) '
minWidth = 'auto'
marginRight = 2
'& svg' = @{
fontSize = 20
}
}
}
MuiAvatar = @{
root = @{
width = 32
height = 32
}
}
}
}
This the dashboard used to create the above image.
Copy
$Navigation = @(
New-UDListItem -Label "Home"
New-UDListItem -Label "Getting Started" -Children {
New-UDListItem -Label "Installation" -Icon (New-UDIcon -Icon envelope) -OnClick { Invoke-UDRedirect '/installation' }
New-UDListItem -Label "Usage" -Icon (New-UDIcon -Icon edit) -OnClick { Invoke-UDRedirect '/usage' }
New-UDListItem -Label "FAQs" -Icon (New-UDIcon -Icon trash) -OnClick { Invoke-UDRedirect '/faqs' }
New-UDListItem -Label "System Requirements" -Icon (New-UDIcon -Icon bug) -OnClick { Invoke-UDRedirect '/requirements' }
New-UDListItem -Label "Purchasing" -OnClick { Invoke-UDRedirect '/purchasing'}
}
)
New-UDDashboard -Theme $theme -Title "Paperbase" -Content {
New-UDButton -Text 'Add user' -Color primary
New-UDCard -Title 'User Info' -Content {
"No users for this project yet."
}
} -Navigation $Navigation -NavigationLayout Permanent
[PreviousSessions](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/sessions)
[NextCascading Style Sheets](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/themes/cascading-style-sheets)
Last updated 3 years ago
---
# About Desktop Mode | PowerShell Universal
Desktop mode runs PowerShell Universal as a desktop application. It installs to the current user's application data folders and does not require administrative access to run. It runs as the current user and with a tray icon to access the console and configuration files.
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#install-desktop-mode)
Install Desktop Mode
---------------------------------------------------------------------------------------------------------------------
To install desktop mode, you can [download](https://ironmansoftware.com/downloads)
the desktop mode installer from our website.
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#differences-in-desktop-mode)
Differences in Desktop Mode
-----------------------------------------------------------------------------------------------------------------------------------
Desktop mode runs slightly differently than PowerShell Universal as a service.
###
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#application-context)
Application Context
The desktop application uses WebView2 to display the PowerShell Universal admin console within the application window. The PowerShell Universal server integrates with the desktop application to provide desktop-specific features based on the configuration of PSU.
The desktop application provides a tray icon that can be used to exit PowerShell Universal, view the admin UI and open the configuration folder in VS Code.
PowerShell Universal will not run when the user is not logged in so scheduled jobs will not execute.
###
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#configuration)
Configuration
Configuration files are stored in `%AppData%\PowerShellUniversal` rather than the ProgramData folder. You can quickly access the configuration folder by using the PowerShell Universal tray icon.
###
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#dashboards)
Dashboards
Desktop mode does not support PowerShell Universal Dashboard v2 frameworks. It actually doesn't support anything except the latest framework version. It will not deploy copies of the framework.
###
[](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode#security)
Security
Desktop mode runs as the current user as a regular desktop application. It starts the PowerShell Universal web server. The server only listens on localhost. You will not be able to change security settings for the server.
[PreviousVariables](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables)
[NextFile Associations](https://docs.powershelluniversal.com/v3/desktop/file-associations)
Last updated 3 years ago
---
# Statistic | PowerShell Universal
Numeric statistics can return data from scripts and APIs and display values with some amount of formatting options.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic#display-a-statistic-from-an-api)
Display a statistic from an API
-----------------------------------------------------------------------------------------------------------------------------------------------
APIs should return a single value to display as a statistic. An example API could look something like this.
Copy
Get-Random -Min 100 -Max 1000
You can then select the API under the data source tab.

Each time the page is loaded, the API is called and the random value is shown.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic#display-a-statistic-from-a-script)
Display a statistic from a Script
---------------------------------------------------------------------------------------------------------------------------------------------------
Statistics shown from scripts will display the value return by the last job run for the script. Loading the page will not run the script again.
We will use this script as an example.
Copy
Get-Random -Min 100 -Max 1000
Select the script on the data source tab.

The statistic will be shown on the page based on the output of the script. You'll notice that refreshing the page does not change the value of the statistic unless the job is run again.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic#customizing-the-statistic)
Customizing the Statistic
-----------------------------------------------------------------------------------------------------------------------------------
You can customize features such as the prefix, suffix, precision and whether to auto-reload the statistic on an interval.


[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic#properties)
Properties
-----------------------------------------------------------------------------------------------------
Property
Description
Available Since
ID
The ID of this component
2.2.0
Title
The text to display within the statistic.
2.2.0
Data Source
The script or API to call to return the statistic's value.
2.2.0
Prefix
The string to display before the value.
2.2.0
Suffix
The string to display after the value.
2.2.0
Auto Reload
Whether to auto-reload the statistic on an interval.
2.2.0
Auto Reload Interval
The number of seconds between auto-reloads.
2.2.0
Precision
The number of decimal places to display in the value.
2.2.0
[PreviousParagraph](https://docs.powershelluniversal.com/v3/userinterfaces/pages/paragraph)
[NextTable](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table)
Last updated 3 years ago
---
# File Associations | PowerShell Universal

File associations in the admin console.
[](https://docs.powershelluniversal.com/v3/desktop/file-associations#define-a-file-association)
Define a File Association
------------------------------------------------------------------------------------------------------------------------------
File associations are stored within the `fileAssociations.ps1` file within the configuration directory. You can use the `New-PSUFileAssociation` cmdlet to define associations directly.
By default, you'll need to include the script to run and the extension to associate with it.
Copy
New-PSUFileAssociation -Script FileAssociation.ps1 -Extension .ps3
[](https://docs.powershelluniversal.com/v3/desktop/file-associations#accessing-the-file-path)
Accessing the File Path
--------------------------------------------------------------------------------------------------------------------------
By default, you can use the `$File` parameter within your script to access the full path to the file that caused the file association to trigger.
Copy
param($File)
$Json = Get-Content $File | ConvertFrom-Json
[PreviousAbout Desktop Mode](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode)
[NextHotkeys](https://docs.powershelluniversal.com/v3/desktop/hotkeys)
Last updated 3 years ago
---
# Form | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#invoke-a-script-with-a-form)
Invoke a Script with a Form
----------------------------------------------------------------------------------------------------------------------------------
Forms can be used to invoke scripts. The form component ties directly into the automation features to allow for the display of output, progress and respond to feedback.
To invoke a script, select the target of Script and the script you'd like to invoke.

By default, no output or progress will be shown. The form will simply consist of a Save button.

If the script succeeds, you'll see a success result. If it fails, it will return a failure result.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#viewing-output)
Viewing Output
You can view the output as the script runs by using the Show Output check box.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#viewing-progress)
Viewing Progress
To view the output of cmdlets like `Write-Progress`, you can use the Show Progress check box. While the script executes, you'll see the progress messages.

The script in this example simply shows progress.
Copy
1..10 | % {
Write-Progress -Activity "Processing..." -PercentComplete ($_ * 10)
Start-Sleep 1
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#viewing-output-after-the-script-has-run)
Viewing Output after the script has run
To view the output of the script after it has run, you can use the Result Type drop down. The Text result type, will display output as text.

To view output as a table, select the result type of Table.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#responding-to-feedback)
Responding to Feedback
Scripts that request feedback will prompt the user to enter more information.

An example of a script that may request feedback is one that uses `Read-Host`
Copy
Read-Host "Enter some feedback"
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#invoke-an-api-with-a-form)
Invoke an API with a Form
------------------------------------------------------------------------------------------------------------------------------
Invoking an API with a form can be done by selecting API from the Target Type and then selecting the API endpoint you wish to call.

API endpoints do not support progress, feedback, or output while running the API. They do support returning results as text or tables. APIs that return 200 will show a Success result and other status codes will return Failure.
Fields provided to an API endpoint will be sent as a single JSON object with properties for each field.
For example, if you had a form with a field named txtName and txtLastName, you could access those properties by deserializing the `$Body` variable.
Copy
$Fields = $Body | ConvertFrom-Json
$Fields.txtName
$Fields.txtLastName
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#fields)
Fields
----------------------------------------------------------------------------------------
You can specify fields for each form. Currently forms support text boxes, checkboxes and hidden values. Fields can have a tooltip description and marked as required.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#fields-in-scripts)
Fields in Scripts
Fields are provided to scripts as parameters. You can use a `param` block to capture these field values.
For example, if you had a FirstName and LastName field, you would define the following param block in your script.
Copy
param(
$FirstName,
$LastName
)
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#fields-in-apis)
Fields in APIs
Fields are provided to APIs as a JSON body to the POST endpoint. Each field will be a property of the JSON object passed to the API.
Copy
$Fields = $Body | ConvertFrom-Json
$Fields.FirstName
$Fields.LastName
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#field-types)
Field Types
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#checkbox)
Checkbox
The checkbox field provides a checkbox the user can select and `$true` or `$false` will be sent to the target.
**Date**
Allows the user to select a date. The value will be passed as a string.
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#hidden)
Hidden
Hidden fields provide a value to the target that is not shown to the user. The value will be a string.
**Number**
Allows the user to select a number. The value will be passed as an integer.
**Password**
Available in PowerShell Universal 2.5 or later
A textbox with a mask to prevent you from seeing the characters typed.
**Select**
Allows the user to select an option from a drop down. The value will be passed as a string.
**Switch**
Allows the user to provide a true or false. The value will be passed as a boolean.
####
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#textbox)
Textbox
The textbox field allows the user to enter any text into the field and it will be submitted to the target. The value will be a string.
Time
Allows the user to select a time. The value is passed as a string.
**Rating**
Allows the user to select a rating between 0 and 5. The value is passed as a float.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#text)
Text
------------------------------------------------------------------------------------
You can customize the text of numerous features of a field including the success and failure text, waiting on feedback text and button text.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#validation)
Validation
------------------------------------------------------------------------------------------------
Available in PowerShell Universal 2.9 or later.

You can validate a form by selecting an API endpoint from the Validation API field. The validation endpoint must be a POST method. Use the `New-PSUValidationResult` parameter to return whether the validation is successful.

Validation API
Copy
$Fields = $Body | ConvertFrom-Json
if ($Fields.Name -eq 'Adam')
{
New-PSUValidationResult -Success
}
else
{
New-PSUValidationResult -ErrorMessage 'Incorrect name'
}
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#smart-properties)
Smart Properties
------------------------------------------------------------------------------------------------------------
Smart properties are hashtables included in the data returned from APIs and Scripts. Tables will automatically translate these hashtables to rendered components when displaying them.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#links)
Links
You can include links by using a hashtable with the `link` type and providing a `url` and `text` property.
Copy
@{
column = @{
type = "link"
url = "https://ironmansoftware.com"
text = "Ironman Software"
}
}
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/form#images)
Images
You can include images by using a hashtable with the `image` type and specifying any valid `img` HTML attributes.
Copy
@{
column = @{
type = "image"
src = "https://ironmansoftware.com/logo.png"
height = "10px"
}
}
[PreviousCard](https://docs.powershelluniversal.com/v3/userinterfaces/pages/card)
[NextiFrame](https://docs.powershelluniversal.com/v3/userinterfaces/pages/iframe)
Last updated 3 years ago
---
# Table | PowerShell Universal
Tables allow you to display the output of APIs and scripts in rows and columns. Each object returned by the data source will create a row within the table. You can customize the columns of the table.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table#selecting-a-data-source)
Selecting a Data Source
---------------------------------------------------------------------------------------------------------------------------
Both APIs and Scripts are supported by tables. When selecting an API, the API will be executed each time the page is loaded. When selecting a script, the last job run of the script will provide the output.

When columns are not defined, all the properties of the objects will be displayed.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table#customizing-columns)
Customizing Columns
-------------------------------------------------------------------------------------------------------------------
You can customize the columns that are selected when displaying data.
###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table#basic)
Basic
Basic columns will select the properties defined and display the text.
In this example, we are selecting the name and service type from a call to `Get-Service`.

The resulting table only has these two properties displayed.

###
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table#buttons)
Buttons
Buttons can be added to columns to provide functionality for each row. Clicking the button will provide the target with the row data via the `$InputObject` parameter.

[PreviousStatistic](https://docs.powershelluniversal.com/v3/userinterfaces/pages/statistic)
[NextVariables](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables)
Last updated 3 years ago
---
# Variables | PowerShell Universal
This feature requires a [PowerShell Universal license](https://docs.powershelluniversal.com/v3/licensing)
.
Variables allow you modify the functionality of a page depending on factors such as the user name or URL route. Variable-based routes allow you to create dynamic pages based on the URL the user is visiting.
Variables that are defined with Platform \\ Variables will also be available to pages.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables#viewing-variables)
Viewing Variables
-------------------------------------------------------------------------------------------------------------------
Variables can be viewed when editing a page. To view variables, click Edit and then Variables.

A drawer will appear with the variables for the current page.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables#using-variables)
Using Variables
---------------------------------------------------------------------------------------------------------------
Variables can be used anywhere you can type a property value. For example, if you have an Alert, you could use the `$pagename` variable within the title property.

When the page is rendered, the variable will be replaced.

You can also use variables within targets and data sources. This allows you to call URLs that will change based on the variable.

You can also use variables to provide hidden input fields to APIs and scripts.

[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables#page-variables)
Page Variables
-------------------------------------------------------------------------------------------------------------
You can load additional data when the page is loading by providing a data source to in the page properties. The data source should return a single PSCustomObject or hashtable. The properties of the object will become variables within the page.
For example, assume you have an API that returns the following hashtable.
Copy
@{
Name = "My Name"
Title = "My Title"
}
Selecting this API as the data source for the page would then create the variables `$Name` and `$Title` within the page.
You can also use Route Variables within the data source to customize which API is called based on the route visited.
[](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables#route-variables)
Route Variables
---------------------------------------------------------------------------------------------------------------
Route variables need to be defined when creating the URL for the page. Each section of the URL that starts with `:` will be treated as a variable.
For example, this page defines a single route variable.

Within the page, the route variables will appear within the variable drawer.

[PreviousTable](https://docs.powershelluniversal.com/v3/userinterfaces/pages/table)
[NextAbout Desktop Mode](https://docs.powershelluniversal.com/v3/desktop/about-desktop-mode)
Last updated 3 years ago
---
# Hotkeys | PowerShell Universal
PowerShell Universal Desktop supports global hotkeys that can be used to invoke scripts with key chords.

Hotkeys Page in the Admin Console
[](https://docs.powershelluniversal.com/v3/desktop/hotkeys#define-a-hotkey)
Define a Hotkey
------------------------------------------------------------------------------------------------
To define a hotkey, you will need to edit the `hotkeys.ps1` file in the `.universal` folder or through the Settings \\ Configurations page within the Admin Console.
Hotkeys are defined using the `New-PSUHotkey` cmdlet. For example, the following will invoke `MyScript.ps1` when `Ctrl+I` is pressed anywhere within Windows.
Copy
New-PSUHotkey -Key I -ModifierKey Ctrl -Script 'MyScript.ps1'
[](https://docs.powershelluniversal.com/v3/desktop/hotkeys#environments)
Environments
------------------------------------------------------------------------------------------
You can define which environment the hotkey runs within by using the `-Environment` parameter.
Copy
New-PSUHotkey -Key I -ModifierKey Ctrl -Script 'MyScript.ps1' -Environment 'pwsh'
[](https://docs.powershelluniversal.com/v3/desktop/hotkeys#parameters)
Parameters
--------------------------------------------------------------------------------------
You can define parameters passed to the script by using the dynamic parameters provided by `New-PSUHotKey`.
For example, if a script accepts a `-Parameter1` parameter, you can define that on `New-PSUHotKey.`
Copy
param($Parameter1)
Within the hotkey, just use `-Parameter1`.
Copy
New-PSUHotkey -Key I -ModifierKey Ctrl -Script 'MyScript.ps1' -Parameter1 'Test'
[PreviousFile Associations](https://docs.powershelluniversal.com/v3/desktop/file-associations)
[NextPages](https://docs.powershelluniversal.com/v3/desktop/pages)
Last updated 3 years ago
---
# Pages | PowerShell Universal

Page displayed as desktop window
You can use the `Show-PSUPage` cmdlet from any script to pop up a tool window for a page, dashboard or other URL. This means that you can integrate with Hotkeys, Shortcuts, Protocol handlers and more to display user interfaces that appear like regular windows.
[](https://docs.powershelluniversal.com/v3/desktop/pages#displaying-a-page)
Displaying a Page
--------------------------------------------------------------------------------------------------
For example, you could place the following in a script to display a page.
Copy
Show-PSUPage -Url "MyPage"
[PreviousHotkeys](https://docs.powershelluniversal.com/v3/desktop/hotkeys)
[NextProtocol Handlers](https://docs.powershelluniversal.com/v3/desktop/protocol-handlers)
Last updated 3 years ago
---
# Protocol Handlers | PowerShell Universal

Protocol Handlers in the Admin Console
Protocol handlers allow you to trigger scripts when custom protocols are executed. Protocols can be executed locally and also from webpages as links.
[](https://docs.powershelluniversal.com/v3/desktop/protocol-handlers#define-a-protocol-handle)
Define a Protocol Handle
----------------------------------------------------------------------------------------------------------------------------
You can define protocol handlers in the `protocolHandlers.ps1` file using the `New-PSUProtocolHandler` cmdlet. You will need to define the protocol name and script to execute.
Copy
New-PSUProtocolHandler -Script test.ps1 -Protocol psu
To execute the protocol handler, you could include the following HTML tag in a web page.
Copy
Click Me
[](https://docs.powershelluniversal.com/v3/desktop/protocol-handlers#accessing-uri-data)
Accessing URI Data
----------------------------------------------------------------------------------------------------------------
When a script is executed, you will receive the `$ProtocolUri` parameter. It will include the full URI that was invoked. For example, a script could take the URI and show a page.
Copy
param($ProtocolUri)
$Page = $ProtocolUri.Replace("psu://", "")
$Page
Show-PSUPage -Url $Page
[PreviousPages](https://docs.powershelluniversal.com/v3/desktop/pages)
[NextCache](https://docs.powershelluniversal.com/v3/platform/cache)
Last updated 3 years ago
---
# Modules | PowerShell Universal
Module management requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
The Modules page provides information about the modules installed in the system.
[](https://docs.powershelluniversal.com/v3/platform/modules#viewing-modules)
Viewing Modules
-------------------------------------------------------------------------------------------------
You can view and search the modules accessible by PowerShell Universal by visiting the Platform \\ Modules page. Searching provides a wildcard result of the modules found in each of the environments defined within PowerShell Universal.

[](https://docs.powershelluniversal.com/v3/platform/modules#install-modules-from-the-gallery)
Install Modules from the Gallery
-----------------------------------------------------------------------------------------------------------------------------------
Modules can be installed from the PowerShell Gallery. To search for a module, you can change the drop down next to the search box from Local to PowerShell Gallery. Searches conducted will run against the Gallery rather than locally.
Once a module is found, you'll be able to click the Install button to save it locally. Modules installed in this method will be installed into the Repository directory under Modules.
[](https://docs.powershelluniversal.com/v3/platform/modules#package-sources)
Package Sources
-------------------------------------------------------------------------------------------------
PowerShell Universal integrates with the `PackageManagement v3` module and will automatically pick up on registered package sources. For example, you can register a package source with the command below.
Copy
Register-PSResourceRepository -Name MyNuGet -Uri https://www.nuget.org/api/v2
Once the source has been registered, it will be shown within the drop down on the modules page.

[](https://docs.powershelluniversal.com/v3/platform/modules#creating-modules)
Creating Modules
---------------------------------------------------------------------------------------------------
You can also create modules directly in PowerShell Universal. These modules will be created in the Repository directory under Modules.
These modules will be available in all environments.
To create a new module navigate to Platform \\ Modules and click Create New Module. Define the module name and version.

Once created, the module will be listed under Universal Modules with the option to edit properties and content as well as delete the module.

When editing the module, it will open a code editor where you can define functions, variables and aliases to export.

[](https://docs.powershelluniversal.com/v3/platform/modules#manually-install-modules)
Manually Install Modules
-------------------------------------------------------------------------------------------------------------------
PowerShell Universal will add the repository's `Modules` directory to the `$ENV:PSModulePath` for all environments. Adding modules to this directory will ensure the module is available to any PowerShell process running with PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/platform/modules#module-information)
Module Information
-------------------------------------------------------------------------------------------------------
This section includes information about certain modules and their use within PowerShell Universal.
###
[](https://docs.powershelluniversal.com/v3/platform/modules#activedirectory)
ActiveDirectory
The `ActiveDirectory` module supports native PowerShell 7 support when using the 1.0.1.0 version. When using the 1.0.0.0 version, the Windows Compatibility layer is used when running the commands in PowerShell 7 and the Integrated environment. This can cause problems within PowerShell Universal. Our guidance for this module is as follows.
####
[](https://docs.powershelluniversal.com/v3/platform/modules#windows-server-2019-and-above)
Windows Server 2019 and above
Update the `ActiveDirectory` module to version 1.0.1.0 which has PowerShell Core support
####
[](https://docs.powershelluniversal.com/v3/platform/modules#windows-server-2016-and-below)
Windows Server 2016 and below
Choose from 1 of 2 available workarounds:
* Include the `-SkipEditionCheck` parameter with **Import-Module** when importing the ActiveDirectory module
* Use the Windows PowerShell 5.1 environment instead of Integrated/PowerShell Core
####
[](https://docs.powershelluniversal.com/v3/platform/modules#further-reading)
Further Reading
[https://devblogs.microsoft.com/powershell/increased-windows-modules-coverage-with-powershell-core-6-1/](https://devblogs.microsoft.com/powershell/increased-windows-modules-coverage-with-powershell-core-6-1/)
[PreviousCache](https://docs.powershelluniversal.com/v3/platform/cache)
[NextMonitoring](https://docs.powershelluniversal.com/v3/platform/monitoring)
Last updated 2 years ago
---
# Cache | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/platform/cache#server-level-cache)
Server-Level Cache
-----------------------------------------------------------------------------------------------------
PowerShell Universal provides the ability to use a server-level cache to store data that you use between APIs, Automation and Dashboards. You can configure cache item life times use the `Set-PSUCache` cmdlet in any PowerShell script you run in PowerShell Universal. You can also retrieve items from the cache using `Get-PSUCache`.
Some examples of usages for the cache may be:
* Collecting data with a scheduled job and displaying it within a dashboard
* Collecting data from an API and using it in a job
* Collecting using input from a dashboard and queuing it to run in a scheduled job
####
[](https://docs.powershelluniversal.com/v3/platform/cache#setting-items-in-the-cache)
Setting items in the cache
To set items in the cache, you can use `Set-PSUCache`. Items in the cache are serialized to strings using CLIXML and the PowerShell serializer. When you retrieve objects from the cache, they will no longer be live objects.
Copy
Set-PSUCache -Key "CurrentDate" -Value (Get-Date)
There are three types of cache invalidation techniques you can employ.
####
[](https://docs.powershelluniversal.com/v3/platform/cache#absolute-expiration)
Absolute Expiration
The `AbsoluteExpiration` parameter defines at what time the item in the cache is invalidated.
The follow example invalidates the cache item after 10 minutes.
Copy
Set-PSUCache -Key "CurrentDate" -Value (Get-Date) -AbsoluteExpiration (Get-Date).AddMinutes(10)
####
[](https://docs.powershelluniversal.com/v3/platform/cache#absolute-expiration-from-now)
Absolute Expiration From Now
The `AbsoluteExpirationFromNow` parameter defines when a cache item is invalidated using a TimeSpan rather than a calculated DateTime.
The following cache item is invalidated 1 hour from now.
Copy
Set-PSUCache -Key "CurrentDate" -Value (Get-Date) -AbsoluteExpirationFromNow ([TimeSpan]::FromHours(1))
####
[](https://docs.powershelluniversal.com/v3/platform/cache#sliding-expiration)
Sliding Expiration
The `SlidingExpiration` parameter allows you to defines the amount of time before the cache item is invalidated. Each time the cache item is accessed, the timer is reset.
The following cache item will be invalidated in 5 minutes. If it's accessed within those 5 minutes, it will be reset for another 5 minutes.
Copy
Set-PSUCache -Key "CurrentDate" -Value (Get-Date) -SlidingExpiration ([TimeSpan]::FromMinutes(5))
[](https://docs.powershelluniversal.com/v3/platform/cache#getting-items-from-the-cache)
Getting items from the cache
-------------------------------------------------------------------------------------------------------------------------
You can use the `Get-PSUCache` cmdlet to retrieve items from the cache. You simply need to supply the key of the item you wish to retrieve. The deserialized object will be returned from the cmdlet.
Copy
Get-PSUCache -Key "CurrentDate"
[](https://docs.powershelluniversal.com/v3/platform/cache#usdcache-scope)
$Cache Scope
-------------------------------------------------------------------------------------------
APIs, Automation scripts and Dashboards all support a $Cache scope. This scope is used to cache data across runspaces that will persist in memory of each of the execution environments. The $Cache scope differs from the server-level cache as it only resides in the execution environment of feature you are using.
For example, if you set a $Cache variable in a dashboard, then it will not be available in an API. This is not true when using the Integrated environment. If a dashboard and API both use the integrated environment, then they share the cache scope.
You can set and retrieve data from the cache scope using variable assignment and retrieval syntax.
Copy
$Cache:MyValue = "Hello"
Write-Host $Cache:MyValue
[](https://docs.powershelluniversal.com/v3/platform/cache#api)
API
-----------------------------------------------------------------------
* [Get-PSUCache](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUCache.txt)
* [Set-PSUCache](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSUCache.txt)
[PreviousProtocol Handlers](https://docs.powershelluniversal.com/v3/desktop/protocol-handlers)
[NextModules](https://docs.powershelluniversal.com/v3/platform/modules)
Last updated 3 years ago
---
# Notifications | PowerShell Universal
PowerShell Universal can generate notifications for numerous reasons. These can include operations such as restarting a dashboard or a configuration error.
Notifications are available by clicking the bell icon within the admin console.

You can view all notifications by clicking the View All button.

[](https://docs.powershelluniversal.com/v3/platform/notifications#levels)
Levels
-------------------------------------------------------------------------------------
Notifications can be Information, Warning or Error levels. When an error level notification is generated, the bell icon will change to an exclamation mark and change to red.

You can configure which levels are generated by navigating to Settings \\ General \\ Admin Console. Change the Notification Level setting to the lowest level you'd like to see. For example, if you set it to Warning, you will only see Warning and Error notifications.

[PreviousMonitoring](https://docs.powershelluniversal.com/v3/platform/monitoring)
[NextPublished Folders](https://docs.powershelluniversal.com/v3/platform/published-folders)
Last updated 3 years ago
---
# Monitoring | PowerShell Universal
PowerShell Universal automatically integrates with Microsoft Application Insights to provide monitoring and alerting for your system. It also provides performance counters for various features in the environment.
[](https://docs.powershelluniversal.com/v3/platform/monitoring#application-insights)
Application Insights
--------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/platform/monitoring#configuring-application-insights)
Configuring Application Insights
Within the Azure Portal, you will need to create a new Application Insights resource. Once it's been created, you will need to copy the instrumentation key.

Application Insights Information
Next, paste your instrumentation key into the [Settings file](https://docs.powershelluniversal.com/v3/config/settings)
for PowerShell Universal. Finally, restart the PowerShell Universal server. Application monitoring will now be enabled.
Copy
"ApplicationInsights": {
"InstrumentationKey": "73b84b67-6fc9-4c37-9f54-000000000000"
},
###
[](https://docs.powershelluniversal.com/v3/platform/monitoring#viewing-monitoring-data)
Viewing Monitoring Data
Within the Azure Portal, you can view the Application Insights resource to view information about your PowerShell Universal server. This will include data such as failed responses, server response time, server requests and availability. You'll also be able to setup alerts to monitor for particular conditions of the PowerShell Universal server.
[](https://docs.powershelluniversal.com/v3/platform/monitoring#performance-counters)
Performance Counters
--------------------------------------------------------------------------------------------------------------
Performance counters are only supported on Windows.
Performance counters are installed when running the MSI installer. Once this occurs, performance data will automatically be generated by the following counters.
* PowerShell Universal \\ Active API Endpoints \\ \_Total
* PowerShell Universal \\ Active API Endpoints \\ Endpoint
* PowerShell Universal \\ API Endpoint Calls per Second \\ \_Total
* PowerShell Universal \\ API Endpoint Calls per Second \\ Endpoint
* PowerShell Universal \\ API Execution Time \\ \_Total
* PowerShell Universal \\ API Execution Time \\ Endpoint
* PowerShell Universal \\ Active Dashboard Connections \\ \_Total
* PowerShell Universal \\ Active Dashboard Connections \\ Dashboard
[](https://docs.powershelluniversal.com/v3/platform/monitoring#processes)
Processes
----------------------------------------------------------------------------------------
Processes started directly from PowerShell Universal will be displayed in the processes page. You can access this page by click Home and then the Processes card.
Information includes the process ID, purpose, file name, and memory usage. You can also view the state of runspaces within the process.

Note that processes started by your scripts will not be listed here.
[](https://docs.powershelluniversal.com/v3/platform/monitoring#user-sessions)
User Sessions
------------------------------------------------------------------------------------------------
You can view user sessions for dashboards and the admin console by click the User Sessions card on the Home page. Session information includes the connection time, source, user name, user agent string and remote IP Address.

[PreviousModules](https://docs.powershelluniversal.com/v3/platform/modules)
[NextNotifications](https://docs.powershelluniversal.com/v3/platform/notifications)
Last updated 2 years ago
---
# Published Folders | PowerShell Universal
Published folders allow you to share a local folder through your Universal website. Any file within the published folder will be accessible via a web request. This can be helpful for storing images or other files that you may want to provide via your Universal Dashboard.
[](https://docs.powershelluniversal.com/v3/platform/published-folders#publishing-a-folder)
Publishing a Folder
-------------------------------------------------------------------------------------------------------------------
From the `Dashboard / Published Folders` page, you can click Add Published Folder. You will need to enter the local path as well as the request path. The local path is the folder that you wish to publish. The request path is the path that the end user will request to download the files from the folder.
You can choose to turn on authentication and authorization for the folder.

Once the folder has been published, it will be listed in the published folders table.

[](https://docs.powershelluniversal.com/v3/platform/published-folders#download-files)
Download Files
---------------------------------------------------------------------------------------------------------
You can now download files that are found in the published folder by visit the request path. In the example above, I could visit the following URL to download the test.txt file.
Copy
http://localhost:5000/src/test.txt
You'll notice that unauthenticated requests will not be able to access the file.
Copy
PS C:\src\universal\src> invoke-webrequest http://localhost:5000/src/test.txt
Invoke-WebRequest: Response status code does not indicate success: 401 (Unauthorized).
[](https://docs.powershelluniversal.com/v3/platform/published-folders#default-documents)
Default Documents
---------------------------------------------------------------------------------------------------------------
Default documents allow you to load files when a user specifies the folder and not the document within a folder. This can be handy when a user visits `/docs` but does not specify `/docs/index.html`. Instead of returning a 404, you can return the `index.html` when the user specifies `/docs`.
To configure default documents, set the `-DefaultDocument` parameter on `New-PSUPublishedFolder`.
Copy
New-PSUPublishedFolder -Path C:\website -RequestPath /docs -DefaultDocument @("index.hml")
[](https://docs.powershelluniversal.com/v3/platform/published-folders#impersonation)
Impersonation
-------------------------------------------------------------------------------------------------------
Impersonation only works when using [Windows authentication](https://docs.powershelluniversal.com/v3/api/security#authenticating-with-windows-authentication)
.
By default, when PSU accesses files when serving them to users, it will do so as the service account the process is running as. If you wish to access files as the user that is downloading the file, you can turn on impersonation.
Copy
New-PSUPublishedFolder -Path C:\website -RequestPath /docs -DefaultDocument @("index.hml") -Impersonation
[](https://docs.powershelluniversal.com/v3/platform/published-folders#api)
API
-----------------------------------------------------------------------------------
* [New-PSUPublishedFolder](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUPublishedFolder.txt)
[PreviousNotifications](https://docs.powershelluniversal.com/v3/platform/notifications)
[NextTemplates](https://docs.powershelluniversal.com/v3/platform/templates)
Last updated 3 years ago
---
# Templates | PowerShell Universal
PowerShell Universal templates allow you to share your configurations with other users internally or with the PSU community. Configuration import and export functionality is built directly into PSU. You will need at least version 2.1.0 to use this functionality.
[](https://docs.powershelluniversal.com/v3/platform/templates#exporting-a-template)
Exporting a Template
-------------------------------------------------------------------------------------------------------------
To export a template, you can navigate to Platform \\ Templates and click Export Configuration as Template.

Templates
Once you click the button, you will be prompted for a name, description, author and version for the template. The Readme value can contain markdown and is rendered on IronmanSoftware.com.

When you export a configuration, any variables that you have defined will not be included. The user that imports the template will need to define the variables.
If you have a license defined, it will not be included.
[](https://docs.powershelluniversal.com/v3/platform/templates#importing-a-template)
Importing a Template
-------------------------------------------------------------------------------------------------------------
To import a configuration, navigate to Platform \\ Templates and click the template to Import.

Templates
You will be prompted to before applying the template.

Import Template
[](https://docs.powershelluniversal.com/v3/platform/templates#import-a-psupkg)
Import a PSUPKG
---------------------------------------------------------------------------------------------------
Templates are stored as `psupkg` files. To import a template from a file, click Platform \\ Templates and then Import Template. Navigate to the local `psupkg` file. Template information will be presented before importing the template.
[](https://docs.powershelluniversal.com/v3/platform/templates#publishing-a-template)
Publishing a Template
---------------------------------------------------------------------------------------------------------------
You can publish a template to the Ironman Software website after logging into your account. Click PowerShell Universal \\ Templates and then the Upload Template button. Upload your `psupkg` file. Metadata will be read from the template file. After uploading the file, you'll be able to add some screenshots.
[PreviousPublished Folders](https://docs.powershelluniversal.com/v3/platform/published-folders)
[NextTranslations](https://docs.powershelluniversal.com/v3/platform/translations)
Last updated 3 years ago
---
# Translations | PowerShell Universal
Translations require a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
Translation support provides the ability to use a special provider to return strings based on the language of the user accessing the API or dashboard.
[](https://docs.powershelluniversal.com/v3/platform/translations#defining-strings)
Defining Strings
--------------------------------------------------------------------------------------------------------
Navigate to Platform \\ Translations in the Admin Console to define language strings.

To define a new language, click Create New Language Translation. The language ID should be the [language ID](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
that the browser will present when a user accesses the API or dashboard (e.g. `en-US`)

Once you have created the language, you can begin to add strings to it by click Edit. The Key will be used within your scripts and will return the value. The value will change depending on the language.

[](https://docs.powershelluniversal.com/v3/platform/translations#using-strings)
Using Strings
--------------------------------------------------------------------------------------------------
To use a string, you will take advantage of the new `$tl:` provider. Using this provider in your scripts will automatically translate the key to the string for the user's language.
For example, you would use the variable like this.
Copy
$tl:String1
The returned value, when the user's locale is en, will be `USA`.
Strings are currently available in APIs and dashboards automatically and in scripts when setting the `LanguageID` variable.
Note that the `$t:` provider is also available but due to conflicts with the FileSystem provider and mapped T: drives, we suggest using the `$tl:` provider instead. The `$t:` provider will be mapped on machines that do not already have a T: drive mapped.
[](https://docs.powershelluniversal.com/v3/platform/translations#selecting-a-language)
Selecting a Language
----------------------------------------------------------------------------------------------------------------
PowerShell Universal selects the user's language by examining the `Accept-Language` header in the HTTP request when user's visit the dashboard page or make an API call. If you want to set a language when running a script, you will need to set the `$LanguageID` variable to the language you wish to return.
###
[](https://docs.powershelluniversal.com/v3/platform/translations#fallback-logic)
Fallback Logic
If a language is not defined for the specific language ID (e.g. `en-US`), then PowerShell Universal will attempt to locate the next best language. For example, this would then look for `en`.
If no language can be found, then the server-wide fallback language will be used. If this hasn't been defined, `en` will be used. You can specify this the fallback language in Settings \\ General \\ Platform.
If no language can be found for the specified key, the key will be returned.
[](https://docs.powershelluniversal.com/v3/platform/translations#language-files)
Language Files
----------------------------------------------------------------------------------------------------
Language files are generated in the translations folder within the repository. Each language will have a `.ps1` file named after the language ID. `New-PSUTranslation` is used to define the language and set the strings.
It may be desired to edit language files in this way to accommodate copy and pasting keys between language files.

[PreviousTemplates](https://docs.powershelluniversal.com/v3/platform/templates)
[NextUser Sessions](https://docs.powershelluniversal.com/v3/platform/user-sessions)
Last updated 2 years ago
---
# User Sessions | PowerShell Universal
When users access PowerShell Universal via the Admin Console or dashboard, the sessions will be stored within the database. Information about sessions include:
* Timestamp
* User
* Source
* User Agent String
* Remote IP Address
To access user sessions, click Home and the User Sessions card.
[PreviousTranslations](https://docs.powershelluniversal.com/v3/platform/translations)
[NextVariables](https://docs.powershelluniversal.com/v3/platform/variables)
Last updated 2 years ago
---
# Variables | PowerShell Universal
Variables allow for the global definition of variables that are available within scripts. You can also import secrets that are also available within scripts or as run as credentials.
Variables are stored in the `variables.ps1` configuration file.
[](https://docs.powershelluniversal.com/v3/platform/variables#creating-a-variable)
Creating a Variable
-----------------------------------------------------------------------------------------------------------
To create a variable, navigate to the Platform \\ Variables page. Click Add Variable to define a new variable.
Standard variables are just name \\ value pairs of strings. They will be added to your scripts before they are run.

[](https://docs.powershelluniversal.com/v3/platform/variables#creating-a-secret-variable)
Creating a Secret Variable
-------------------------------------------------------------------------------------------------------------------------
Secret variables are stored within the selected vault. The value of those variables is never stored within Universal. To define a new secret variable, click Add Variable on the variables page and select the Secret tab.
From this dialog, you'll be able to define string and PSCredentials in the specified vault.

[](https://docs.powershelluniversal.com/v3/platform/variables#vaults)
Vaults
---------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/platform/variables#database)
Database
The database vault stores secrets within the PowerShell Universal database. These secrets are encrypted using AES encryption using a customizable key. You can customize the key by specifying the Secrets \\ Database \\ EncryptionKey.
####
[](https://docs.powershelluniversal.com/v3/platform/variables#appsettings.json)
appsettings.json
You can configure this setting in appsettings.json.
Copy
"Secrets": {
"Database": {
"EncryptionKey": "=b0ywQA@VOSdr&R7an5g&XK6NVO%s4Tf"
}
}
####
[](https://docs.powershelluniversal.com/v3/platform/variables#environment-variable)
Environment Variable
You can configure this setting with an environment variable.
Copy
$Env:Secrets__Database__EncryptionKey = "=b0ywQA@VOSdr&R7an5g&XK6NVO%s4Tf"
###
[](https://docs.powershelluniversal.com/v3/platform/variables#builtinlocalvault)
BuiltInLocalVault
Values for secrets with the `BuiltInLocalVault` are stored within the Windows Credential Manager instance of the security principal that is running PSU. For example, the service account of the user running the Universal service. If you change users (such as running as a service account), the account will not have access to the previous user's secrets and you will need to add those secrets again.
###
[](https://docs.powershelluniversal.com/v3/platform/variables#psusecretstore)
PSUSecretStore
The `PSUSecretStore` vault is integrated with the Microsoft `SecretStore` module to store secrets in a cross-platform file. Ths file is tied to the current user account running PowerShell Universal. The password for the vault is stored in `appsettings.json`.
###
[](https://docs.powershelluniversal.com/v3/platform/variables#az.keyvault)
Az.KeyVault
We do not include the Azure Key Vault extension directly in PowerShell Universal, but below you will find how to configure it. This example uses an Azure hosted web-app version of PowerShell Universal.
In Azure, we'll need to configure a managed identity for our web app. This step isn't necessarily required if you are running outside of Azure. You can enable the managed identity under the Identity page for your web app.

Next, you'll need to allow your managed identity to access your key vault and read your subscription. You can add the managed identity to the builtin Reader group to allow access to the subscription.

Then, I provided all privileges to secret and key management for my managed identity in my Key Vault resource.

Finally, we will need to register the key vault and connect to Azure when the web app starts. This can be accomplished by using the Az.Account and Az.KeyVault modules.
After deploying your web-app, you will need to first install the Az.Account and Az.KeyVault modules. You can do so on the modules page. They will be installed to the local repository within the web app.

Next, create a script within PowerShell Universal to connect to Azure and register the vault. Run the script to verify it works properly.
Copy
$sub = 'affdf0d4-eed5-48a6-889c-599d482xxxxx'
Connect-AzAccount -Id -Scope CurrentUser -SubscriptionId $sub
Register-SecretVault -ModuleName Az.KeyVault -Name AzureKeyVault -VaultParameters @{
AZKVaultName = 'psu-demo'
SubscriptionId = $sub
} -AllowClobber
Now, when you are creating secrets, you will see the AzureKeyVault available.

To ensure the application is connected to Azure and the key vault is registered, create a startup trigger to run the script when the web app starts. We recommend setting a delay when for the trigger to allow the app to warm up.

[](https://docs.powershelluniversal.com/v3/platform/variables#importing-secret-variables)
Importing Secret Variables
-------------------------------------------------------------------------------------------------------------------------
You can also import pre-existing secrets as variables into Universal. The variable values are not imported but will be looked up during execution. Click the Import Secret button to import secrets.
[](https://docs.powershelluniversal.com/v3/platform/variables#using-variables)
Using Variables
---------------------------------------------------------------------------------------------------
Variables can be used in APIs, Scripts and Dashboards. When using the default environments, all variables are automatically imported. This is accomplished by specifying the `-Variable` parameter of `New-PSUEnvironment` with a wild card (\*). If you are using your own environments, you will have to configure [which variables you would like included](https://docs.powershelluniversal.com/config/environments#variables)
. You can reference a variable like you would any other PowerShell variable. The variable will contain the value you set. If you use a secret, it will contain the secret's value.
Copy
$MyVariable
You can customize which variables are allowed in an environment by customizing the environments `-Variable` parameter.
See [Environments](https://docs.powershelluniversal.com/v3/config/environments#variables)
for more information.
[](https://docs.powershelluniversal.com/v3/platform/variables#secret-scope)
Secret Scope
---------------------------------------------------------------------------------------------
To access secrets that you have added to PowerShell Universal, you can use the `$Secret` scope. For example, if you defined a secret named `Credential`, you could access that secret anywhere with the secret scope. You cannot set secrets using the secret scope.
Copy
Invoke-Command -Credential $Secret:Credential { Write-Host "Hello" }
###
[](https://docs.powershelluniversal.com/v3/platform/variables#access-variables-by-name)
Access Variables by Name
You can access variables by name using the `$Secret:` prefix.
Copy
# PSCredential
$Secret:MyNewSecret.UserName
$Secret:MyNewSecret.Password
# String
$Secret:DashboardSecret
###
[](https://docs.powershelluniversal.com/v3/platform/variables#access-values-dynamically)
Access Values Dynamically
You can access the secret scope dynamically by using `Get-ChildItem`. The secret scope is implemented as a provider. This is helpful if you don't have static variable names.
Copy
# PSCredential
(Get-ChildItem "Secret:MyNewSecret").UserName
(Get-ChildItem "Secret:MyNewSecret").Password
# String
(Get-ChildItem "Secret:DashboardSecret")
###
[](https://docs.powershelluniversal.com/v3/platform/variables#foreach-object-parallel)
ForEach-Object -Parallel
In order to use secrets when using `ForEach-Object` with the `-Parallel` parameter, you will need to take advantage of the `$using` keyword.
Copy
1..5 | ForEach-Object -Parallel {
$using:Secret:MySecret
}
[](https://docs.powershelluniversal.com/v3/platform/variables#configuring-the-psusecretstore-password)
Configuring the `PSUSecretStore` Password
-----------------------------------------------------------------------------------------------------------------------------------------------------
By default, the `PSUSecretStore` vault password is stored within `appsettings.json` in Secrets \\ SecretStore \\ Password.
[](https://docs.powershelluniversal.com/v3/platform/variables#built-in-variables)
Built-In Variables
---------------------------------------------------------------------------------------------------------
The following variables are available throughout all environments within PowerShell Universal.
Name
Type
Description
$PSUEnvironment
string
The name of the environment the script is running within (e.g. Integrated)
$Repository
string
The absolute path to the repository folder.
###
[](https://docs.powershelluniversal.com/v3/platform/variables#api)
API
There are a set of predefined variables that are available in API endpoints. You'll be able to use these variables in your scripts.
Variable
Description
Type
$Url
URL the client used to call the endpoint
String
$Method
The HTTP method used to call the endpoint
String
$Headers
Headers provided by the client to call the endpoint
Hashtable
$Body
The UTF8 encoded string of the content of the request
String
$Data
Binary byte array for the content of the request
Byte\[\]
$RemoteIpAddress
The remote IP address used to make the request.
String
$LocalIpAddress
The local IP address used to service the request.
String
$RemotePort
The remote port that was called to make the request.
Integer
$LocalPort
The local port that was used to service the request.
Integer
$Identity
The identity name of the principal accessing the API.
String
$UrlDefinition
The definition for the URL.
String
$ConnectionId
The [HTTP Context connection ID](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.connectioninfo.id?view=aspnetcore-6.0#Microsoft_AspNetCore_Http_ConnectionInfo_Id)
.
String
$SessionId
The [HTTP Context session ID.](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.isession.id?view=aspnetcore-6.0#Microsoft_AspNetCore_Http_ISession_Id)
String
$RequestId
The [HTTP Context request ID.](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httpcontext.traceidentifier?view=aspnetcore-6.0#Microsoft_AspNetCore_Http_HttpContext_TraceIdentifier)
String
$ClaimsPrincipal
The claims principal of the current user. This is the same object that is provided to role-based access policies.
[ClaimPrincipal](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access)
###
[](https://docs.powershelluniversal.com/v3/platform/variables#dashboards)
Dashboards
Below are variables that are available in dashboards in addition to the global variables.
Name
Description
Type
$User
The user name of the logged in user. $Null if authentication is disabled.
String
$Roles
The roles that the user has been granted. $Null if authentication is disabled.
String\[\]
$RemoteIpAddress
The remote IP address of the connected user.
String
$RemotePort
The remote port of the connected user.
Int
$ClaimsPrincipal
The claims principal of the current user. This is the same object that is provided to role-based access policies.
[ClaimPrincipal](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access)
$Headers
The headers provided by the browser.
hashtable
$Cookies
The request cookies provided by the browser.
hashtable
$PSUAppToken
The app token of the current user. Only available when -GrantAppToken is enabled.
string
$PSUComputerName
The URL of the PSU server. Only available when -GrantAppToken is enabled.
string
$DashboardName
The name of the current dashboard
string
###
[](https://docs.powershelluniversal.com/v3/platform/variables#scripts)
Scripts
There are several built-in variables that are defined when a job is run. You can use these variables in your scripts to retrieve information about the current job.
Name
Description
$UAJob
The current job that is running. This will include properties such as the script, the user that started the job and when the job was started.
$UAJobId
The ID of the running job.
$UAScript
The script that is running. This will include properties such as the name of the script and path to the script.
$UAScriptId
The ID of the running script.
$UASchedule
The schedule that was used to start the script.
$UAScheduleId
The ID of the schedule that started the script.
$AccessToken
When using OIDC authentication, you can retrieve the current user's access token for access resources on their behalf.
####
[](https://docs.powershelluniversal.com/v3/platform/variables#retrieving-the-user-that-started-a-script)
Retrieving the user that started a script
You can retrieve the name of the user that started the script by using the `UAJob` variable
Copy
$UAJob.Identity.Name
[](https://docs.powershelluniversal.com/v3/platform/variables#api-1)
API
-----------------------------------------------------------------------------
* [New-PSUVariable](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUVariable.txt)
* [Get-PSUVariable](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUVariable.txt)
* [Remove-PSUVariable](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-PSUVariable.txt)
* [Set-PSUVariable](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSUVariable.txt)
[PreviousUser Sessions](https://docs.powershelluniversal.com/v3/platform/user-sessions)
[NextAbout](https://docs.powershelluniversal.com/v3/config/about)
Last updated 2 years ago
---
# About | PowerShell Universal
Universal utilizes an idempotent configuration system to ensure repeatable deployments of instances of the platform. The same cmdlets that are used to call the REST API are used to configure the system. When they are called by the configuration system, they do not call the REST API and just return objects that are then used to configure Universal.
A typical configuration file is just a PS1 file.
Copy
New-PSUDashboard -Name 'Dashboard' -Path 'dashboard.ps1' -Framework 'UniversalDashboard:3.0.0'
Using an idempotent configuration system all enables the ability to source control the configuration files used to deploy Universal instances.
[](https://docs.powershelluniversal.com/v3/config/about#idempotent-configuration)
Idempotent Configuration
---------------------------------------------------------------------------------------------------------------
The configuration files for Universal define the state of the system. Rather than calling a Remove cmdlet to remove an item from the Universal system, you simply remove the New cmdlet call from the established configuration file.
You can call the Remove cmdlets to invoke the Universal REST API. The REST API will then synchronize with the configuration files to remove the entity.
For example, scripts are added to the system by adding a `New-PSUScript` cmdlet call to the `./universal/scripts.ps1`file.
If you had two scripts, your `scripts.ps1`would look like this.
Copy
New-PSUScript -Name 'Script1.ps1' -Path 'Script1.ps1'
New-PSUScript -Name 'Script2.ps1' -Path 'Script2.ps1'
To remove `Script2.ps1`from the system, you would just remove the second line.
Copy
New-PSUScript -Name 'Script2.ps1' -Path 'Script2.ps1'
When calling the Universal REST API or by using the Universal admin console, the configuration files will be updated automatically.
[](https://docs.powershelluniversal.com/v3/config/about#configuration-files)
Configuration Files
-----------------------------------------------------------------------------------------------------
For each type of entity that is managed within Universal there is a configuration file that will be stored within the `./universal` folder. The `./universal`folder will be managed underneath the `RepositoryFolder` that you define within your `appsettings.json` file.
By default, configuration files will automatically be reloaded when changed. This means that if you make a change to one of the files, Universal will read the file, synchronize to its local database and the platform will have the new setting you defined.
For example, if you wanted to disable telemetry collection, you could change the `./universal/settings.ps1`file. The original settings file may look like this.
Copy
Set-PSUSetting -Telemetry
To reconfigure Universal to turn off telemetry collection, you would just remove the `-Telemetry` switch parameter.
Copy
Set-PSUSetting
Universal would detect this change and reload internally.
You can disable the automatic reload of the system by specifying the `-DisableAutoReload` switch on `Set-PSUSetting`. Settings will only reload on restart of the system or when a Git synchronization takes place.
[](https://docs.powershelluniversal.com/v3/config/about#git-synchronization)
Git Synchronization
-----------------------------------------------------------------------------------------------------
Universal provides the ability to automatically synchronization configuration files and other artifacts with a remote git repository. Changes made via the Universal REST API or admin console will result in git commits and then be pushed automatically to the remote. Additionally, changes made in the remote will be pulled and Universal will automatically reload settings internally.
To configure git synchronization, use the `GitRemote`, `GitUserName`, and `GitPassword` settings in the `appsettings.json` file. You will need to restart Universal after making these changes.
To learn more about configuration settings, read the [Settings](https://docs.powershelluniversal.com/v3/config/settings)
page.
You can view the status of Git synchronization operations on the `Settings \ General` page within the admin console. Git synchronizations take place one a minute.
[PreviousVariables](https://docs.powershelluniversal.com/v3/platform/variables)
[NextAPI](https://docs.powershelluniversal.com/v3/config/api)
Last updated 3 years ago
---
# API | PowerShell Universal
The Universal API can be used to manage the platform from any compatible REST client. You will need a valid App Token to access the API.
[](https://docs.powershelluniversal.com/v3/config/api#invoking-the-api)
Invoking the API
---------------------------------------------------------------------------------------------
To invoke the API, you can send an HTTP request with the Bearer token set for authorization.
Copy
Invoke-RestMethod http://localhost:5000/api/v1/script -Headers @{ Authorization = "Bearer myAppToken" }
[](https://docs.powershelluniversal.com/v3/config/api#api-documentation)
API Documentation
-----------------------------------------------------------------------------------------------
You can access the API documentation by navigating to Security \\ Tokens and click the API Documentation button.
The URL for the API documentation can be found at the following location. You will need to be authenticated before accessing this URL: `http://localhost:5000/swagger/index.html`
[PreviousAbout](https://docs.powershelluniversal.com/v3/config/about)
[NextCommand Line Options](https://docs.powershelluniversal.com/v3/config/command-line-options)
Last updated 3 years ago
---
# Command Line Options | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/config/command-line-options#appsettings)
\--appsettings
-------------------------------------------------------------------------------------------------------
Copy
Universal.Server.exe --appsettings
Loads the specified appsettings file.
[](https://docs.powershelluniversal.com/v3/config/command-line-options#demo)
\--demo
-----------------------------------------------------------------------------------------
Copy
Universal.Server.exe --demo
Starts PowerShell Universal in demo mode.
[](https://docs.powershelluniversal.com/v3/config/command-line-options#desktop)
\--desktop
-----------------------------------------------------------------------------------------------
Copy
Universal.Server.exe --desktop
Starts PowerShell Universal in desktop mode.
[](https://docs.powershelluniversal.com/v3/config/command-line-options#reset-admin-account)
\--reset-admin-account
-----------------------------------------------------------------------------------------------------------------------
Copy
Universal.Server.exe --reset-admin-account
Resets the local admin account password to `admin`.
[](https://docs.powershelluniversal.com/v3/config/command-line-options#service)
\--service
-----------------------------------------------------------------------------------------------
Copy
Universal.Server.exe --service
Runs PowerShell Universal as a Windows service.
[PreviousAPI](https://docs.powershelluniversal.com/v3/config/api)
[NextEnvironments](https://docs.powershelluniversal.com/v3/config/environments)
Last updated 2 years ago
---
# Feature Flags | PowerShell Universal
Using feature flags, you can disable features that you don't use to simplify your deployments. This can be useful to make the platform easier to use and reduce attack vectors from a security standpoint.
[](https://docs.powershelluniversal.com/v3/config/feature-flags#disable-features)
Disable Features
-------------------------------------------------------------------------------------------------------
To disable built-in features, you can use the `-DisabledFeatures` parameter of `Set-PSUSetting`.
Copy
$Parameters = @{
DisabledFeatures = ([PowerShellUniversal.Features]::Api -bor [PowerShellUniversal.Features]::Pages)
}
Set-PSUSetting @Parameters
Once a feature has been disabled, it will no longer appear in the admin console.

More importantly, disabled features will be completely disabled in the PowerShell Universal server. The Management APIs will no longer function, and the configuration scripts will not be run.
Features that can be disabled include:
* API
* Scripts
* Terminals
* Dashboards
* Pages
* RateLimiting
* PublishedFolders
* Templates
* Protect
[](https://docs.powershelluniversal.com/v3/config/feature-flags#experimental-features)
Experimental Features
-----------------------------------------------------------------------------------------------------------------
Experimental features are disabled by default. To enable an experiment feature, use the `-ExperimentalFeatures` parameter of `Set-PSUSetting`.
Copy
$Parameters = @{
ExperimentalFeatures = ([PowerShellUniversal.ExperimentalFeatures]::CSharpLang)
}
Set-PSUSetting @Parameters
Experimental features may not have a user interface component when enabled.
Experimental features that can be enabled include:
* C# APIs
[PreviousEnvironments](https://docs.powershelluniversal.com/v3/config/environments)
[NextGit](https://docs.powershelluniversal.com/v3/config/git)
Last updated 2 years ago
---
# Environments | PowerShell Universal
Environments allow you to define an executable, arguments, modules and variables to use when running scripts, hosting APIs and dashboards.
Environments are stored within the `environments.ps1` file.
[](https://docs.powershelluniversal.com/v3/config/environments#configuring-environments)
Configuring Environments
----------------------------------------------------------------------------------------------------------------------
To configure environments, you can use the Settings \\ Environments page.

Environments Page
Environments support setting the name, path, arguments, modules and variables.

###
[](https://docs.powershelluniversal.com/v3/config/environments#name)
Name
The name of the environment. This name will be shown through out the rest of the platform when running scripts, configuring the API host environment and hosting dashboards.
###
[](https://docs.powershelluniversal.com/v3/config/environments#path-and-arguments)
Path and Arguments
Environments support defining a path to an executable and arguments for that executable. These should be either PowerShell.exe or Pwsh.exe.
You can also define modules and variables.
###
[](https://docs.powershelluniversal.com/v3/config/environments#modules)
Modules
The modules list allows you to define zero or more modules to load in the PowerShell runspaces for the environment. These modules will be part of the initial session state so they will not need to be loaded manually. Items added to this list can either be module names or full paths to module files.
###
[](https://docs.powershelluniversal.com/v3/config/environments#variables)
Variables
The variables list allows you to define zero or more variables to load in the PowerShell runspaces for the environment. This list can consist of variable names from the [variable configuration](https://docs.powershelluniversal.com/v3/platform/variables)
.
You can also use wild cards (`*`) to bring in multiple variables that match a pattern.
###
[](https://docs.powershelluniversal.com/v3/config/environments#psmodulepath)
PSModulePath
You can use the `-PSModulePath` parameter of `New-PSUEnvironment` to configure additional PSModulePaths to include within the environment.
###
[](https://docs.powershelluniversal.com/v3/config/environments#startup-scripts)
Startup Scripts

Startup scripts are run once when the environment is first creates a runspace. For APIs, this happens whenever a runspace is created to service an HTTP request. This can happen for frequently if the server is busy. For dashboards, this will happen whenever a runspace is crated to service an endpoint being run while the user views a dashboard. Busy servers and dashboards with many dynamic components will do this more frequently. For jobs, this will happen once when the job is started.
Startup scripts are relative to the Repository folder. For example, if you had a script in your repository named `startup.ps1`, you would just list the file name in the configuration. If you had a script in a directory, you would need to include that as well.
Platform variables are not available in startup scripts.
[](https://docs.powershelluniversal.com/v3/config/environments#using-environments)
Using Environments
----------------------------------------------------------------------------------------------------------
Environments can be used across the platform.
###
[](https://docs.powershelluniversal.com/v3/config/environments#apis)
APIs
To select the environment to use, modify the `settings.ps1` file and include the `-ApiEnvironment` parameter of `Set-PSUSetting`. It needs to be the name of the environment.
###
[](https://docs.powershelluniversal.com/v3/config/environments#automation)
Automation
Each script, job and schedule can use an environment. You can define environments for scripts by modifying the `scripts.ps1` and setting the `-Environment` parameter of `New-PSUScript`. To set the environment of a schedule, set the `-Environment` parameter of `New-PSUSchedule` in `schedules.ps1`. When invoking a script, you can also choose an environment to use.
###
[](https://docs.powershelluniversal.com/v3/config/environments#dashboards)
Dashboards
To use a particular environment for a dashboard, set the `-Environment` parameter of `New-PSUDashboard` in `dashboards.ps1`.
###
[](https://docs.powershelluniversal.com/v3/config/environments#security)
Security
By default, authentication and authorization happen within the `Universal.Server.exe` process. To run these out of process, you can select an environment by setting the `-SecurityEnvironment` parameter of `Set-PSUSetting` in `settings.ps1`.
[](https://docs.powershelluniversal.com/v3/config/environments#integrated-environment)
Integrated Environment
------------------------------------------------------------------------------------------------------------------
The integrated environment does not support running as alternate credentials.
The integrated environment uses the PowerShell Universal server process directly rather than starting external PowerShell processes to service requests.
The integrated environment is easier to configure and use than having multiple disparate environments. You will also see a performance improvement because there is no need to serialize and communicate via interprocess communication.
The downside is that you cannot elevate to alternate credentials or use alternate PowerShell versions. You will be using the current version of the PowerShell Universal server's PowerShell SDK. Additionally, since all the PowerShell scripts are running within the service, you can affect the stability of the platform with your PowerShell scripts.
Please read [Best Practices](https://docs.powershelluniversal.com/v3/config/best-practices#favor-non-integrated-environments)
for more information.
###
[](https://docs.powershelluniversal.com/v3/config/environments#configuring)
Configuring
The integrated environment is always available and you do not need to configured it directly. If you do want to import modules or set up persistent runspaces, you can set settings for the integrated environment in `environments.ps1`.
.universal\\environments.ps1
Copy
New-PSUEnvironment -Name 'Integrated' -Path 'none' -Modules @('ActiveDirectory')
###
[](https://docs.powershelluniversal.com/v3/config/environments#apis-1)
APIs
To set the integrated environment, you can use the `Set-PSUSetting` in `settings.ps1`.
.universal\\settings.ps1
Copy
Set-PSUSetting -ApiEnvironment 'Integrated'
###
[](https://docs.powershelluniversal.com/v3/config/environments#automation-1)
Automation
You can assign the integrated environment to scripts and schedules. You can also set the integrated environment as the default environment for the platform.
Copy
Set-PSetting -DefaultEnvironment 'Integrated'
You can also choose the integrated environment from the run dialog.

###
[](https://docs.powershelluniversal.com/v3/config/environments#dashboards-1)
Dashboards
You can run dashboards in the integrated environment. Select the integrated environment from the environment drop down.

###
[](https://docs.powershelluniversal.com/v3/config/environments#module-support)
Module Support
The integrated environment works by creating multiple ruspaces within the PowerShell Universal service. Some modules do not work well when run within a single process. Below is a list of modules with known issues running within the integrated environment.
* VMware.PowerCLI
* Az
[](https://docs.powershelluniversal.com/v3/config/environments#agent-environment)
Agent Environment
--------------------------------------------------------------------------------------------------------
PowerShell Universal includes an agent process that can be executed outside of the PowerShell Universal service. Similar to the Integrated environment, it uses the current version of PowerShell that PowerShell Universal includes. Unlike the integrated environment, it spawns an external process and doesn't require PowerShell 7 be installed on the target machine.
The Agent environment also supports run as credentials.
[](https://docs.powershelluniversal.com/v3/config/environments#windows-powershell-compatiblity)
Windows PowerShell Compatiblity
------------------------------------------------------------------------------------------------------------------------------------
Windows PowerShell Compatibility is a feature of PowerShell 7. When commands and modules are not available in PowerShell 7, the platform will automatically start a Windows PowerShell process in the background and perform local remoting from the PowerShell 7 process. This achieves backwards compatibility with Windows PowerShell modules.
You may see a warning in the environments page when this feature of PowerShell is enabled due to the implications on the PowerShell Universal platform.
###
[](https://docs.powershelluniversal.com/v3/config/environments#problems-with-winps-compatiblity-in-powershell-universal)
Problems with WinPS Compatiblity in PowerShell Universal
For each runspace opened by PowerShell Universal in which Windows PowerShell Compatibility is used, a new Windows PowerShell process will be started. These processes will only stop once the runspace is recycled.
This greatly reduces performance due to an excessive number of processes running and memory and CPU usage attributed to serialization and remote runspace management.
The most common cause of this is using the Active Directory 1.0.0.0 module from PowerShell 7.
###
[](https://docs.powershelluniversal.com/v3/config/environments#disabling-implicit-windows-powershell-compatibility)
Disabling Implicit Windows PowerShell Compatibility
You can disabled Windows PowerShell Compatibility via the settings within the environment's properties.
Windows PowerShell Compatibility is disabled for the Integrated environment by default and cannot be enabled.
###
[](https://docs.powershelluniversal.com/v3/config/environments#cleanly-using-windows-powershell-compatibility)
Cleanly Using Windows PowerShell Compatibility
If required, you can remove the Windows Compatibility runspace after executing a command using the feature. This will remove the Windows PowerShell process. Each time this endpoint is run, it will need to re-establish the session.
Copy
Import-Module PSScheduledJob -UseWindowsPowerShell
Get-ScheduledJob | Out-Null
Get-PSSession -Name 'WinPSCompatSession' | Remove-PSSession
You can learn more about [Windows PowerShell Compatibility here](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_windows_powershell_compatibility?view=powershell-7.2)
.
[](https://docs.powershelluniversal.com/v3/config/environments#api)
API
----------------------------------------------------------------------------
* [New-PSUEnvironment](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUEnvironment.txt)
* [Get-PSUEnvironment](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Get-PSUEnvironment.txt)
* [Remove-PSUEnvironment](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Remove-PSUEnvironment.txt)
[PreviousCommand Line Options](https://docs.powershelluniversal.com/v3/config/command-line-options)
[NextFeature Flags](https://docs.powershelluniversal.com/v3/config/feature-flags)
Last updated 2 years ago
---
# Hosting | PowerShell Universal
You can host PowerShell Universal as a Windows Service, in IIS, as a Azure Web App or just as a stand alone application. If you are running on Windows, we suggest either a Windows Service or IIS.
[](https://docs.powershelluniversal.com/v3/config/hosting#hosting-as-a-windows-service)
Hosting as a Windows Service
-------------------------------------------------------------------------------------------------------------------------
To host as a Windows Service, you can download and install the PowerShell Universal MSI. The MSI will automatically install the PowerShell Universal service and start it. Jobs will run under the system account by default but you can configure the service to run under another account after installation.
After the MSI has finished setup, your default web browser will open to [http://localhost:5000](http://localhost:5000/)
for login. The default login credentials are set to Admin and any password.
###
[](https://docs.powershelluniversal.com/v3/config/hosting#configuring-a-windows-service-manually)
Configuring a Windows Service Manually
You do not need to use the MSI to configure Universal as a Windows Service. You can also do it manually with the following PowerShell script.
Copy
New-Service -Name "PowerShellUniversal" -BinaryPathName "Universal.Server.exe --service" -Description "PowerShell Universal server service." -DisplayName "PowerShell Universal" -StartupType Automatic
Start-Service PowerShellUniversal
[](https://docs.powershelluniversal.com/v3/config/hosting#hosting-in-azure)
Hosting in Azure
-------------------------------------------------------------------------------------------------
Read our [Azure hosting guide](https://docs.powershelluniversal.com/v3/config/hosting/azure)
.
[](https://docs.powershelluniversal.com/v3/config/hosting#hosting-manually)
Hosting Manually
-------------------------------------------------------------------------------------------------
You can also host the Universal server as a stand alone application. Simply run the `Universal.Server.exe` from the binary directory to utilize the [Kestrel web server implementation in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1)
to start the web server.
[](https://docs.powershelluniversal.com/v3/config/hosting#web-server-configuration)
Web Server Configuration
-----------------------------------------------------------------------------------------------------------------
This section applies to Universal when it is hosted outside of IIS.
###
[](https://docs.powershelluniversal.com/v3/config/hosting#setting-the-port-and-listening-address)
Setting the Port and Listening Address
You can set the port of the Universal server by modifying the `appsettings.json` file. We recommend that you create an `appsettings.json` file in the [default configuration folder](https://docs.ironmansoftware.com/config/settings)
.
**Windows**
`%ProgramData%\PowerShellUniversal`
**Linux**
`%HOME%/.PowerShellUniversal`
To set the port, change the Kestrel endpoints section of the `appsettings.json`. By default, the configuration is defined to listen on port 5000 and on any address.
Copy
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000"
}
}
},
###
[](https://docs.powershelluniversal.com/v3/config/hosting#configuring-https)
Configuring HTTPS
To configure HTTPS, you can adjust the `appsettings.json` file to use a particular certificate and port. The below configuration uses the `testCert.pfx` file and `testPassword` and listens on port 5463.
####
[](https://docs.powershelluniversal.com/v3/config/hosting#pfx-certificates)
PFX Certificates
Copy
{
"Kestrel": {
"Endpoints": {
"HTTP": { "Url": "http://*:5000" },
"HTTPS": {
"Url": "https://*:5463",
"Certificate": {
"Path": "testCert.pfx",
"Password": "testPassword"
}
}
}
}
####
[](https://docs.powershelluniversal.com/v3/config/hosting#certificate-store)
Certificate Store
To configure a certificate in a particular location and store, you can use a configuration such as this.
When selecting the certificate by subject name, ensure you use the common name with out `CN=` prefix.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:443",
"Certificate": {
"Subject": "windows-server.ironman.local",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
}
}
Location can be either `CurrentUser` or `LocalMachine`.
####
[](https://docs.powershelluniversal.com/v3/config/hosting#certificate-store-by-thumbprint)
Certificate Store by Thumbprint
You can use thumbprint rather than subject in version 3.4 and later.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:443",
"Certificate": {
"Thumbprint": "SDFSDFSDFSDFSDFSDFSDFFSD",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
}
}
####
[](https://docs.powershelluniversal.com/v3/config/hosting#pem-and-key-certificates)
PEM And Key Certificates
Some providers, like Let's Encrypt and GoDaddy, will issue certificates as PEM and key text files. You can use these types of certificates directly with the Kestrel web server. You will need to specify the `HttpsFromPem` section within the `Endpoints` for Kestrel.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000"
},
"HttpsFromPem": {
"Url": "https://*:5001",
"Certificate": {
"Path": "C:\\Users\\adamr\\Desktop\\cert.pem",
"KeyPath": "C:\\Users\\adamr\\Desktop\\key.pem"
}
}
},
"RedirectToHttps": "true"
},
}
###
[](https://docs.powershelluniversal.com/v3/config/hosting#protocol)
Protocol
By default, Universal will listen on HTTP1 and HTTP2. You can adjust the protocols that the server listens to by setting the Protocols property. For example, you can specifically set HTTP1 and HTTP2 support with the following setting.
Copy
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000",
"Protocols": "Http1AndHttp2"
}
},
"RedirectToHttps": "false"
},
Some versions of Windows Server (like 2012R2), do not support HTTP2. To disable HTTP2 support, set the listener to only listen on HTTP1.
Copy
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000",
"Protocols": "Http1"
}
},
"RedirectToHttps": "false"
},
For a full set of listening options, you can refer to the [ASP.NET Core Documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#listenoptionsusehttps)
.
[](https://docs.powershelluniversal.com/v3/config/hosting#example-self-signed-certificate)
Example: Self-Signed Certificate
--------------------------------------------------------------------------------------------------------------------------------
In this example, we'll show how to create a self-signed certificated and use it with PowerShell Universal.
First, create a self-signed certificate and store it into your local machine store. You will need to run PowerShell as administrator. The local machine store is required because PowerShell Universal may be running as service and not as your account.
Copy
New-SelfSignedCertificate -DnsName localhost -CertStoreLocation cert:\LocalMachine\My
Next, you'll need to configure PowerShell Universal to use the certificate. This can be accomplished by editing or creating the `appsettings.json` file in `%ProgramData%\PowerShellUniversal`. This file should already exist if you installed with the MSI installer. The contents of the file should include the DNS name of your certificate and the location.
For self-signed certificates, you will need to include the `AllowInvalid` option.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:443",
"Certificate": {
"Subject": "localhost",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
}
}
Once you have updated the `appsettings.json` file, restart the PowerShell Universal service. You should now be able to access your PowerShell Universal web site at `https://localhost`.
[PreviousGit](https://docs.powershelluniversal.com/v3/config/git)
[NextAzure](https://docs.powershelluniversal.com/v3/config/hosting/azure)
Last updated 2 years ago
---
# Git | PowerShell Universal
Git integration requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
PowerShell Universal is capable of synchronizing the configuration scripts with a remote git repository.
[](https://docs.powershelluniversal.com/v3/config/git#configuration)
Configuration
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/git#database)
Database
Git sync can be configured in the database. This is the preferred approach when using SQL persistence. The benefit is that when you connect new instances of PowerShell Universal to your SQL instance, you will not need to configure git sync again.
To configure git sync, navigate to Settings \\ Git within the Admin Console. You will be able to click the Git Settings button.

###
[](https://docs.powershelluniversal.com/v3/config/git#appsettings.json)
appsettings.json
You can also use the [Configuration settings](https://docs.powershelluniversal.com/v3/config/settings)
to setup git sync. This is useful if you have a single instance of PSU and would like to back up your appsettings.json file.
[](https://docs.powershelluniversal.com/v3/config/git#git-sync-settings)
Git Sync Settings
-----------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/git#use-database)
Use Database
This feature requires a git client installed on each PowerShell Universal server.
To avoid having to use an external git service like GitHub or Gitlab, you can use the PowerShell Universal database. Git synchronization will produce a git bundle and upload it to the SQL database. Other nodes within your cluster will pull the git bundle and update their configuration based on the bundle rather than a remote git fork.
###
[](https://docs.powershelluniversal.com/v3/config/git#branch)
Branch
By default, PowerShell Universal will sync with the `master` branch. If you wish to use a different branch, specify the `GitBranch` setting within your `appsettings.json`.
###
[](https://docs.powershelluniversal.com/v3/config/git#authentication)
Authentication
You will need to configure authentication to your remote git repository. We recommend a personal access token.
###
[](https://docs.powershelluniversal.com/v3/config/git#external-git-client)
External Git Client
You can choose to use an external git client rather than using the library built into PowerShell Universal. This allows you additional configuration options such as using SSH authentication. PowerShell Universal will not use configured username, passwords or PATs when enabling this method. You will need to have a git client installed.
####
[](https://docs.powershelluniversal.com/v3/config/git#setting-credentials)
Setting Credentials
When using the external git client, you are responsible for configuring credentials before performing a synchronization.
You can configure credentials via git configuration or the URL passed to PowerShell Universal.
The following command will store the credentials in plaintext on the PowerShell Universal server. You will need to run this command as the service account user so that they have access to the credentials. This will create a `.git-credentials` file that will be used when authenticating against the target URL. You may need to change the URL depending on your git remote.
Copy
git config --global credential.helper store
echo "https://${username}:${password_or_access_token}@github.com" > ~/.git-credentials
You can also store credentials directly in the URL provided to PowerShell Universal.
Copy
https://adam:[email protected]/myOrg/myRepo.git
####
[](https://docs.powershelluniversal.com/v3/config/git#example-user-name-and-pat)
Example: User Name and PAT
To use an external git client and pass a user name and PAT to authenticate with, you can specify them in the git remote URL. For example:
Copy
https://username:[email protected]/ironmansoftware/universal
####
[](https://docs.powershelluniversal.com/v3/config/git#example-ssh-and-github)
Example: SSH and GitHub
First, you will need to configure your local ssh-agent and GitHub account with SSH keys.
You can follow their [guide here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh)
.
Next, you will provide a SSH URI for the git remote URL in PowerShell Universal. The configured SSH key will be used for the connection.
Copy
[email protected]:ironmansoftware/universal.git
####
[](https://docs.powershelluniversal.com/v3/config/git#ssl-certificate-problem)
SSL Certificate Problem
SSL Certificate problem: unable to get local issuer certificate
If you are running on Windows and receive an SSL Certificate problem, you may need to ensure that you have [enabled schannel support](https://stackoverflow.com/questions/23885449/unable-to-resolve-unable-to-get-local-issuer-certificate-using-git-on-windows)
.
####
[](https://docs.powershelluniversal.com/v3/config/git#credential-persistence)
Credential Persistence
Unable to persist credentials with the 'wincredman' credential store.
If you are on Windows and receive an error about persisting credentials in wincredman, you may need to set the credential persistence to DAPI. You can [learn how to do that here](https://github.com/GitCredentialManager/git-credential-manager/issues/633)
.
###
[](https://docs.powershelluniversal.com/v3/config/git#manual-mode)
Manual Mode
Manual mode requires users editing the PowerShell Universal instance to click Edit in order to make changes in the system.

Once the changes are complete, the user can then click Save Changes to begin a commit

On the git commit page, you can view the changed files and enter a commit message.

Once changes have been committed, they will be pushed to the remote and the service will start to synchronize with git again. There is also a chance that a git merge conflict can take place at this time. See [Dealing with Conflicts](https://docs.powershelluniversal.com/v3/config/git#dealing-with-conflicts)
for more information.
Manual mode can be set in the git settings within the admin console or within `appsettings.json`.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "filename=%ProgramData%\\UniversalAutomation\\database.db;upgrade=true",
"RunMigrations": true,
"GitRemote": "",
"GitUserName": "",
"GitPassword": "",
"GitBranch": "",
"GitSyncBehavior": "TwoWay",
"GitInitializeBehavior": "",
"GitSyncInterval": "1",
"ConfigurationScript": "",
"Mode": "Manual" // Or Automatic
},
###
[](https://docs.powershelluniversal.com/v3/config/git#method-one-pushing-local-files-to-remote)
Method One: Pushing Local Files to Remote
The default location for the local repository is `C:\ProgramData\UniversalAutomation\Repository`
You must ensure that your local folder is not a pre-existing git repository. Your repository directory should be simply a folder with your PowerShell Universal files. If a `.git` folder exists, and you do not wish to use this repository, you should delete it and PowerShell Universal will create a new repository.
If you are populating a new git repository, you need to ensure that the remote does not have any files in it. It should be a completely bare repository. For example, when creating a repository on GitHub, do not select a license or readme.md file to be created.

Once the repository has been created, you can retrieve the git remote URL and provide that to the PowerShell Universal `appsettings.json` file.

Once you have the branch, git remote URL and credentials, you can provide them to your `appsettings.json` file and the git remote will be populated with your local files.
###
[](https://docs.powershelluniversal.com/v3/config/git#method-two-pulling-from-a-git-remote)
Method Two: Pulling from a Git Remote
The default location for the local repository is `C:\ProgramData\UniversalAutomation\Repository`
You can configure PowerShell Universal to pull from a git remote. In this configuration, you must ensure that your local repository folder is completely empty. Any files within the folder will cause the git sync to fail and prevent it from recovering.
Configure the `appsettings.json` file to include the branch, credentials and git remote URL that you are cloning. Once the fields have been set, you can start the PowerShell Universal service. The first thing the service will do is clone the repository and configure it locally.
[](https://docs.powershelluniversal.com/v3/config/git#included-files)
Included Files
-----------------------------------------------------------------------------------------
The files that are included with a git sync are any files within the local repository. This includes PS1 configuration files, pages XML files and any other files you may add manually.
The following are not included:
* appsettings.json
* database.db
* web.config
* PowerShell Universal Application Binaries
[](https://docs.powershelluniversal.com/v3/config/git#git-history-and-status-page)
Git History and Status Page
-------------------------------------------------------------------------------------------------------------------
The history tab displays all the git commit history for the current repository.

The sync status tab displays the current status of nodes within the PSU cluster.

###
[](https://docs.powershelluniversal.com/v3/config/git#testing-git-sync)
Testing Git Sync
The best way to ensure that your git sync is working properly is to click the Synchronize Now button. This will force a sync to run, and you can verify whether the settings entered worked properly.

###
[](https://docs.powershelluniversal.com/v3/config/git#viewing-changes)
Viewing Changes
You can view changes within the table of git syncs. Each sync includes the number of changes found since the last sync, the SHA of the commit and a list of changes between that SHA and the previous one. When files are in a modified state, you will be able to view the diffs using the file diff tool.

###
[](https://docs.powershelluniversal.com/v3/config/git#dealing-with-conflicts)
Dealing with Conflicts
Conflict resolution is only available in manual git sync mode.
When multiple users are editing the PowerShell Universal configuration files, there may be conflicts. PowerShell Universal will display that a particular node is in a conflicted state when attempting to commit changes. You will see a list of changes that are conflicted on the git commit page. Click the Resolve Conflict button to view the conflict in an editor.

In this example, the string for this endpoint was edited on both the remote and the local repository.

Edit the text to remove the conflict.

Save the changes and navigate back to the git commit page. Enter a new commit message for the merge conflict and click Commit Changes.

This will resolve the merge conflict and push to the remote.
[](https://docs.powershelluniversal.com/v3/config/git#git-synchronization-behavior)
Git Synchronization Behavior
---------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/git#two-way)
Two-Way
By default, git synchronization will work both ways. If you make changes within the PSU admin console, those changes will be committed and sync'd to the configured remote.
Any changes that are made in the remote will be pulled locally.
If you setup git sync with a preexisting git remote, the changes will be pulled and synchronized locally. You cannot have any changes locally.
If you setup git sync with a bare repository, the local changes will be sync'd and the repository will be initialized.
###
[](https://docs.powershelluniversal.com/v3/config/git#one-way)
One-Way
You can adjust the git synchronization behavior by changing the `GitSyncBehavior` setting in `appsettings.json`. When set to `OneWay`, the admin console and management API will become read-only. The PowerShell Universal system will pull from the remote but will never push or commit locally.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"DatabaseType": "LiteDB",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "any",
"GitPassword": "MYPAT----------------"
"GitBranch": "dev",
"GitSyncBehavior": "OneWay",
"ConfigurationScript": ""
},
###
[](https://docs.powershelluniversal.com/v3/config/git#push-only)
Push-Only
Push-only git sync mode will not pull changes from the remote. Any changes made locally will be pushed up to the remote. The console will not be read-only. This configuration is useful for scenarios where you have one machine that is used to for the source-of-truth configuration for a pool of servers that are read-only.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"DatabaseType": "LiteDB",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "any",
"GitPassword": "MYPAT----------------"
"GitBranch": "dev",
"GitSyncBehavior": "PushOnly",
"ConfigurationScript": ""
},
[](https://docs.powershelluniversal.com/v3/config/git#git-initialization-behavior)
Git Initialization Behavior
-------------------------------------------------------------------------------------------------------------------
Defines the git initialization behavior. If this parameter is not set, PowerShell Universal will attempt to select the proper method based on the state of the local file system.
###
[](https://docs.powershelluniversal.com/v3/config/git#clone)
Clone
Clones the remote to the local repository folder. The local folder must be empty.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"DatabaseType": "LiteDB",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "any",
"GitPassword": "MYPAT----------------"
"GitBranch": "dev",
"GitSyncBehavior": "OneWay",
"GitInitializationBehavior": "clone",
"ConfigurationScript": ""
},
###
[](https://docs.powershelluniversal.com/v3/config/git#init)
Init
Initializes the local repository and pushes it to the remote. The remote must be bare.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"DatabaseType": "LiteDB",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "any",
"GitPassword": "MYPAT----------------"
"GitBranch": "dev",
"GitSyncBehavior": "OneWay",
"GitInitializationBehavior": "init",
"ConfigurationScript": ""
},
[](https://docs.powershelluniversal.com/v3/config/git#personal-access-token)
Personal Access Token
-------------------------------------------------------------------------------------------------------
We recommend that you use a personal access token (PAT) over a user name and password. You can configure a personal access token by setting the password property in the `appsettings.json` or other configuration methods.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "any",
"GitPassword": "MYPAT----------------"
},
In GitHub, you can retrieve a personal access token by clicking your avatar in the top right, selecting Settings, Developer Settings and then Personal Access Tokens.
When generating your access token, ensure that you select the Repo permissions.

Note, that if you are using BitBucket, you will need to specify the user name in addition to the PAT in `appsettings.json`.
[](https://docs.powershelluniversal.com/v3/config/git#user-name-and-password)
User name and password
---------------------------------------------------------------------------------------------------------
You can also configure a git remote to authenticate with a user name and password. Set the user name and password either with the `appsettings.json` file or another configuration method.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"GitRemote": "https://github.com/myorg/myrepo.git",
"GitUserName": "myusername",
"GitPassword": "mypassword"
},
[](https://docs.powershelluniversal.com/v3/config/git#benefits-of-git-sync-vs-manual-git-sync)
Benefits of Git Sync vs Manual Git Sync
-------------------------------------------------------------------------------------------------------------------------------------------
It is possible to manually git sync a repository. PowerShell Universal uses very basic commands when dealing with git. Any changes made to PowerShell Universal through the admin console or API invoke a `git commit` and the author is set to the identity of the user making the change. During a git sync operation, we first perform a `git pull` to ensure that we have the latest version of files on the remote. Next, we perform a `git push` to push up local commits that have happened since the last sync.
You could achieve this functionality with a scheduled job.
That said, one feature of the git sync is that it analyzes the commit to ensure that only files that were changed during the sync are reloaded. This will stop dashboards from auto-deploying when they haven't changed or APIs services from restarting when environments haven't been updated. So there is a performance gain here.
The other issue is that due to the way that PowerShell Universal watches files (with a `FileSystemWatcher`) and the way that git updates files, the configurations will not reload automatically after a pull. You will have to ensure that you force the configurations to be reevaluated.
[PreviousFeature Flags](https://docs.powershelluniversal.com/v3/config/feature-flags)
[NextHosting](https://docs.powershelluniversal.com/v3/config/hosting)
Last updated 2 years ago
---
# High Availability | PowerShell Universal
PowerShell Universal can be configured for high availability ("HA") by using a combination of SQL server persistence and a load balancer to ensure that both the front end tools, such as dashboards are accessible and back-end tools, such as jobs, continue to run.

[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#persistence-configuration)
Persistence Configuration
-------------------------------------------------------------------------------------------------------------------------------------
We recommend taking advantage of [SQL persistence](https://docs.powershelluniversal.com/v3/config/persistence#sql)
to ensure that all nodes within your cluster share the same data in regards to job queues, app tokens and identities within your system. Each node should be configured with the same SQL server connection string.
As jobs run, users login and app tokens are created, the SQL server will be used to store this information and will be shared across nodes.
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#source-control-configuration)
Source Control Configuration
-------------------------------------------------------------------------------------------------------------------------------------------
We recommend using [git synchronization](https://docs.powershelluniversal.com/v3/config/git)
to store and version control the PowerShell configuration scripts used to manage the PowerShell Universal nodes. One-way git sync may be preferred as the nodes will then be read-only and pull configurations after they have been merged to your production branch. Each node pulls the configuration files on a configurable interval (defaults to 1 minute). Storing git configuration settings in the database is desired as it requires less configuration per node.
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#load-balancing)
Load Balancing
---------------------------------------------------------------------------------------------------------------
PowerShell Universal supports the use of load balancers such as F5 and nginx. There are some requirements that must be met when using load balancers.
* Persistent (sticky) sessions are required by dashboards
* Web socket support is required by the admin console and dashboards
To aid with load balancing; you can use the `/api/v1/status` endpoint for your nodes. The endpoint will return status codes based on the current state of the node. `200` means the node is online and ready to receive requests. Servers running in maintenance mode will return `503`. Servers that failed to start due to a configuration error, will return `500`. Servers with dashboards that failed to start will also return `500`.
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#maintenance-mode)
Maintenance Mode
-------------------------------------------------------------------------------------------------------------------
You can set your nodes into Maintenance Mode by clicking Platform \\ Computers and checking the maintenance mode option. Once maintenance mode is enabled, the `/api/v1/status` endpoint will begin returning `503`. This should be configured to disable traffic being routed to the node while maintenance is performed.
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#limitations)
Limitations
---------------------------------------------------------------------------------------------------------
There currently are some limitations to highly available PowerShell Universal clusters.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#multi-node-caching)
Multi-Node Caching
Caching performed using `$Cache` or `Set-PSUCache` is currently limited to the single node that is performing these operations as they are stored in memory on the system. We recommend an external cache, such as Redis, if you wish to cache data across nodes.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/high-availability#multi-node-dashboard-broadcast)
Multi-Node Dashboard Broadcast
Multi-Node dashboard broadcast messages are currently not supported. Using cmdlets like `Show-UDToast -Broadcast` will cause a toast modal to be shown to all connected users of the current node but will not be broadcast to the dashboards across all nodes.
[PreviousAzure](https://docs.powershelluniversal.com/v3/config/hosting/azure)
[NextIIS](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis)
Last updated 2 years ago
---
# Azure | PowerShell Universal
PowerShell Universal is an ASP.NET Core web application and can be hosted in Windows Azure Web Apps.
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#container-web-app)
Container Web App
---------------------------------------------------------------------------------------------------------
Container web apps allow for using Docker images as web apps in Azure. Within the Azure portal, you can create a Docker Container web app by using the App Services \\ Create Web App wizard.
Once you have selected a resource group, assigned a name and selected a compute plan, you will be able to create the web app.

Container Web App
Next, you'll need to deploy the image to your web app. To do so, select the Deployment Center and configure the image to pull. You can either pull a static tagged version (like 2.7.3) or pull the latest and your web app will automatically stay up to date with new PowerShell Universal releases.
For production environments, we suggest setting a tagged version to avoid unintentional updates to your container when it restarts. By default, Azure will automatically update containers when a tag, such as latest, is updated. This will allow you to control updates to your PowerShell Universal version.

Deployment Center Settings
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#azure-storage-and-litedb)
Azure Storage and LiteDB
For single instance systems, you can use an Azure Storage Account with a File Share to store the configuration and database.
Do not use an Azure Storage Account if you chose to use git integration. PowerShell Universal performance will be severely degraded if you use this configuration due to the performance of Azure File Shares.
We'll need to configure the Azure Storage Account for file shares to store the data for this web app. Within your storage account, create a new File Share that is transaction optimized.

Storage Account File Shares
Back in your App Service, you can setup a Path mapping to the file share we just created. In my example, I've set the mount path to `/Data`. This is where the configuration and database will be stored.

Path Mappings
Finally, we need to configure PowerShell Universal to store data on our file share. On the Application settings tab, set the `Data__ConnectionString` and `Data__RepositoryPath` to store data on the file share.

Application Settings
Restart the App Service and login to your new PowerShell Universal instance. You'll see that data generated by PowerShell Universal is being stored on the share.

File Share Content
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#git-and-sql)
Git and SQL
If you choose to use git integration in PowerShell Universal, we recommend setting up a SQL server and database for storage. Git will be used to synchronize configuration files when the container is started. SQL will store the git configuration settings alongside resources like jobs, app tokens and identities.
You'll need an Azure SQL database to get started. Once you create the resource, you will need to copy the connection string from the database to provide to PowerShell Universal.

Ensure that you have allowed Azure services to access the database.

To enable SQL support, you should set the plugins within PowerShell Universal to use the SQL plugin in the Application Configuration for your web app.
Create a `Plugins__0` setting with the value `SQL`. Next, set the `Data__ConnectionString` value to your SQL server database.

Once you have SQL configured, you can start your container. The database schema will be created as the container starts. Next, you'll need to configure git within PowerShell Universal by clicking Settings \\ Git. Enter your remote, branch, username, password or personal access token, and synchronization mode. Push-only is not recommended in this configuration because container state is lost between restarts. Ensure that the initialization mode is set to Clone.
Git settings are stored in your SQL database and will be retrieved each time the container is started.

###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#forwarded-headers)
Forwarded Headers
Containers are typically hosted behind a reverse proxy and will not be aware of the actual external URL without additional configuration. In order to ensure that systems that require the external URL, like OpenID Connect, receive the proper information, you will need to set the `ASPNETCORE_FORWARDEDHEADERS_ENABLED` environment variable to `true`.

For more information, you can read this blog post from the [Microsoft](https://devblogs.microsoft.com/dotnet/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6/)
.
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#standard-web-app)
Standard Web App
-------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#manually-creating-a-web-app)
Manually Creating a Web App
Within the Azure Portal, you will need to create a new Web App resource. PowerShell Universal currently requires the .NET 6 runtime stack. You can use either Linux or Windows.
If you choose a Windows hosting plan rather than a Linux hosting plan in Azure when configuring your WebApp then you need to choose a Basic Plan (B1) or higher to be able to use 64-bit apps. You also have to go to Settings > Configuration > General setting > Platform and select 64-bit before you run the `Publish-AzWebApp` command, or it will fail to install.

**Startup Command (Linux Only)**
When hosting in a Linux environment, you will need to set the startup command under Settings \\ Configuration \\ General Settings \\ Startup Command to the following.
Copy
dotnet Universal.Server.dll
In the below example, we'll use the Azure PowerShell module to deploy the Web App manually.
You'll first need to install Azure PowerShell.
Copy
Install-Module Az
Once installed, you'll need to connect to your subscription.
Copy
Connect-AzAccount
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#deploy-windows-files)
Deploy Windows Files
If you are using Windows, you will need to download the Windows ZIP file. This will download the latest version of PowerShell Universal.
Copy
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v3-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.win7-x64.$LatestVersion.zip" -OutFile .\Universal.zip
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#deploy-linux-files)
Deploy Linux Files
If you are using Linux, you will need to download the Linux ZIP file. This will download the latest version fo PowerShell Universal.
Copy
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v3-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.linux-x64.$LatestVersion.zip" -OutFile .\Universal.zip
Now that we have the Az module configured and the Universal ZIP downloaded, we can deploy the Web App.
Copy
$Parameters = @{
Force = $true
ResourceGroupName = 'psudemo2_group'
Name = 'psudemo2'
ArchivePath = '.\Universal.zip'
}
Publish-AzWebApp @Parameters
You can check in Azure under Deployment Center > Logs for Status Success (Active) to ensure files deployed / installed successfully.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#setting-adjustments-required)
Setting Adjustments Required
These settings can be set within the Configuration tab within the Application settings.

####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#jwt-signing-key)
JWT Signing Key
The default JWT signing key is not of a sufficient length and will need to be updated. This can be done in `appsettings.json` or by using environment variables.
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#appsettings.json)
appsettings.json
Copy
"Jwt": {
"SigningKey": "xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$",
"Issuer": "IronmanSoftware",
"Audience": "PowerShellUniversal"
},
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#environment-variable)
Environment Variable
Copy
$Env:Jwt__SigningKey = 'xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$'
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#api-url)
API URL
Azure Web Apps use a reverse proxy and PowerShell Universal does not detect the external URL appropriately. When running jobs, Universal uses the Management API to automatically look up job, script and schedule information. This means that this will fail if it cannot correctly address the external API URL.
The API URL should be the external HTTP address of your Web App. You can update this in `appsettings.json` or by using an environment variable.
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#appsettings.json-1)
appsettings.json
Copy
"Api": {
"Url": "https://psudemo.azurewebsites.net"
},
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#environment-variable-1)
Environment Variable
Copy
$Env:Api__Url = "https://psudemo.azurewebsites.net"
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#nodename)
NodeName
You can set the name of the PowerShell Universal instance by specifying the NodeName. This will ensure that restarts will not affect the PowerShell Universal database. This is not required for LiteDB installations.
Copy
$Env:NodeName = "psuazure"
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#port-and-websites_port-linux-only)
PORT and WEBSITES\_PORT (Linux Only)
To override the default port in a Linux web app, you need to set the PORT and WEBSITES\_PORT setting to 5000.
After publishing the Web App, view your PowerShell Universal instance by navigating to the Web App's URL.
####
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#persistent-storage)
Persistent Storage
The default `appsettings.json` file will store the database and configuration files in a non-persistent location. You can add environment variables to move them to persistent storage within your web app.
**Data\_\_ConnectionString**
The `Data__ConnectionString` environment variable sets the location of the database. You will have to ensure that you enable a "shared" connection for LiteDB to function properly in Azure. Set the value to the following.
Copy
filename=D:\home\Data\PowerShellUniversal\database.db;Connection=shared
**Data\_\_RepositoryPath**
The `Data__RepositoryPath` environment variable sets the location of the configuration files for Universal. Set the value to the following.
Copy
D:\home\Data\PowerShellUniversal\Repository
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#updating-your-web-app)
Updating your Web App
When a new version of PowerShell Universal is released, you will need to update the application files for your Web App. We recommend removing the application directory and redeploying the files. The database and configuration files are not stored in the application directory.
You can delete the files for your Web App by using the Kudu command API. Your Kudu credentials use Basic authentication and are the same as your [deployment credentials](https://github.com/projectkudu/kudu/wiki/Deployment-credentials)
.
To delete all the files in your Web App, issue the following command.
Copy
$Parameters = @{
Uri = "https://psudemo2.scm.azurewebsites.net/api/command"
Credential = (Get-Credential)
Body = (@{
command = "rd /s /q D:\home\site\wwwroot"
dir = "D:\home\site\wwwroot"
} | ConvertTo-Json)
}
Invoke-RestMethod @Parameters
Once you've delete the application files, you can redeploy them by running the manual creation steps again.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/azure#undefined)
[PreviousHosting](https://docs.powershelluniversal.com/v3/config/hosting)
[NextHigh Availability](https://docs.powershelluniversal.com/v3/config/hosting/high-availability)
Last updated 2 years ago
---
# IIS | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#hosting-in-iis)
Hosting in IIS
---------------------------------------------------------------------------------------------------------
PowerShell Universal supports being hosted in IIS (Internet Information Services (IIS) for Windows® Server). Please note that a series of host prerequisites and specific configuration steps are required to facilitate running PowerShell universal on IIS. Please review each section carefully as IIS requires many specific configuration settings applied to work with modern .NET Core applications such as PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#step-1-preparing-the-iis-host)
Step 1 : Preparing the IIS Host
-----------------------------------------------------------------------------------------------------------------------------------------
The following components are required in order to host PowerShell Universal on IIS.
* [Internet Information Services (IIS) Version 10.0](https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10-version-1709/new-features-introduced-in-iis-10-1709)
* Including: WebSocket Protocol
* [ASP.NET Core Hosting Bundle 6.0](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-6.0.3-windows-hosting-bundle-installer)
The following Windows Server IIS features are also required to be enabled on the IIS Host:
Feature Display Name
Requirement
Installation Script
WebSocket Protocol
Required to run PowerShell Universal
`Install-WindowsFeature Web-WebSockets`
Windows Authentication
Required for using Windows Authentication
`Install-WindowsFeature Web-Windows-Auth`
First make sure to enable the IIS feature on Windows Server and then install the ASP.NET Core hosting bundle.
**NOTE**: IIS often requires a host reboot after installing the .NET Core Hosting bundle! It is strongly recommended that you REBOOT the IIS host after installing the .NET Core Hosting bundle.
Once these prerequisites are met, you are ready to begin configuration of PowerShell Universal on IIS.
Enabling the IIS WebDav Publishing feature will cause issues with Universal. WebDav Publishing filters HTTP requests and prevents PUT and DELETE verbs by default. If you have WebDav Publishing enabled, please ensure you have it configured properly to allow these verbs.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#step-2-download-powershell-universal)
Step 2 : Download PowerShell Universal
-------------------------------------------------------------------------------------------------------------------------------------------------------
Download the Latest copy of PowerShell Universal. You will need to download the **ZIP** Archive version of PowerShell Universal. This archive is specifically built for those wishing to configure PowerShell Universal for IIS or other third party web servers. Extract the contents of the Zip to the intended web host folder location on your IIS Host.
You must ensure that the PowerShell Universal application files are unblocked after extracting them. You can unblock them with the `Unblock-File` cmdlet.
Copy
Get-ChildItem C:\inetpub\wwwroot -Recurse | Unblock-File
This location is very important and will be referenced throughout this document. Most importantly this location must be accessible by the Identity used by the IIS Application Pool.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#step-3-iis-application-pool-configuration)
Step 3 : IIS Application Pool Configuration
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Now that our Host is ready and we have downloaded PowerShell Universal, we can begin configuring IIS.
The First step in the IIS configuration process is to create a new Application Pool in IIS. Before we begin the configuration we should ensure that we select a valid identity for the IIS Application Pool.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#id-3.1-choosing-an-app-pool-identity)
3.1 : Choosing an App Pool Identity
The Application Pool Identity is crucial for PowerShell Universal as this will be the "default user" that jobs and dashboards will run as. It will also be the user that will perform read/write operations to the Universal Automation database and will be used by IIS to read the web content directory and execute the application.

Application Pool Identity Configuration
It is suggested to use "**LocalSystem"** or a **Service Account** of your choosing.
Due to limitations in IIS, the Application Pool Identity settings have **MAJOR** consequences on the behavior for "**Run As**" options when using Universal Automation.
**IIS Limitations with Universal Automation**
* **App Service configured as Local System** - Scripts will execute as the System Account by default and a _Run as Accounts_ _**CAN**_ be specified when executing a Script in Universal Automation
* **App Service configured as a Service Account** - Scripts can **ONLY** be executed with the Service Account and a **\*\***_**Run as Account**_ \_\*\*\_CANNOT\*\* be specified when executing scripts.
**Service Account Identity Requirements**
* Full Read/Write access the PowerShell Universal Application Folder we extracted in **Step 2**
* Full Read/Write access to the PowerShell Universal Database : Default: _C:\\ProgramData\\Universal Automation_
* _Log on as a batch job_ rights (e.g. from secpol.msc > Local Policies > User Rights Assignment
The Default Database location can be customized via the PowerShell Universal `appsettings.json` file if desired.
Once we have selected a valid identity we are ready to create the Application Pool in IIS.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#id-3.2-creating-the-new-iis-application-pool)
3.2 : Creating the New IIS Application Pool
Now that we have chosen an App Pool identity that has read/write access to the PowerShell Universal Application and Database folders we can create the Application Pool in IIS.
* In IIs Manager, Choose the option to **Add Application Pool...**
* **Name:** Use any Name you would like for the Application Pool
* **.NET CLR Version**: No managed code
* 
* Click **OK** create the Application Pool.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#id-3.3-configure-the-advanced-settings-of-the-iis-application-pool)
3.3 : Configure the "Advanced Settings" of the IIS Application Pool
Now that the Application Pool has been created, we will need to configure the **Advanced Settings**
* Open the "**Advanced Settings"** for the Application Pool and apply the following Configurations:
* **General / Enable 32-Bit Applications**: False
* **Process Model / Identity**: Use the Identity we selected for our Application Pool in the "Choosing an App Pool Identity" section above.
* **Process Model / Load User Profile**: True
Once the Advanced Settings have been applied, our Application Pool is ready, our next step will be to configure the IIS Web Site that will utilize this Application Pool.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#step-4-iis-web-site-configuration)
Step 4 : IIS Web Site Configuration
-------------------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#id-4.1-prepping-the-web.config-for-our-website)
4.1 : Prepping the web.config for our Website
Now that we have a valid Application Pool we need to create an IIS website to expose the application. Before we do this we will want to review the PowerShell Universal `web.config` file for our website. Within the extracted PowerShell Universal Application folder, we will find a web.config file. This configuration file has been specifically designed for IIS and has a number of configurations we need to review prior to creating the IIS Website.
Most Importantly we will need to update "**processPath**" argument value of this configuration file. This value will provide IIS with the exact path of the application binary so that it can properly launch the application.
* Open the web.config file in the PowerShell Universal Application Folder
* Locate the **
There are a variety of additional configurations in this file. We'll be reviewing these in more detail in the "Advanced Configuration" Section but you can refer to the "**Additional web.config configurations**" on this page for more details
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#id-4.2-creating-the-iis-website-for-iis)
4.2 : Creating the IIS Website for IIS
Now that an Application Pool has been created for PowerShell Universal with a valid Identity and we have configured the web.config file, we are finally ready to create the IIS Website. The Website component of IIS loads the application artifacts and exposes the application on the configured web endpoint.
1. In the IIS Manager: Click "Add Website.."
2. Configure the new website options :
* **Site Name**: Use any name you would like, ex: `PowerShell Universal.`
* **Application Pool**: **DO NOT** use the _DefaultAppPool_ - **Select** the Application Pool we created in our previous step.
* **Physical Path**: This must be the physical path to the PowerShell Universal Content we extracted from our download .zip file. **NOTE**: The AppPool identity must have access to the location.
* **Binding Settings**: Note, for initial configuration is suggested to use the base defaults, we'll update these later in our advanced configuration
* Type http - For Initial Configuration
* IP Address: All Unassigned
* Port: 80
* Host Name: Name of the Host
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#step-5-starting-website)
Step 5 : Starting Website
-----------------------------------------------------------------------------------------------------------------------------
At this point, all the required configurations should be in place, and the IIS website hosting PowerShell Universal should be up and running. With a web browser - browse to the configured website location to validate that PowerShell Universal has started. From here you can follow the "Getting Started" guide to validate base functionality. Once you are sure that the Application is working properly with a Basic IIS configuration you can proceed to the "Advanced Configuration" to secure and finalize your desired IIS Configuration.
You are are still experiencing issues with the basic IIS Configuration try checking the "Logs" path specified in the web.config for common issues. If you are still experiencing issues reach out on the forums or support for assistance.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#nested-iis-applications)
Nested IIS Applications
---------------------------------------------------------------------------------------------------------------------------
It is possible to nest multiple PowerShell Universal instances under a single application pool and website, but it does require some additional configuration.
You will need have two folders for your application files: one for each application. You will also need to setup two data folders: one for each application.

Web Site Root

Application Files

Data Files
Once you have setup your folder structure configured, you will need to create two appsettings.json files and update your web.config files for each application.
Within the appsettings.json files, you will need to set the proper paths to the data files for each instance. You will also need to configure the correct base URL for the nested site.
Copy
{
"Kestrel": {
"BasePath": "/psu1"
},
"Logging": {
"Path": "C:\\src\\psu\\data1\\log.txt",
},
"Data": {
"RepositoryPath": "C:\\src\\psu\\data1\\Repository",
"ConnectionString": "filename=C:\\src\\psu\\data1\\database.db;upgrade=true",
}
}
Next, you'll need to update the web.config files for each site to use the proper appsettings.json file and use OutOfProcess hosting.
Copy
Now, within the IIS Manager, right click on the psu1 and psu2 folders to convert them to applications.
You should now be able to access the PowerShell Universal admin console at both of the following URLs.
Copy
http://localhost/psu1/admin
http://localhost/psu2/admin
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#configuration-for-jobs)
Configuration for Jobs
-------------------------------------------------------------------------------------------------------------------------
Misconfigured app pool settings can cause jobs to fail to run. The primary cause is app pool recycling or a failure to start the web app when the server is started. This is not an issue for features like APIs or Dashboards but due to the background processing of jobs, you will need to ensure the server starts the website and keeps it running. You can [learn more here](https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html#making-asp-net-core-application-always-running-on-iis)
.
If you are going to be running scheduled jobs within your PowerShell Universal instance hosted in IIS, you must make sure to configure IIS appropriately. There are several settings to validate when configuring your application pool.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#application-initialization)
Application Initialization
Install the Application Initialization feature of the Web Server Role.

###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#app-pool-settings)
App Pool Settings
You will want to configure the following settings:
* **General**: .NET CLR version = [No Managed Code](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/advanced?view=aspnetcore-6.0#sub-applications)
.
* **General**: Start Mode = AlwaysRunning
* **Process Model**: Idle Time-out setting = 0 (disabled)
* **Recycling**: Regular Time Interval = 0.


###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#website-settings)
Website Settings
Within the IIS Site that is hosting Universal, you will need to ensure that Preload is enabled.

###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#environment-variables)
Environment Variables
While we attempt to detect that PSU is running within IIS, you may run into problems with the negotiate authentication handler being enabled when it's not supported in IIS. To ensure this is not a problem, you can completed disabled it by setting the below environment variable on your IIS machine.
Copy
$Env:PSU_DISABLE_WIN_AUTH = true
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#debugging-issues-with-iis-and-jobs)
Debugging Issues with IIS and Jobs
If you are still having issues with IIS and jobs, you should consider turning on [IIS recycle logging](https://blogs.iis.net/ganekar/iis-7-0-application-pool-recycles-log-a-event-in-windows-event-log)
to ensure that IIS is keeping your site running.
As of PowerShell Universal 3.3, you can via the uptime of the system on the home page of the admin console to get a good indicator of the last time the service was started.
Prior to version 3.3, you can view the server uptime by visiting the [Hangfire](https://docs.powershelluniversal.com/v3/development/hangfire)
dashboard and clicking the Servers tab.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#authentication)
Authentication
---------------------------------------------------------------------------------------------------------
PowerShell Universal can use anonymous authentication and Windows Authentication in IIS.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#windows-authentication)
Windows Authentication
To enable Windows Authentication, you will first need to enable it for your Web Server and then for your website. You can find the authentication settings under the Authentication section in IIS Manager.

For the website, set the same settings.

Once authentication is enabled in IIS, you will have to ensure that Windows Authentication is enabled for PowerShell Universal.
First, adjust the `web.config` file to forward the Windows authentication token.
Copy
Next, enable Windows Authentication in the `appsettings.json` file for PowerShell Universal.
Copy
"Authentication" : {
"Windows": {
"Enabled": "true"
},
}
Restart your Application Pool and now you should be able to login with Windows credentials.
When enabling Windows Authentication but not Anonymous Authentication, you will no longer be able to use PowerShell Universal AppTokens. You will need to enable both authentication methods to support Windows Credentials as well as App Tokens.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#anonymous-authentication)
Anonymous Authentication
Anonymous Authentication can be enabled to allow for app tokens and other requests to be transmitted through the IIS proxy. You will need to enable Anonymous Authentication on both the Server and Web site levels. There is no additional configuration to do within PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#additional-web.config-configurations)
Additional web.config configurations
-----------------------------------------------------------------------------------------------------------------------------------------------------
The settings within the Universal web.config can be adjusted as you see fit. Below you will find a description of each setting.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#forwardwindowsauthtoken)
ForwardWindowsAuthToken
This setting is used for Windows Authentication. If you wish to use Windows Authentication with IIS, ensure that you disable Anonymous Authentication and enable Windows Authentication within your IIS site and then set this setting to true.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#stdoutlogenabled-and-stdoutlogfile)
StdoutLogEnabled and StdoutLogFile
This setting is used for debugging start up issues with your Universal setup. It's recommended to enable this when first configuring IIS integration. You can disable it once everything is configured. You need to ensure that your AppPool identity has write access to the StdOutLogFile location.
###
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#hostingmodel)
HostingModel
The hosting model sets how the Universal server will run. When set to InProcess, the Universal Server will run from within the IIS agent. This provides better performance than using OutOfProcess hosting. InProcess hosting does not work with StdOutLogEnabled. It's recommended to use OutOfProcess hosting only while configuring Universal and, InProcess when your configuration steps have been completed.
[](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis#upgrading)
Upgrading
-----------------------------------------------------------------------------------------------
When upgrading, ensure that you do not copy files over the top of your existing install. Instead, delete the current application files and copy the new ones into the directory. Copying over the top of the files can result in binaries being present in the installation directory that are not expected and can issues with the system.
[PreviousHigh Availability](https://docs.powershelluniversal.com/v3/config/hosting/high-availability)
[NextLogin Page](https://docs.powershelluniversal.com/v3/config/login-page)
Last updated 2 years ago
---
# Login Page | PowerShell Universal
Login page customization requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
The login page colors, image, copyright and title can be customized by editing the `.universal/loginPage.ps1` file.
[](https://docs.powershelluniversal.com/v3/config/login-page#customizing-the-login-page)
Customizing the login page
------------------------------------------------------------------------------------------------------------------------
You can host an image by using [Published Folders](https://docs.powershelluniversal.com/v3/platform/published-folders)
. In this example, we have a `dbatools.png` file in our local folder.

DBATools Logo
Next, we can create a `loginPage.ps1` file in the repository folder. Add the various colors, text and image URL to customize the login page. As soon as you save this file, you can refresh the login page to see the result.
Copy
$LoginPage = @{
PrimaryColor = '#5c2751'
Title = 'DBATools Web Portal'
Copyright = 'DBATools 2020'
HeaderFontColor = 'white'
HeaderColor = '#4bc0d9'
SecondaryColor = '#6457a6'
SecondaryFontColor = 'white'
Image = 'http://localhost:5000/images/dbatools.png'
Links = @(
New-PSULoginPageLink -Text 'Google' -Url 'http://www.google.com'
New-PSULoginPageLink -Text 'Microsoft' -Url 'http://www.microsoft.com'
)
}
New-PSULoginPage @LoginPage
This login page looks like this.

[](https://docs.powershelluniversal.com/v3/config/login-page#customizing-the-login-page-in-the-admin-console)
Customizing the login page in the Admin Console
------------------------------------------------------------------------------------------------------------------------------------------------------------------
This feature will be available in PowerShell Universal 2.3.
In addition to being able to customize the login page via PowerShell, you can also do so in the admin console. Click Settings \\ Login page to adjust the settings.

[](https://docs.powershelluniversal.com/v3/config/login-page#customizing-the-login-page-with-a-dashboard)
Customizing the login page with a Dashboard
----------------------------------------------------------------------------------------------------------------------------------------------------------
You can override the login page with a dashboard by setting a dashboard's base URL to `/login`. You need to ensure that the dashboard does not require authentication.
Copy
New-PSUDashboard -Name 'Dashboard' -Path 'dashboard.ps1' -BaseUrl '/login'
You will then need to implement the login features manually.
[](https://docs.powershelluniversal.com/v3/config/login-page#api)
API
--------------------------------------------------------------------------
* [New-PSULoginPage](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSULoginPage.txt)
* [New-PSULoginPageLink](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSULoginPageLink.txt)
###
[](https://docs.powershelluniversal.com/v3/config/login-page#undefined)
[PreviousIIS](https://docs.powershelluniversal.com/v3/config/hosting/hosting-iis)
[NextManagement API](https://docs.powershelluniversal.com/v3/config/management-api)
Last updated 2 years ago
---
# Management API | PowerShell Universal
You can manage PowerShell Universal using the built in Management API. It provides the ability to perform all the actions as the admin console in an automated manner. You can view and test the API by visiting the Swagger API documentation at it's default location on your machine `http://localhost:5000/swagger/index.html` .
The Management API is built in and does not require a license to Universal API.
[](https://docs.powershelluniversal.com/v3/config/management-api#powershell-module)
PowerShell Module
----------------------------------------------------------------------------------------------------------
We provide a PowerShell module that calls the API on your behalf so you do not have to write the HTTP requests yourself. You can download this module from the PowerShell Gallery.
Copy
Install-Module Universal
The PowerShell module requires an app token and computer name to call the Universal server. You can provide this items on each call.
Copy
Invoke-PSUScript -Script $Script -ComputerName http://localhost:5000 -AppToken $AppToken
Additionally, you can connect to the Universal server using `Connect-UAServer`.
Copy
Connect-PSUServer -ComputerName http://localhost:5000 -AppToken $AppToken
[](https://docs.powershelluniversal.com/v3/config/management-api#rest-api)
REST API
----------------------------------------------------------------------------------------
The PowerShell Universal Management API can be accessed via REST calls. You can view the available calls using the built in Swagger API documentation. You will need an App Token to make calls to the REST API.
[](https://docs.powershelluniversal.com/v3/config/management-api#app-tokens)
App Tokens
--------------------------------------------------------------------------------------------
[App Tokens](https://docs.powershelluniversal.com/v3/config/security/app-tokens)
are required by the Management API. You will need to use an App Token with both the PowerShell Cmdlets as well as the calling the Management API directly through REST.
You can use an App Token with `Invoke-RestMethod` by specifying the authorization header.
Copy
Invoke-RestMethod http://localhost:5000/api/v1/script -Headers @{ Authorization = "Bearer appToken" }
[PreviousLogin Page](https://docs.powershelluniversal.com/v3/config/login-page)
[NextPersistence](https://docs.powershelluniversal.com/v3/config/persistence)
Last updated 3 years ago
---
# Persistence | PowerShell Universal
PowerShell Universal stores job output and input, identities and app tokens within the database.
[](https://docs.powershelluniversal.com/v3/config/persistence#litedb)
LiteDB
---------------------------------------------------------------------------------
By default, PowerShell Universal stores all data within a single file database local to the PowerShell Universal application.
###
[](https://docs.powershelluniversal.com/v3/config/persistence#configuring-litedb)
Configuring LiteDB
To configure the database location for LiteDB you can edit the `appsettings.json` file or set the file path during installation if using the MSI. By default, the database is stored in the ProgramData directory. Update this setting to change the database location.
Copy
"ConnectionString": "filename=%ProgramData%\\UniversalAutomation\\database.db;upgrade=true",
LiteDB does not support multiple instances of PowerShell Universal connecting to the same database.
[](https://docs.powershelluniversal.com/v3/config/persistence#sql)
SQL
---------------------------------------------------------------------------
SQL support requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
You can configure PowerShell Universal to store data within a Microsoft SQL Database. This allows you to scale out your database and PowerShell Universal instances. PowerShell Universal will automatically run jobs across the pool of agents. You can update the `appsettings.json` file for PowerShell Universal as follows to connect to a central SQL server.
Copy
"Plugins": [\
"SQL"\
],
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=PSUv3;Integrated Security=true;",
"GitRemote": "",
"GitUserName": "",
"GitPassword": "",
"GitBranch": "",
"GitSyncBehavior": "TwoWay",
"GitInitializeBehavior": "",
"ConfigurationScript": ""
},
The PowerShell Universal instances will share a single job queue and only one instance will run a job either on the schedule, as a trigger, or manually. All data about jobs will be stored in the centralized database.
###
[](https://docs.powershelluniversal.com/v3/config/persistence#manual-schema-install-update)
Manual Schema Install\\Update
In some environments, the PSU service may not have access to create schema in the database. In this scenario, you can manually install and update the schema by executing SQL files included with PowerShell Universal. Within the PowerShell Universal installation folder, you will find a `SQL` directory that includes two SQL files.
Run these files against your database prior to upgrading PowerShell Universal. You will need to stop PowerShell Universal while you are doing this. You can run them in any order. Both scripts are idempotent.
By default, PowerShell Universal will attempt to update the schema of the database. To completely disable this feature, you can set the `RunMigrations` setting to false in appsettings.json.
Copy
"Data": {
"RunMigrations": false
}
###
[](https://docs.powershelluniversal.com/v3/config/persistence#frequently-asked-questions)
Frequently Asked Questions
####
[](https://docs.powershelluniversal.com/v3/config/persistence#database-account-privileges)
Database Account Privileges
_What is the maximum permission for a database user account needed during installs or upgrades?_
During the startup of the PowerShell Universal server, the database will be installed and upgraded, if required. If the database already exists, you will need `db_owner` in order to create and modify tables. If the database does not yet exist, you will need `dbcreator` .
_What is the maximum permission needed once the database(s) has been created for ongoing daily activities?_
PowerShell Universal performs limited database operations during daily activities. This consist of inserting, updating, deleting and viewing data in the tables created. You will only need the following roles: `db_datawriter`, `db_datareader`
####
[](https://docs.powershelluniversal.com/v3/config/persistence#database-and-operating-system-install-and-support)
Database & Operating System Install & Support
_Which versions of SQL Server are supported? Is there a minimum version required?_
We support Microsoft SQL Server 2016 and onwards.
_Do any other SQL Server components need to be installed beside the Database Engine?_
None
_Which versions of Windows Server are supported?_
Currently Supported versions by Microsoft - Windows Server 2012 R2 and onwards. Currently, the extended end date for support for 2012 R2 from Microsoft is October 10, 2023, at which time we will drop support for the operating system.
####
[](https://docs.powershelluniversal.com/v3/config/persistence#database-maintenance-and-backup)
Database Maintenance & Backup
_How quickly does the data need to be recovered?_
Data is primarily for reporting, aside from app tokens, so data doesn't need to be immediately recovered. Depending on the use of the app tokens, some systems may lose access to the server when the database is being recovered.
####
[](https://docs.powershelluniversal.com/v3/config/persistence#database-design)
Database Design
_How large will the database(s) be for the initial load?_
The initial database does not include a large set of initial data and primarily will only take the space of the schema.
_What is the estimated growth per month/year of each database?_
The estimated growth depends on many factors that include the number of jobs run per month, amount of job log and pipeline output stored, and how aggressive data is groomed.
Database size rarely grows over 2 GB in size with the default settings. Extending groom settings to contain a longer history of jobs, running jobs more frequently and storing data like terminal history can increase the database size.
_Does your application support use of SQL Server compression (Row or Page level)?_
Yes. We use a standard database client and has no limitation on row and page level compression.
####
[](https://docs.powershelluniversal.com/v3/config/persistence#database-usage)
Database Usage
_Is this a transactional (OLTP) or reporting (OLAP) database?_
This is primarily a reporting database that includes information like job history, job output and app tokens.
_What is the total number of user/device connections?_
One connection pool per PSU server. 1024 connections maximum per server.
_What is the maximum number of concurrent user/device connections?_
One connection pool per PSU server. 1024 connections maximum per server.
[](https://docs.powershelluniversal.com/v3/config/persistence#data-migration)
Data Migration
-------------------------------------------------------------------------------------------------
PowerShell Universal includes a data migration tool for moving data from LiteDB to SQL. You can find `DataMigration.exe` in the installation folder.
You will need access to the LiteDB database and the SQL server in order to run the tool. You cannot have PowerShell Universal running while migrating the data.
Below is an example of how to run the data migration tool.
Copy
DataMigration.exe -l C:\ProgramData\UniversalAutomation\database.db -s 'Server=(localdb)\mssqllocaldb;Database=PSU;Trusted_Connection=True;'
By default, the migration tool will install the schema for the database. You can use the `--noschema` parameter to prevent this from happening.
###
[](https://docs.powershelluniversal.com/v3/config/persistence#command-line-arguments)
Command Line Arguments
Argument
Description
Required
\-l, --litedb
Path to the LiteDB database file.
yes
\-s, --sql
Connection string for the SQL database
yes
\-c, --clean
Drop the database before migrating
no
\--noschema
Skip schema migrations and only transfer the data
no
\--continueonerror
Continue migrating items even if there is an error
no
[PreviousManagement API](https://docs.powershelluniversal.com/v3/config/management-api)
[NextApp Settings](https://docs.powershelluniversal.com/v3/config/settings)
Last updated 2 years ago
---
# App Settings | PowerShell Universal
Application settings can be found within the `appsettings.json` file within the installation directory. This file defines various settings you can apply to Universal. Although you can edit this file directly, it's recommended that you use one of the following methods to persist settings as the `appsettings.json` file in the installation directory will be overridden on upgrades.
When installed from the MSI, the installation directory for PowerShell Universal is `${env:ProgramFiles(x86)}\Universal`.
[](https://docs.powershelluniversal.com/v3/config/settings#programdata-appsettings.json)
ProgramData AppSettings.json
--------------------------------------------------------------------------------------------------------------------------
You can create an appsettings.json file within the `$Env:ProgramData\PowerShellUniversal` folder. You can use a subset of the settings from within the `appsettings.json` file. For example, if you wanted to override the JWT settings, you could have an `appsettings.json` file like this.
Copy
{
"Jwt": {
"SigningKey": "PleaseUseYourOwnSigningKeyHere",
"Issuer": "IronmanSoftware",
"Audience": "PowerShellUniversal"
}
}
[](https://docs.powershelluniversal.com/v3/config/settings#environment-variables)
Environment Variables
------------------------------------------------------------------------------------------------------------
You can also set environment variables for your settings. Environment variables should have an underscore between each subset of the `appsettings.json` file\*. For example, if you want to change the JWT signing key via environment variable, you would set the variable `$Env:Jwt__SigningKey`. If you wanted to set the external API URL, you would set `$Env:Api__Url`.
###
[](https://docs.powershelluniversal.com/v3/config/settings#examples)
Examples
Using an environment variable for the OpenID Connect secret.
Copy
$Env:Authentication__OIDC__ClientSecret = "mySecret"
Using an environment variable for JWT signing key.
Copy
$Env:Jwt__SigningKey = "mySigningKey"
\* It is possible to set the License by assigning the environment variable PSULICENSE to the entire content of your license file.

figure shows setting the License by way of environment variables
[](https://docs.powershelluniversal.com/v3/config/settings#command-line)
Command Line
------------------------------------------------------------------------------------------
You can specify the location of the `appsettings.json` file by using the `--appsettings` command line argument for `Universal.Server.exe` .
Copy
.\Universal.Server.exe --appsettings C:\appsettings.json
[](https://docs.powershelluniversal.com/v3/config/settings#setting-descriptions)
Setting Descriptions
----------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/settings#kestrel-endpoints)
Kestrel / Endpoints
**Default Value**
Copy
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000"
}
},
"RedirectToHttps": "false"
},
The Kestrel endpoints section allows you to configure the web server. This settings are not used when hosting in IIS. In this section you can configure options like HTTPS and the port that Universal is listening on.
Kestrel is the web server implementation for ASP.NET Core that PowerShell Universal uses. For more information on the configuration options for Kestrel, visit this [Microsoft Documentation page](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#listenoptionsusehttps)
.
Key
Description
RedirectToHttps
When true, the web server will redirect HTTP requests to HTTPS
BasePath
Required when configuring PowerShell Universal as a nested site within IIS. This should contain the nested IIS route. Such as `/psu`
Hsts \\ MaxAgeDays
Sets the max age in days for [HTTP Strict Transport Security](https://https.cio.gov/hsts/)
.
CookiePolicy
When set to SameSiteNone, the SameSite=None value will be set on cookies in PSU. This is useful for when hosting PSU in iframes.
###
[](https://docs.powershelluniversal.com/v3/config/settings#application-insights)
Application Insights
**Default value**
Copy
"ApplicationInsights": {
"InstrumentationKey": ""
},
Key
Description
InstrumentationKey
Sets the instrumentation key for Application Insights.
###
[](https://docs.powershelluniversal.com/v3/config/settings#logging)
Logging
**Default Value**
Copy
"Logging": {
"Path": "%PROGRAMDATA%/PowerShellUniversal/log.txt",
"RetainedFileCountLimit": 31,
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
The logging options define the level of logging exposed by Universal. The core Universal logging setting Logging / LogLevel / Default can be adjusted to increase the level of logging by the Universal components.
Key
Description
Path
Path to the log file.
RetainedFileCountLimit
The number of log files to retain. A new log file will be created each day.
LogLevel
The log levels for various portions for the Universal server. You can set values such as Debug, Information, Warning and Error.
###
[](https://docs.powershelluniversal.com/v3/config/settings#allowedhosts)
AllowedHosts
**Default Value**
Copy
"AllowedHosts": "*",
The hosts that are allowed to connect to the webserver. Defaults to any host.
###
[](https://docs.powershelluniversal.com/v3/config/settings#corshosts)
**CorsHosts**
**Default Value**
Copy
"CorsHosts": "",
Configures the hosts that are allowed to make cross-origin resource sharing requests (CORS) to the server. To allow multiple hosts, separate each host by a semicolon.
Copy
"CorsHosts" : "https://www.google.com;https://login.microsoftonline.com"
###
[](https://docs.powershelluniversal.com/v3/config/settings#data)
**Data**
**Default Value**
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"GitRemote": "",
"GitUserName": "",
"GitPassword": "",
"GitBranch": "",
"ConfigurationScript": "",
"Mode": "automatic"
},
Key
Description
RepositoryPath
Path to the storage location of the configuration files used by Universal.
ConnectionString
Path to the database used by Universal.
GitRemote
Git remote used to sync to Universal.
GitBranch
Git branch to checkout when syncing to Universal.
GitUserName
Git user name used to sync to the GitRemote. When using a PAT, this can be any value.
GitPassword
The Git user password or personal access token used to sync to the GitRemote.
ConfigurationScript
Location of a custom configuration script to load. You can return objects like scripts, dashboards and endpoints from this script.
Mode
Sets the git mode. It can be either manual or automatic. Defaults to manual.
###
[](https://docs.powershelluniversal.com/v3/config/settings#api)
**API**
**Default Value**
Copy
"Api": {
"Url": ""
},
Key
Description
Url
Sets the external URL used internally by Universal. This is necessary when running Universal from within a reverse proxy like IIS. When using cmdlets like `Get-UAScript` from within a running job, the Universal server needs to determine where the web server. When running within a proxy, it cannot determine this itself. You will want to configure this to point to the name and port of the IIS website in this configuration.
###
[](https://docs.powershelluniversal.com/v3/config/settings#authentication)
**Authentication**
**Default Value**
Copy
"Authentication" : {
"Windows": {
"Enabled": "false"
},
"WSFed": {
"Enabled": "false",
"MetadataAddress": "",
"Wtrealm": "",
"CallbackPath": "/auth/signin-wsfed",
"Wreply": "",
"UseTokenLifetime": true,
"CorrelationCookieSameSite": ""
},
"OIDC": {
"Enabled": "false",
"CallbackPath": "/auth/signin-oidc",
"ClientID": "",
"ClientSecret": "",
"Resource": "",
"Authority": "",
"ResponseType": "",
"SaveTokens": "false",
"CorrelationCookieSameSite": "",
"UseTokenLifetime": true
},
"SessionTimeout": "25"
},
**Windows**
**Key**
Description
Enabled
Enables or disables [Windows Authentication](https://docs.powershelluniversal.com/v3/api/security#authenticating-with-windows-authentication)
.
####
[](https://docs.powershelluniversal.com/v3/config/settings#oidc)
OIDC
OpenID Connect authentication settings.
Key
Description
Enabled
Whether OIDC is enabled.
CallbackPath
The path that the OIDC provider will call back to.
ClientID
The configured OIDC client ID.
ClientSecret
The configured OIDC client secret.
Resource
Resources granted with this OIDC token.
Authority
The authority to invoke when authenticating. This is the URL of your OIDC provider.
ResponseType
The type of response returned by the provider. This most common value here is `code`
SaveTokens
Whether to save the token so it is available to endpoints like dashboards.
CorrelationCookieSameSite
[Correlation cookie same settings.](https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-5.0)
UseTokenLifetime
If set to true, the cookie life time will be set to the token life time. This overrides the session time out value.
GetUserInfo
Returns additional user information for use within roles.ps1 files. You can access the additional information using the $UserInfo variable.
####
[](https://docs.powershelluniversal.com/v3/config/settings#wsfed)
WSFed
WS-Federation authentication settings.
Key
Description
Enabled
Whether WS-Fed is enabled.
MetadataAddress
The metadata address to retrieve information about the WS-Fed instance.
Wrealm
Wreply
CallbackPath
The path that the OIDC provider will call back to.
UseTokenLifetime
If set to true, the cookie life time will be set to the token life time. This overrides the session time out value.
CorrelationCookieSameSite
[Correlation cookie same settings.](https://docs.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-5.0)
###
[](https://docs.powershelluniversal.com/v3/config/settings#jwt)
**JWT**
JSON Web Token configuration settings
**Default Value**
Copy
"Jwt": {
"SigningKey": "PleaseUseYourOwnSigningKeyHere",
"Issuer": "IronmanSoftware",
"Audience": "PowerShellUniversal"
},
Key
Description
SigningKey
The signing key for the JWT tokens.
Issuer
The issuer that will be included in the token.
Audience
The audience that will be included in the token.
###
[](https://docs.powershelluniversal.com/v3/config/settings#secrets)
Secrets
Options for configuring the default secret vaults.
**Default Value**
Copy
"Secrets": {
"SecretStore": {
"Password": "PSUSecretStore"
},
"Database": {
"EncryptionKey": "=b0ywQA@VOSdr&R7an5g&XK6NVO%s4Tf"
}
}
Key
Description
SecretStore \\ Password
The password for the PSUSecretStore vault. This uses the Microsoft SecretStore module.
Database \\ EncryptionKey
The AES 128 encryption key used to encrypt secrets stored in the database.
####
[](https://docs.powershelluniversal.com/v3/config/settings#generating-an-encryption-key)
Generating an Encryption Key
Encryption keys are 128-bit and require the proper length. They are encoded as a base64 string and converted to bytes on startup.
You can use the following code to generate a secret key of the proper length.
Copy
$random = [System.Security.Cryptography.RandomNumberGenerator]::Create();
$buffer = New-Object byte[] 16;
$random.GetBytes($buffer);
[Convert]::ToBase64String($buffer)
###
[](https://docs.powershelluniversal.com/v3/config/settings#universalautomation)
UniversalAutomation
Settings for automation specific features.
**Default Value**
Copy
"UniversalAutomation": {
"Queues": [],
"JobHandshakeTimeout": 5,
"JobDebugging": false,
"ContinueJobOnServerStop": false
}
Key
Description
Queues
Custom queues that this PSU instance is a part of.
JobHandshakeTimeout
The number of seconds to wait before failing a job after starting the PowerShell process to execute it if the process does not communicate back to the server.
JobDebugging
Whether to generate files in the temporary directory when starting job. This is useful for debugging if jobs are timing out before starting.
ContinueJobOnServerStop
Whether to continue running a job after the service has stopped. Job progress will fail to be reported but the script will continue to run.
###
[](https://docs.powershelluniversal.com/v3/config/settings#hideadminconsole)
**HideAdminConsole**
Prevents the service from serving the admin console. This will prevent the admin console from being used by any user, including administrators.
###
[](https://docs.powershelluniversal.com/v3/config/settings#nodename)
NodeName
The node name option is used to change the name of the PowerShell Universal instance. By default, this is the local computer's name. When using PowerShell Universal in a container, this can become probematic because the name can change whenever the container is restarted.
To set a static node name, change this parameter.
###
[](https://docs.powershelluniversal.com/v3/config/settings#profiling)
Profiling
Enables [profiling](https://docs.powershelluniversal.com/v3/development/profiling)
of scripts within PowerShell Universal. This is disabled by default as there is a memory impact when enabling profiling.
[PreviousPersistence](https://docs.powershelluniversal.com/v3/config/persistence)
[NextSecurity](https://docs.powershelluniversal.com/v3/config/security)
Last updated 2 years ago
---
# Security | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/config/security#local-accounts)
Local Accounts
----------------------------------------------------------------------------------------------
Local accounts are created and stored in the PowerShell Universal database. By default, credentials are stored in the local database vault.
To create a local account, you can navigate to Security \\ Identities and create a new identity. Ensure that the Local Account switch is enabled and set a password.

If you have a licensed instance of PowerShell Universal, you can use a different credential vault.
[](https://docs.powershelluniversal.com/v3/config/security#forms-authentication)
Forms Authentication
----------------------------------------------------------------------------------------------------------
The forms authentication script is only called when users login through the login page. If you use any other authentication method, this script is not called. Role policy scripts are called for all authentication types.
By default, the forms authentication script is configured to accept the user _Admin_ and a password of _Admin_. You can configure this authentication policy to interact with whatever system you like. The script will receive a `PSCredential` object that contains the user name and password entered by the user at the login page.
Authentication settings are also stored with `authentication.ps1`
To update forms authentication, click Security (below Settings) then Authentication. Click the 'Edit Details' button from there to review (or update) the forms authentication code.

You can update the PowerShell script found in settings to configure how the user is authenticated. You'll need to return a `New-PSUAuthenticationResult` from the script to indicate whether the user was successfully authenticated.
Copy
param(
[PSCredential]$Credential
)
#
# You can call whatever cmdlets you like to conduct authentication here.
# Just make sure to return the $Result with the Success property set to $true
#
if ($Credential.UserName -eq 'Admin')
{
New-PSUAuthenticationResult -Success -UserName 'Admin'
}
else
{
New-PSUAuthenticationResult -ErrorMessage 'Bad username or password'
}
###
[](https://docs.powershelluniversal.com/v3/config/security#setting-a-password)
Setting a Password
You can check the password of the credential by using the `GetNetworkCredential()` method of `PSCredential`.
Copy
param(
[PSCredential]$Credential
)
#
# You can call whatever cmdlets you like to conduct authentication here.
# Just make sure to return the $Result with the Success property set to $true
#
if ($Credential.UserName -eq 'Admin' -and $Credential.GetNetworkCredential().Password -eq 'MySuperSecretPassword')
{
New-PSUAuthenticationResult -Success -UserName 'Admin'
}
else
{
New-PSUAuthenticationResult -ErrorMessage 'Bad username or password'
}
###
[](https://docs.powershelluniversal.com/v3/config/security#setting-claims)
Setting Claims
During forms authentication, you can set claims that will be available within role policies. This can provide a performance benefit when interacting with remote systems since you can perform a single claim lookup and then evaluate the claims locally rather than having to make additional calls to the remote system.
This example uses Active Directory to look up group membership and assign the as claims that will be available within the roles scripts.
Copy
param(
[PSCredential]$Credential
)
#
# You can call whatever cmdlets you like to conduct authentication here.
# Just make sure to return the $Result with the Success property set to $true
#
$Result = [Security.AuthenticationResult]::new()
if ($Credential.UserName -eq 'Admin')
{
#Maintain the out of box admin user
New-PSUAuthenticationResult -UserName 'Admin' -Success
}
else
{
# Get current domain using logged-on user's credentials - this validates their credential
$CurrentDomain = "LDAP://DC=mydemodomain,DC=com" # Insert Your Domain Here
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,($Credential.UserName),$Credential.GetNetworkCredential().password)
if ($domain.name -eq $null)
{
"Authentication failed for $($Credential.UserName)!" | Out-File "C:\test\adlogin.txt"
write-host "Authentication failed - please verify your username and password."
New-PSUAuthenticationResult -UserName $Credential.UserName
}
else
{
write-host "Successfully authenticated with domain $($domain.name)"
"Authentication success for $($Credential.UserName)!" | Out-File "C:\test\adlogin.txt"
New-PSUAuthenticationResult -UserName $Credential.UserName -Success -Claims {
Get-ADPrincipalGroupMembership $Credential.UserName | Select-Object -ExpandProperty name | ForEach-Object {
New-PSUAuthorizationClaim -Type Role -Value $_
}
}
}
}
Within your `roles.ps1` file, you will be able to use these claims to validate group membership.
This example checks to see if the user is part of the SOC\_Admins group.
Copy
param($User)
$Roles = $User.Claims | Where-Object Type -eq Role | Select-Object -ExpandProperty Value
$Roles -contains 'SOC_Admins'
###
[](https://docs.powershelluniversal.com/v3/config/security#variables)
Variables
These are the variables defined within the security scripts.
Name
Description
Type
$Cookies
Cookies provided in the client's HTTP request.
hashtable
$Headers
Headers provided in the client's HTTP request.
hashtable
$LocalIpAddress
The local IP address of the request.
string
$LocalPort
The local port of the request.
string
$RemoteIpAddress
The remote IP address of the request.
string
$RemotePort
The remote port of the request.
string
###
[](https://docs.powershelluniversal.com/v3/config/security#live-log)
Live Log
You can use the live log view on the authentication page to view information about the script execution. The live log view will display PowerShell streams.
[](https://docs.powershelluniversal.com/v3/config/security#openid-authentication)
OpenID Authentication
------------------------------------------------------------------------------------------------------------
You can configure OpenID authentication and authorization by adjusting the settings within the `OpenID` section of the `appsettings.json` file. Authorization policies that you configure within Universal will be run on the user's identity after authentication is successful.
[](https://docs.powershelluniversal.com/v3/config/security#windows-authentication)
Windows Authentication
--------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security#appsettings.json)
appsettings.json
Windows Authentication provides single-sign on support for browsers and environments that support it. To enable Windows Authentication, set the `WindowsAuthentication` enabled setting to true in `appsettings.json`.
Copy
"Windows": {
"Enabled": "true"
},
###
[](https://docs.powershelluniversal.com/v3/config/security#authentication.ps1)
Authentication.ps1
You can enable Windows authentication by adding a new authentication provider in Security \\ Authentication. Select Windows and enable the authentication.

Once Windows set to authenticated, Windows authentication can now be used against Universal. You will have to log out in order to use Windows authentication.
###
[](https://docs.powershelluniversal.com/v3/config/security#windows-authentication-in-iis)
Windows Authentication in IIS
To enable Windows Authentication in IIS, ensure that you enable Windows Authentication and disable anonymous authentication.

In the web.config file that is included with PowerShell Universal, ensure that you have set the `forwardWindowsAuthToken` to `true`.
Copy
###
[](https://docs.powershelluniversal.com/v3/config/security#windows-authentication-outside-of-iis)
Windows Authentication outside of IIS
Windows Authentication is supported outside of IIS but requires configuration of the account running the Universal service.
####
[](https://docs.powershelluniversal.com/v3/config/security#windows)
Windows
On Windows, you should install PowerShell Universal as a [Windows Service](https://docs.powershelluniversal.com/v3/getting-started#windows)
. Once the service is installed, you will need to create a [service account user](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account#application-service-account)
and set the service to run with that user's account. The Windows authentication [setting](https://docs.powershelluniversal.com/v3/config/settings)
needs to be set to true.
Copy
"Windows": {
"Enabled": "true"
},
The service account needs to have a Service Principal Name (spn) configured for the computer account. You can do this using the `setspn` command. The computer name needs to be the full qualified name of the machine running Universal.
Copy
setspn -S HTTP/myservername.mydomain.com myuser
For more information, you can follow the Microsoft documentation for configuring ASP.NET Core Windows Authentication: [Configuring a Windows machine for Windows Authentication](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1&tabs=visual-studio#windows-environment-configuration)
####
[](https://docs.powershelluniversal.com/v3/config/security#linux)
Linux
[Configuring a Linux or Mac OS machine for Windows Authentication](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1&tabs=visual-studio#linux-and-macos-environment-configuration)
###
[](https://docs.powershelluniversal.com/v3/config/security#cached-claims)
Cached Claims
PowerShell Universal will cache group membership claims when using Windows Authentication. Claims are cached for the configured session timeout value (default is 25 minutes).
To clear the cache manually, navigate to Security \\ Roles and click the Clear Cached Claims button.
[](https://docs.powershelluniversal.com/v3/config/security#browser-configuration)
Browser Configuration
------------------------------------------------------------------------------------------------------------
Depending on your local environment, you may need to configure your browser to properly pass credentials to PowerShell Universal.
* [Google Chrome](https://chromeenterprise.google/policies/#HTTPAuthentication)
* [Microsoft Edge](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies#http-authentication-policies)
[](https://docs.powershelluniversal.com/v3/config/security#authorization)
Authorization
--------------------------------------------------------------------------------------------
User authorization is accomplished with roles. Roles can either be assigned through claims mapping, a policy script or by assigning the role directly to the identity.
By default, users will receive all roles when logging in. Multiple role assignments are valid in PowerShell Universal. While you configure roles, you can choose to disable roles you are not yet or do not plan to use.
Disabling the Administrators role will prevent you from making changes to roles within the Admin Console.
###
[](https://docs.powershelluniversal.com/v3/config/security#role-to-claim-mapping)
Role to Claim Mapping
You can map roles to a claim (such as a group membership) by using the `-ClaimType` and `-ClaimValue` parameters of `New-PSURole`. Settings are also available in the role properties dialog within Security \\ Roles.

For example, with Windows authentication, if you wanted to map a group to a role, you could configure it such that the group SID maps to the administrator role.
Copy
New-PSURole -Name Administrator -ClaimType 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid' -ClaimValue 'S-123-123-123'
Mapping roles to claims in this manner is faster than Policy scripts because it does not require PowerShell to be run when the user is logging in.
###
[](https://docs.powershelluniversal.com/v3/config/security#view-claim-information)
View Claim Information
To help develop policy scripts or assign roles to claims, you can view claim information by clicking View Claim Information in Security \\ Roles.

View Claim Information
###
[](https://docs.powershelluniversal.com/v3/config/security#example-azure-active-directory)
Example: Azure Active Directory
You can map an Azure Active Directory group to a role by looking up the group Object ID in Azure. For example, within the Ironman Software domain, we have a group called Dashboard Administrators. This group has an object ID of `61849bf2-e44b-4057-b589-6cd1812d7545`.
Within PowerShell Universal, I can assign users of this group to the Administrator group by setting up the claim mapping. The Claim Type will be `groups` and the Claim Value will be `61849bf2-e44b-4057-b589-6cd1812d7545`. Once I have mapped the claim, users of the Dashboard Administrators group will be part of the PowerShell Universal Administrators group. The resulting `roles.ps1` will look like this.
All other roles are disabled.
Copy
New-PSURole -Name Administrator -ClaimType 'groups' -ClaimValue '61849bf2-e44b-4057-b589-6cd1812d7545'
New-PSURole -Name "Operator" -Description "Operators have access to manage and execute scripts, create other entities within PowerShell Universal but cannot manage PowerShell Universal itself." -Policy {} -Disabled
New-PSURole -Name "Reader" -Description "Readers have read-only access to PowerShell Universal. They cannot make changes to any entity within the system." -Policy { } -Disabled
New-PSURole -Name "Execute" -Description "Execute scripts within PowerShell Universal." -Policy { } -Disabled
New-PSURole -Name "User" -Description "Does not have access to the admin console but can be assigned resources like APIs, scripts, dashboards and pages." -Policy { } -Disabled
###
[](https://docs.powershelluniversal.com/v3/config/security#policy-assignment)
Policy Assignment
By default, roles are assigned by policies. Policies are run when the user logs in. You can change the policy scripts by visiting the Security / Roles page. Click the Edit Policy button to configure the Policy script.

Policy scripts will receive a `ClaimsPrincipal` object as a parameter and need to return true or false. Policies that throw errors will be assumed to be false. The `ClaimsPrincipal` object contains the user's identity and the claims that the user has received. These may include group assignments or other features of a user's account.
You can expect an object with this structure.
Copy
public class ClaimsPrincipal
{
public List Claims { get; set; } = new List();
public Identity Identity { get; set; } = new Identity();
}
public class Identity
{
public string Name { get ;set; }
}
public class Claim
{
public string Type { get; set; }
public string Value { get; set; }
public string ValueType { get; set; }
public string Issuer { get; set; }
public Dictionary Properties { get; set; } = new Dictionary();
}
###
[](https://docs.powershelluniversal.com/v3/config/security#role-assignment)
Role Assignment
To assign a role to a user, you can create their identity within Universal and then select the role in the drop down on the Identities page.

By default, identities receive a role through claim mapping or policy.

###
[](https://docs.powershelluniversal.com/v3/config/security#built-in-roles)
Built in Roles
####
[](https://docs.powershelluniversal.com/v3/config/security#administrator)
Administrator
Full access to the entire PowerShell Universal platform and settings.
####
[](https://docs.powershelluniversal.com/v3/config/security#operator)
Operator
Operators have access to add and remove resources such as APIs, Scripts and Dashboards. Operators cannot change settings like environments, roles, or general settings.
####
[](https://docs.powershelluniversal.com/v3/config/security#execute)
Execute
The Execute role grants the ability to run scripts and read access for everything else.
####
[](https://docs.powershelluniversal.com/v3/config/security#reader)
Reader
The Reader role provides read-only access to PowerShell Universal.
###
[](https://docs.powershelluniversal.com/v3/config/security#default-route-per-role)
Default Route per Role
You can change which page the user sees when logging in by setting the `Default Route` property for the role. For example, you may want HR users to go to the Human Resources dashboard while you want IT users to go to the IT Dashboard.
###
[](https://docs.powershelluniversal.com/v3/config/security#users-with-many-groups)
Users with Many Groups
If your users are members of more than about 40 groups you may experience problems logging in. This is due to size limits of the HTTP headers in IIS and Kestrel. The more groups a user is a member of, the more authorization claims they have and the large the header.
You can increase the header limit for Kestrel by using the limits configuration in `appsettings.json` file. You will need to increase the header size. It is a value in bytes and defaults to 32kb.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000"
}
},
"Limits": {
"MaxRequestHeadersTotalSize": 132768
},
"RedirectToHttps": "false"
},
###
[](https://docs.powershelluniversal.com/v3/config/security#iis-authorization)
IIS Authorization
Authorization in IIS works as with any other method but you need to be aware of the request header size limit. You may receive errors when you enable claims that include many groups. They can exceed the header size limit and IIS will return errors. We have found that about 40 Azure Active Directory groups will cause this issue on a default IIS installation.
The error you will receive will either be a 400 error with the request is too long.

If you have HTTPS enabled, you will receive an error about a HTTP2 protocol error.

You can increase the IIS request size by setting the following registry keys. You will need to restart you machine in order for them to take affect.
Copy
HKLM:\System\CurrentControlSet\Services\Http\Parameters
MaxFieldLength: DWORD
HKLM:\System\CurrentControlSet\Services\Http\Parameters
MaxRequestBytes: DWORD
More information can be found on [Microsoft's documentation](https://docs.microsoft.com/en-us/troubleshoot/iis/http-bad-request-response-kerberos#workaround-2-set-maxfieldlength-and-maxrequestbytes-registry-entries)
.
As an alternative to increasing the request size, you can also reduce the number of groups sent. In Azure Active Directory, you can set to just the groups assigned to the application to prevent all groups from being sent.
In Azure go to **App registrations** > (Select the app) > **Token Configuration**, and specify Groups assigned to the application. 
Now go to **Enterprise Application** > (Select the app) > **Users and groups**. Assign the group(s) you are interested in including in the claims. (Note: this can also be used as a security boundary if you set “User Assignment Required” to Yes in the ‘Properties’ section of the app)

[](https://docs.powershelluniversal.com/v3/config/security#app-tokens)
App Tokens
--------------------------------------------------------------------------------------
App Tokens can be assigned to services that cannot login interactively. You can grant a new app token to your account by clicking the Grant App Token button within the Security / App Tokens tab.
The token will have a expiration of one year and have the valid roles for your account. To copy the App Token to your account, click the Copy action. To revoke an App Token, click the Revoke action.
You can use App Tokens with the Universal cmdlets or by using web requests directly using Bearer authorization.

[](https://docs.powershelluniversal.com/v3/config/security#environment)
Environment
----------------------------------------------------------------------------------------
By default, the forms authentication and policy assignment scripts run within the PowerShell Universal process. You can optionally configure an external [Environment](https://docs.powershelluniversal.com/v3/config/environments)
to run your authentication and authorization scripts. When you configure a security environment, an external PowerShell process will be started and configured use your Environment's settings.
To adjust the environment used by the security process, set the `-SecurityEnvironment` in `settings.ps1`.
Copy
Set-PSUSetting -SecurityEnvironment '5.1'
[](https://docs.powershelluniversal.com/v3/config/security#example-forms-authentication-with-active-directory)
Example: Forms Authentication with Active Directory
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
The following example shows performing a simple "LDAP BIND" in order to validate a users Active Directory Credentials. If a user attempting to access PowerShell Universal is not the Default Admin User they will have to successfully authenticate their credentials with Active Directory via a simple LDAP bind. This can be combined with a AD Group Member check in the Admin, Operator, and Reader role policies to effectively use Active Directory Authentication AND Active Directory Group membership to provide Role Based Access to PowerShell Universal.
Copy
param(
[PSCredential]$Credential
)
#
# You can call whatever cmdlets you like to conduct authentication here.
# Just make sure to return the $Result with the Success property set to $true
#
$Result = [Security.AuthenticationResult]::new()
if ($Credential.UserName -eq 'Admin')
{
#Maintain the out of box admin user
$Result.UserName = 'Default Admin'
$Result.Success = $true
}
else
{
# Get current domain using logged-on user's credentials - this validates their credential
$CurrentDomain = "LDAP://DC=mydemodomain,DC=com" # Insert Your Domain Here
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,($Credential.UserName),$Credential.GetNetworkCredential().password)
if ($domain.name -eq $null)
{
"Authentication failed for $($Credential.UserName)!" | Out-File "C:\test\adlogin.txt"
write-host "Authentication failed - please verify your username and password."
$Result.UserName = ($Credential.UserName)
$Result.Success = $false
}
else
{
write-host "Successfully authenticated with domain $($domain.name)"
"Authentication success for $($Credential.UserName)!" | Out-File "C:\test\adlogin.txt"
$Result.UserName = ($Credential.UserName)
$Result.Success = $true
}
}
$Result
[](https://docs.powershelluniversal.com/v3/config/security#example-policy-based-on-active-directory-group-membership-windows-authentication)
Example: Policy based on Active Directory Group Membership (Windows Authentication)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This example requires an authentication method that will provide group information during the authentication process. Methods like Windows authentication and WS-Federation can provide this information. Forms authentication will not work with this type of policy.
This example takes advantage of the claims that are provided during authentication. You can check to see if the user has a groupsid (group membership) by using claim mappings. Map the groupid claim type to the value you want to assign the role to.
Copy
$Parameters = @{
Name = "Administrators"
ClaimType = 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid'
ClaimValue = 'S-1-5-21-22222222-111111-3333333-153'
}
New-PSURole @Parameters
[](https://docs.powershelluniversal.com/v3/config/security#example-policy-based-on-active-directory-group-membership)
Example: Policy based on Active Directory Group Membership
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In this example we will configure out Administrator Policy Script to use LDAP to retrieve the membership of an Active Directory Group. Here we have created a group called "PowerShell Universal Admins" where members of the group should be granted Administrator Access in PowerShell Universal. Here we are doing a simple samaccountname check for the user to ensure they are a member of the group. For more robust environments a SID/DN/ObjectGUID check would be more appropriate.

Copy
param(
$User
)
$UserName = ($User.Identity.Name)
$UserName = $UserName.Substring($UserName.IndexOf('\')+1,($UserName.Length -($UserName.IndexOf('\')+1)))
$IsMember = $false;
# Perform LDAP Group Member Lookup
$Searcher = New-Object DirectoryServices.DirectorySearcher
$Searcher.SearchRoot = 'LDAP://CN=Users,DC=berg,DC=com' # INSERT ROOT LDAP HERE
$Searcher.Filter = "(&(objectCategory=person)(memberOf=CN=PowerShell Universal Admins,OU=Information Technology,DC=berg,DC=com))" #GROUP INSERT DN TO CHECK HERE
$Users = $Searcher.FindAll()
$Users | ForEach-Object{
If($_.Properties.samaccountname -eq $UserName)
{
$IsMember = $true;
"$UserName is a member of admin group!" | Out-File "C:\test\adgroup.txt"
}
else {
"$UserName is NOT member of admin group!" | Out-File "C:\test\adgroup.txt"
}
}
return $IsMember
[](https://docs.powershelluniversal.com/v3/config/security#example-group-membership-based-on-azure-active-directory)
Example: Group membership based on Azure Active Directory
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This example takes advantage of [OpenID Connect and Azure Active Directory](https://docs.powershelluniversal.com/v3/config/security/openid-connect#configuring-azuread)
.
Once you have configured PowerShell Universal and Azure Active Directory, you can configure role scripts to verify whether users are members of groups found in Azure AD. You can take advantage of claims mappings to map from the Azure AD Group ID to a PowerShell Universal role.
First, ensure that you have group membership claims enabled in the manifest for your application registration. This will include all group membership, so it is accessible in PowerShell Universal.

Copy
"groupMembershipClaims": "All",
Once configured, you can update your role script to check for a group membership. First make note of the object ID of the group you are looking to check within Azure AD.

Next, within your `roles.ps1` script, you can validate a user has a particular role by using claims mapping.
Copy
New-PSURole -Name 'Administrators' -ClaimType 'groups' -ClaimValue '4acabc67-56cc-4590-9de6-164f3c4faf10'
As users login, their group membership will be validated against their claims and a role will be assigned.
[PreviousApp Settings](https://docs.powershelluniversal.com/v3/config/settings)
[NextBest Practices](https://docs.powershelluniversal.com/v3/config/security/best-practices)
Last updated 2 years ago
---
# Access Controls | PowerShell Universal
Access controls requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#about)
About
--------------------------------------------------------------------------------------------
Access controls allow you to define who has access to particular resources inside PowerShell Universal. Currently, access controls only apply to scripts.
There are three types of access controls.
* Global
* Resource
* Tag
PowerShell Universal uses a least-privileged model and users have no access without an access control that applies to their role.
Access controls are defined within the `accessControls.ps1` file within your PowerShell Universal configuration repository.
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#admin-console)
Admin Console
------------------------------------------------------------------------------------------------------------
You can define access controls in the admin console under Security \\ Access Controls.

[](https://docs.powershelluniversal.com/v3/config/security/access-controls#access-control-types)
Access Control Types
--------------------------------------------------------------------------------------------------------------------------
There are five different privileges that can be granted to users. These values are available on the `[PowerShellUniversal.AccessControlType]` enumeration.
* View (1)
* Edit (2)
* Create (4)
* Delete (8)
* Execute (16)
You can define multiple access control types on a single access control by using a binary or operator.
For example, this creates a privilege for both Create and View.
Copy
$Type = ([PowerShellUniversal.AccessControlType]::Create -bor [PowerShellUniversal.AccessControlType]::View)
You can also use the integer values for a more terse syntax. This creates the same Create and View privileges.
Copy
$Type = 1 -bor 4
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#global-access-controls)
Global Access Controls
------------------------------------------------------------------------------------------------------------------------------
Global access controls allow you to define an access for a role for all resources of the chosen type.
For example, to allow any user with the `ScriptBuilder` role to create a script, you can define an access control using the following command. You'll also want to grant the View privilege so that the user can also view scripts.
Copy
$Type = ([PowerShellUniversal.AccessControlType]::Create -bor [PowerShellUniversal.AccessControlType]::View)
New-PSUAccessControl -Role 'ScriptBuilder' -ObjectType 'Script' -Type $Type
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#resource-access-controls)
Resource Access Controls
----------------------------------------------------------------------------------------------------------------------------------
Resource access controls allow you to specify access controls directly on a resource.
This example defines the execute privilege on the `OnBoarding.ps1` script to the `ScriptRunner` role.
Copy
$Type = ([PowerShellUniversal.AccessControlType]::Execute -bor [PowerShellUniversal.AccessControlType]::View)
New-PSUAccessControl -Role 'ScriptRunner' -ObjectId 'OnBoarding.ps1' -ObjectType 'Script' -Type $Type
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#tag-access-controls)
Tag Access Controls
------------------------------------------------------------------------------------------------------------------------
Tag access controls allow you to specify an access control based on a tag. All tagged resources will have this access control defined. This allows you to group resources and apply access controls to the group.
The following example provides the edit privilege to the `ScriptEditor` role and the `HR` tag.
Copy
$Type = ([PowerShellUniversal.AccessControlType]::Edit -bor [PowerShellUniversal.AccessControlType]::View)
New-PSUAccessControl -Role 'ScriptEditor' -Tag 'HR' -Type $Type
[](https://docs.powershelluniversal.com/v3/config/security/access-controls#api)
API
----------------------------------------------------------------------------------------
* [New-PSUAccessControl](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUAccessControl.txt)
[PreviousBest Practices](https://docs.powershelluniversal.com/v3/config/security/best-practices)
[NextApp Tokens](https://docs.powershelluniversal.com/v3/config/security/app-tokens)
Last updated 2 years ago
---
# Best Practices | PowerShell Universal
This document provides security best practices and hardening options for PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#authentication-and-authorization)
Authentication and Authorization
-------------------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#app-token-enhanced-security)
App Token Enhanced Security
We recommend enabling app token enhanced security. App tokens generated within PowerShell Universal will be hashed and stored in the database rather than persisted in plaintext. As app tokens are used, they are hashed and compared against the hashed values. Tokens are hashed with SHA256.
Copy
Set-PSUSetting -EnhancedAppTokenSecurity
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#app-token-signing-key)
App Token Signing Key
We recommend adjusting the default app token signing key. This setting is present in `appsettings.json`. Changing the signing key will invalidate existing app tokens.
Copy
"Jwt": {
"SigningKey": "PleaseUseYourOwnSigningKeyHere"
}
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#authentication-configuration)
Authentication Configuration
Consider using `authentication.ps1` for configuring authentication methods that require secrets. When using authenticaiton.ps1, you can use secret variables and, in turn, secret vaults to load these values when starting up.
Copy
Set-PSUAuthenticationMethod -Type OIDC -ClientSecret $Secret:ClientSecret #...
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#default-admin-account)
Default Admin Account
We recommend changing the default admin account password. By default, this password is stored within the PowerShell Universal database. You will receive a warning on the login page if the admin password is the default.
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#default-authorization)
Default Authorization
Ensure that role scripts are either disabled or do not simply return true. Returning true from a role script will grant any user access to that role. With authentication methods like Windows Authentication, any user that is a capable of logging into the domain will have acecss to PowerShell Universal if the roles are not properly configured.
Copy
New-PSURole -Name 'Administrator' -Policy {
# Grants administrator to everyone
$true
}
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#least-privilged-access)
Least Privilged Access
Consider using a least privileged access model for roles within PowerShell Universal. Much of PowerShell Universal can be used with the execute or operator role. It isn't necessary to assign the administrator role to all users.
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#limit-identities)
Limit Identities
It may be desirable to limit identities to ones created within PowerShell Universal. This will prevent users from accessing PowerShell Universal if they have not been added on the identities page.
Copy
Set-PSUSetting -LimitIdentities
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#security-triggers)
Security Triggers
Consider creating triggers that will notify you of potential issues with authentication and authorization. The following triggers may be useful:
* Revoked App Token Usage
* User Login
* New User Login
* API Authentication Failed
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#automation)
Automation
-----------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#experimental-feature-run-id)
Experimental Feature: Run ID
By default, job runs are stored as sequential big integers. This means that bad actors can guess job runs by incrementing a number from the current job ID. As of PowerShell Universal 3.8, an experimental feature can be enabled to only allow access of jobs by run ID. Run IDs are globally unique identifiers and cannot be guessed.
Copy
Set-PSUSetting -ExperimentalFeature @("JobRunId")
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#dashboards)
Dashboards
-----------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#avoid-long-running-event-handlers)
Avoid Long Running Event Handlers
Avoid running long running event handlers directly within dashboards. This can be an avenue for a denial-of-service attack. Consider running long running processes as jobs to take advantage of queuing.
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#credentials-and-secrets)
Credentials and Secrets
-------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#secret-encryption-keys)
Secret Encryption Keys
If using the Database or PSUSecretStore vaults, we recommend changing the default passwords. Both systems use a symmetric encryption method for storing secrets. The Database secret stored encrypts values using the specified key into the database persistence layer. The PSUSecretStore creates a local file in the service account's profile with the secret values.
Copy
"Secrets": {
"SecretStore": {
"Password": "PSUSecretStore"
},
"Database": {
"EncryptionKey": "=b0ywQA@VOSdr&R7an5g&XK6NVO%s4Tf"
}
},
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#alternate-secret-storage)
Alternate Secret Storage
PowerShell Universal integrates with the Microsoft Secret Management module. This module provides the ability to interact with an extensible set of vaults. Many vault implementations can be found on the PowerShell Gallery.
We recommend using a secure vault, such as Cyberark or Azure KeyVault, to store secrets in an enterprise ready fashion.
Follow the documentation for [secret variable vaults](https://docs.powershelluniversal.com/v3/platform/variables)
to learn how to configure an alternate vault.
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#service-configuration)
Service Configuration
---------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#https)
HTTPS
Enabling HTTPS for the web server is highly recommended. If possible, we recommend storing a certificate within the Certificate Manager to avoid having to include a clear-text password for a local PFX file. Certificates are configured within `appsettings.json`.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:443",
"Certificate": {
"Subject": "windows-server.ironman.local",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
}
}
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#rate-limiting)
Rate Limiting
Consider configuring rate limiting to avoid denial of service attacks. PowerShell Universal executes PowerShell in many different ways. PowerShell can be slower to execute than compiled languages so rate limiting can be very beneficial, especially for PowerShell Universal instances accessible externally.
Learn more about [rate limiting here](https://docs.powershelluniversal.com/v3/config/security/best-practices#rate-limiting)
.
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#cors-hosts)
CORS Hosts
Consider configuring the CORS hosts setting in `appsettings.json` . You can learn more about the benefits of the [CORS hosts setting here](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
.
Copy
"CorsHosts": "",
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#service-accounts)
Service Accounts
Consider utilizing service accounts with a least-privileged access model. It's possible to configure the PowerShell Universal service to run as a service account that does not have access to certain resources and utilize alternate accounts when running scripts that need to access resources.
Learn more about [service accounts here](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account)
.
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#persistence)
Persistence
-------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#sql)
SQL
We recommend the use of SQL server with integrated security or Azure managed identities. This avoids having to store passwords locally.
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#litedb)
LiteDB
By default, the LiteDB database is not password protected. Actors that can physically access the PowerShell Universal server can copy the database file from disk and open it elsewhere. Consider providing an encryption key to the [LiteDB connection string to enable encryption](https://www.litedb.org/docs/connection-string/)
.
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#scripting)
Scripting
---------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#powershell-security)
PowerShell Security
PowerShell Universal exposes PowerShell scripts remotely in different ways. It's important to follow strict PowerShell script security best practices to guard against potentional attacks such as script injection.
Some recommendations include:
* Use of param blocks to validate input
* Avoiding Invoke-Expression to help prevent injection
* Code and security review processes on scripts
Learn more about [scripting security here](https://learn.microsoft.com/en-us/mem/configmgr/apps/deploy-use/learn-script-security)
.
###
[](https://docs.powershelluniversal.com/v3/config/security/best-practices#one-way-git-sync)
One-Way Git Sync
Consider using one-way git sync for changes in your production environment. This ensures that PowerShell Universal is read-only, and only validated changes will be picked up in production environments.
[PreviousSecurity](https://docs.powershelluniversal.com/v3/config/security)
[NextAccess Controls](https://docs.powershelluniversal.com/v3/config/security/access-controls)
Last updated 2 years ago
---
# App Tokens | PowerShell Universal
PowerShell Universal app tokens can be used with both [custom API endpoints](https://docs.powershelluniversal.com/v3/config/api)
and the [management API](https://docs.powershelluniversal.com/v3/config/management-api)
. The management API uses the standard Administrator, Operator and Reader roles. The custom API app tokens can utilize custom roles as well as the built in ones.
You can grant App Tokens to using the Admin Console or you can use the Management API directly.
[](https://docs.powershelluniversal.com/v3/config/security/app-tokens#admin-console)
Admin Console
-------------------------------------------------------------------------------------------------------
To grant a token in the Admin Console, navigate to Security \\ Tokens. Click the Add New App Token button to grant an App Token.

When you click Grant App Token, you will be provided with a dialog that allows you to specify the Identity, Role and expiration time of the token.

App Token options.
[](https://docs.powershelluniversal.com/v3/config/security/app-tokens#management-api)
Management API
---------------------------------------------------------------------------------------------------------
You can also grant app tokens to users from the management API. To grant an App Token programmatically using the API, you can do the following.
Copy
PS C:\Users\adamr> Invoke-RestMethod http://localhost:5000/api/v1/signin -Method POST -Body (@{ username = 'admin'; password = 'test' } | ConvertTo-Json) -SessionVariable Session -ContentType 'application/json'
PS C:\Users\adamr> Invoke-RestMethod http://localhost:5000/api/v1/apptoken/grant -WebSession $Session
id : 3
token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2Ns
YWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoI
joiYjJlOGM4MDktMjE0NS00NjhhLWI4NTEtYjU0MjVhZDgzOTQ2Iiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2
hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6WyJBZG1pbmlzdHJhdG9yIiwiT3BlcmF0b3I
iLCJSZWFkZXIiXSwibmJmIjoxNTkzMTkyMjY1LCJleHAiOjE2MjQ3MjgyNjUsImlzcyI6Iklyb25tYW5Tb2Z0d2FyZSIsImF1ZCI6IlBv
d2VyU2hlbGxVbml2ZXJzYWwifQ.hnKyXe8C4kbrmkeeUFr-LUDjVr-xP7fRWwgClcrnxfc
identity : @{id=3; name=admin; source=0; role=}
revoked : False
role : Administrator, Operator, Reader
created : 26/06/2020 17:24:25
expiration : 26/06/2021 17:24:25
revokedDate : 01/01/0001 00:00:00
Administrators can grant app tokens to any user by specifying the user's identity ID. In order to grant an app token to an identity via the REST API, the user needs to have a defined role. The user is defined with the Operator role and thus their App Token will be granted access based on that role.

Copy
PS C:\Users\adamr> Invoke-RestMethod http://localhost:5000/api/v1/apptoken/grant/2 -WebSession $Session
id : 4
token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2Ns
YWltcy9uYW1lIjoiYWRhbUBpcm9ubWFuc29mdHdhcmUub25taWNyb3NvZnQuY29tIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd
3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvaGFzaCI6IjhhYWM2NWFmLTA2NmItNDYwNy1hMGJjLTNlYTM2ZDY2YjJmMSIsInN1YiI6Il
Bvd2VyU2hlbGxVbml2ZXJzYWwiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3J
vbGUiOiJPcGVyYXRvciIsIm5iZiI6MTU5MzE5MjM2MCwiZXhwIjoxNjI0NzI4MzYwLCJpc3MiOiJJcm9ubWFuU29mdHdhcmUiLCJhdWQi
OiJQb3dlclNoZWxsVW5pdmVyc2FsIn0.9VYiRFOojFyZMH0E5rwdfFcOkoasXFrrWJDNtYk0PIw
identity : @{id=2; [email protected]; source=0; role=}
revoked : False
role : Operator
created : 26/06/2020 17:26:00
expiration : 26/06/2021 17:26:00
revokedDate : 01/01/0001 00:00:00
[](https://docs.powershelluniversal.com/v3/config/security/app-tokens#migrating-app-tokens)
Migrating App Tokens
---------------------------------------------------------------------------------------------------------------------
You can migrate app tokens between systems by using the management API. This is helpful when developing for high availability scenarios.
The following is an example of the POST that is required to create an existing app token in any PSU instance. Note that the signing key must be the same between the instances. You need a valid app token in the target system to create the migrated tokens.
Copy
Invoke-RestMethod http://localhost:5000/api/v1/apptoken -Method POST -Body (@{
Token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoIjoiMDhiYTFlMTktMjgyZi00YTRjLWIxZGUtNTY0Zjk3NWU2ODEwIiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InBvbGljeSIsIm5iZiI6MTYzMzEwNjkzMywiZXhwIjoxNjQwODg2NDgwLCJpc3MiOiJJcm9ubWFuU29mdHdhcmUiLCJhdWQiOiJQb3dlclNoZWxsVW5pdmVyc2FsIn0.GHjJI3kMpcAY1pvOGLWOdPqC2-IPo0-4lJfHZwStmOk'
Identity = @{
Name = 'Admin'
}
Role = 'Administrator'
Expiration = (Get-Date).AddMonths(6)
} | ConvertTo-Json) -Headers @{
"Content-Type" = "application/json";
"Authorization" = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoIjoiMjVjMzFlZTAtMGM4Mi00NzBiLWJkZGYtOGFmOTgxZGI2ZDdmIiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYmYiOjE2MzM2NDY5OTgsImV4cCI6MTYzNjIzODk0MCwiaXNzIjoiSXJvbm1hblNvZnR3YXJlIiwiYXVkIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCJ9.jw2VCvtpOWpgnpIUlO8sTdK9Z5RMoWLmvYn0MDmzkNM"
}
[](https://docs.powershelluniversal.com/v3/config/security/app-tokens#enhanced-app-token-security)
Enhanced App Token Security
-----------------------------------------------------------------------------------------------------------------------------------
When enhanced app token security is enabled, token values are only accessible once they are created. They are hashed and the hash value is stored in the database rather than the token. You will use the token the same way as any other token.
[PreviousAccess Controls](https://docs.powershelluniversal.com/v3/config/security/access-controls)
[NextClient Certificate](https://docs.powershelluniversal.com/v3/config/security/client-certificate)
Last updated 2 years ago
---
# Client Certificate | PowerShell Universal
Client certificate authentication ensures that client machines hold a particular certificate when connecting to PowerShell Universal. The certificate check is handled during the HTTP negotiation so it affects the entire webserver and cannot be configured per route.
For detailed information about client certificate authentication in ASP.NET Core 5.0, you can visit the [Microsoft documentation here](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-5.0)
.
[](https://docs.powershelluniversal.com/v3/config/security/client-certificate#enable-client-certificate-authentication)
Enable Client Certificate Authentication
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
You will need to enable HTTPS hosting and turn on client certificate authentication. First, ensure that you have an HTTP certificate selected and you have set the `ClientCertificateMode` to `RequireCertificate`. These settings can be set within the appsettings.json file.
Copy
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:5000",
"ClientCertificateMode": "RequireCertificate",
"Certificate": {
"Subject": "localhost",
"Store": "My",
"Location": "LocalMachine",
"AllowInvalid": "true"
}
}
},
"RedirectToHttps": "false"
},
Next, you will need to enable client certificate authentication.
Copy
"ClientCertificate": {
"Enabled": "true"
},
[](https://docs.powershelluniversal.com/v3/config/security/client-certificate#authorization)
Authorization
---------------------------------------------------------------------------------------------------------------
You can use the roles.ps1 file to evaluate the certificate provided by the client. This can be used to determine which roles the user will receive when connecting to PSU.
To evaluate the properties that are available during authorization, you can serialize the `$user` variable provided to the role policy functions.
Copy
param($User)
$User | ConvertTo-Json | Out-File .\user.txt
$true
You will receive information about the certificate within the user object similar to below.
Copy
{
"Claims": [\
{\
"Type": "issuer",\
"Value": "CN=Cert1, OU=Cert2, O=Org, L=Scottsdale, S=Arizona, C=US",\
"ValueType": "http://www.w3.org/2001/XMLSchema#string",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
},\
{\
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint",\
"Value": "8D2212B6EA170A33055A5",\
"ValueType": "http://www.w3.org/2001/XMLSchema#base64Binary",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
},\
{\
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname",\
"Value": "CN=*.cert.com, OU=Domain Control Validated",\
"ValueType": "http://www.w3.org/2001/XMLSchema#string",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
},\
{\
"Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber",\
"Value": "009D21369",\
"ValueType": "http://www.w3.org/2001/XMLSchema#string",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
},\
{\
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns",\
"Value": "*.cert.com",\
"ValueType": "http://www.w3.org/2001/XMLSchema#string",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
},\
{\
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",\
"Value": "*.cert.com",\
"ValueType": "http://www.w3.org/2001/XMLSchema#string",\
"Issuer": "LOCAL AUTHORITY",\
"Properties": "System.Collections.Generic.Dictionary`2[System.String,System.String]"\
}\
],
"Identity": {
"Name": "*.cert.com"
}
}
You can evaluate the the claims using the `HasClaim` method. The following is an example of checking the thumbprint of the certificate.
Copy
param($User)
$User.HasClaim('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint', '8D2212B6EA170A33055A5')
[PreviousApp Tokens](https://docs.powershelluniversal.com/v3/config/security/app-tokens)
[NextOpenID Connect](https://docs.powershelluniversal.com/v3/config/security/openid-connect)
Last updated 2 years ago
---
# OpenID Connect | PowerShell Universal
OpenID Connect requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
OpenID Connect is an authentication layer on top of OAuth 2.0, an authorization framework. It is supported by many vendors and provides the ability to authenticate against systems like AzureAD.
This document will outline the steps necessary to configure AzureAD OpenID Connect and use it with Universal.
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#configuring-azure-active-directory)
Configuring Azure Active Directory
-----------------------------------------------------------------------------------------------------------------------------------------------------
Within the Azure Portal, navigate to your Azure Active Directory blade. Next, click the App registrations node and then click New registration.

In the New registration page, enter the name of your application and the reply URL. The URL can be configured in the `appsettings.json` for Universal but the default value is shown below.

Next, you'll need to configure a client secret. You can click the Certificates & secrets menu and then click New client secret. This secret will need to go into the `appsettings.json` file.

Now, you will need to take note of your Application (client) ID GUID. This will be used in the `appsettings.json` file.

Finally, you will have to click the Endpoints button to open the Endpoints drawer. This contains a list of the endpoints. Make note of the OAuth 2.0 authorization endpoint URL. You will need this for the `appsettings.json`.
Note that you will not input the entire endpoint URL. You will need to include the portion of the URL through the GUID but without the path after oauth2 in the Authority setting below (e.g. [https://login.microsoftonline.com/fffffff-4b76-4470-a736-8481d7a2ed87](https://login.microsoftonline.com/fffffff-4b76-4470-a736-8481d7a2ed87)
).

###
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#configuring-universal-for-azure-active-directory)
Configuring Universal for Azure Active Directory
####
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#use-appsettings.json)
Use Appsettings.json
Read more about `appsettings.json` on our [Settings](https://docs.powershelluniversal.com/v3/config/settings)
page.
Now that we have completed the configuration of an AzureAD App Registration, we can update the `appsettings.json` file with the appropriate settings. For my application, it would look something like this.
Copy
"OIDC": {
"Enabled": "true",
"CallbackPath": "/auth/signin-oidc",
"ClientID": "6f006906-643a-40fe-af00-9060ceffffff",
"ClientSecret": "xxxxxxxxxxxxxxxxxx",
"Resource": "",
"Authority": "https://login.microsoftonline.com/fffffff-4b76-4470-a736-8481d7a2ed87",
"ResponseType": "code",
"SaveTokens": "false",
"GetUserInfo": false
},
If you are using Chrome, you will also need to enable HTTPS. You will see a 500 error without HTTPS enabled.
####
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#use-authentication.ps1)
Use Authentication.ps1
Available in PowerShell Universal 2.5 or later.
You can use the admin console to configure OpenID Connect. We recommend this method as you will not need to restart the PowerShell Universal service after configuring OIDC.
To add a new authentication method, navigate to Security \\ Authentication and add the OpenID Connect provider.

Once the provider has been added, you can click the details button to enter the settings you'll need to authenticate against your OIDC provider. After setting the OIDC options, set the provider to enabled and log out. When visiting the `/admin` page, you'll be prompted for OIDC login.

###
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#delegated-access-tokens)
Delegated Access Tokens
You can use access tokens generated by an OIDC login for other services the user may have access to. Within your OIDC provider, like Azure AD, you can grant additional permissions to the token.

You will also have to enable access tokens within the authentication flow so that the token provides the necessary resource access.

Finally, within your PSU `appsettings.json` file, you will need to ensure that `SaveTokens` is enabled, the resource type includes token and the resource you wish to access is included in the Resource setting. The URL that you specify in the resource should be listed in within the provider.
The below example adds a resource for Microsoft O365.
Copy
"OIDC": {
"Enabled": "true",
"CallbackPath": "/auth/signin-oidc",
"ClientID": "",
"ClientSecret": "",
"Resource": "https://manage.office.com/",
"Authority": "https://login.microsoftonline.com/tenant",
"ResponseType": "id_token token",
"SaveTokens": "true",
"UseTokenLifetime": true
},
Within your dashboard, you will now have access to an `$AccessToken` and `$IdToken` variable that you can use with cmdlets that require authorization.
For example, the `Connect-AzureAd` cmdlet accepts an access token.
Copy
Connect-AzureAD
[-AzureEnvironmentName ]
[-TenantId ]
-AadAccessToken
[-MsAccessToken ]
-AccountId
[-LogLevel ]
[-LogFilePath ]
[-InformationAction ]
[-InformationVariable ]
[-WhatIf]
[-Confirm]
[]
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#configuring-okta)
Configuring Okta
-----------------------------------------------------------------------------------------------------------------
Okta supports OpenID Connect. You can configure an application to allow authentication against PowerShell Universal instances.
Within your Okta admin console, expand Applications and click Applications. Then click Create App Integration.

Select OIDC and Web Application.

Name your application and define the Sign-In redirect URL used to call your PowerShell Universal server. You will need to specify this callback URL within your PowerShell Universal configuration.

Once you've created your application, take note of your Client ID and Client Secret. You will specify these within your PowerShell Universal configuration.

Within the Sign On tab, specify the group claims filter to use for providing claims to PowerShell Universal. These claims can be used to assign roles based on group membership. The following filter returns all claims.

Once you have your Application configured, you can configure PowerShell Universal.
###
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#configurating-universal-for-okta)
Configurating Universal for Okta
Once you have defined your Okta application, you can set your `appsettings.json` file to use the provider for logins. Below is an example of the section required for Okta to function. Take note of the scope functionality as it is required for retrieving group membership.
Copy
"OIDC": {
"Enabled": "true",
"CallbackPath": "/authorization-code/callback",
"ClientID": "6f006906-643a-40fe-af00-9060cea5d6ef",
"ClientSecret": "M~.rE56.md_MOpB2I5kwj_voFuX-i891N0",
"Resource": "",
"Authority": "https://poshtools.okta.com",
"ResponseType": "code",
"SaveTokens": "true",
"CorrelationCookieSameSite": "",
"UseTokenLifetime": true,
"Scope": "openid profile groups",
"GetUserInfo": true
},
###
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#role-based-access)
Role-Based Access
In order to look up group membership for Okta, you will need to use the `$UserInfo` variable that is available within `roles.ps1`. This variable provides additional information about the user logging in.
The groups property will contain a list of groups the user is a member of. You can validate membership by checking whether the list contains the desired group.
Copy
param($User)
$UserInfo.groups -contains 'Administrators'
###
[](https://docs.powershelluniversal.com/v3/config/security/openid-connect#delegated-access-tokens-1)
Delegated Access Tokens
Access tokens are available for users within their scripts. You can use access tokens in jobs started by users and dashboards.
For example, you could return the current user's information by using the access token provided by Okta.
Copy
Invoke-RestMethod https://poshtools.okta.com/oauth2/v1/userinfo -Headers @{
Authorization = "Bearer $AccessToken"
}
[PreviousClient Certificate](https://docs.powershelluniversal.com/v3/config/security/client-certificate)
[NextPowerShell Protect](https://docs.powershelluniversal.com/v3/config/security/powershell-protect)
Last updated 2 years ago
---
# PowerShell Protect | PowerShell Universal
[PowerShell Protect](https://docs.poshtools.com/powershell-pro-tools-documentation/powershell-protect)
is a feature of PowerShell Pro Tools. It allows you to audit and block PowerShell scripts and PowerShell command lines that are executed on your machine. You can deploy the client piece and then configure it using PowerShell Universal. PowerShell Universal can also be used as a collection mechanism for events generated by PowerShell Protect. Additionally, PowerShell Universal can trigger scripts when certain rules are triggered.
You can access PowerShell Protect tooling by navigating to Security \\ Protect.

[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#configuring-powershell-protect)
Configuring PowerShell Protect
-------------------------------------------------------------------------------------------------------------------------------------------------
PowerShell Protect is configured via XML. PowerShell Universal can be used to create this XML. Navigate to the PowerShell Protect page and then click Configurations. Click Create New Configuration and name the configuration you are creating.

###
[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#default-rules)
Default Rules
Default rules are configured that will block certain behaviors without additional configuration. You can choose to disable any rules you may not desire to enforce.

###
[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#actions)
Actions
Actions are the result of custom rules triggering based on scripts being run. You can take actions such as blocking the script, sending the event to the event log or sending the event to PowerShell Universal.

Depending on the action selected, you will need to include additional settings. For example, to integrate with PowerShell Universal, you will need to define the HTTP address of the PSU server and an app token used to authenticate against PSU.

###
[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#custom-rules)
Custom Rules
Custom rules can be defined to match features of a script being run. For example, you can match the user, script content, variables and domain being used to run a script. If the custom rule matches, you can then execute one or more rules that you have defined.

###
[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#license)
License
PowerShell Protect requires a PowerShell Pro Tools license for each user that will have the client installed. You can include the license information on the license tab. It will be included as part of the configuration file.

[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#installing-a-powershell-protect-config)
Installing a PowerShell Protect Config
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Once you have completed your configuration, you can navigate back to the Configurations page and download the XML.

You can learn how to install PowerShell Protect configurations [here](https://docs.poshtools.com/powershell-pro-tools-documentation/powershell-protect/configuration)
.
[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#events)
Events
-------------------------------------------------------------------------------------------------
When you configure a rule to use the Universal action, events will be populated within the Events tab of PowerShell Universal.

[](https://docs.powershelluniversal.com/v3/config/security/powershell-protect#triggers)
Triggers
-----------------------------------------------------------------------------------------------------
When you configure a rule to use the Universal action, events can also trigger scripts. From the Automation \\ Triggers page, create a new trigger and set the Event to PowerShell Protect Event. Then, you can choose to filter down which rule causes the trigger to fire.

The `$ProtectEvent` parameter will be passed to your script. This object contains the following properties.
Name
Type
Description
Rule
String
The name of the rule that trigger this script.
Script
String
The content of the script executed.
ContentPath
String
The script path. If run from the command line, this will be null.
ApplicationName
String
An application name identifier. This may include the application version.
UserName
String
The user that ran the script.
ComputerName
String
The computer name of where the script ran.
Administrator
Boolean
Whether or not the user had admin access while running the script.
DomainName
String
The domain name of where the script was run.
Timestamp
DateTime
When the script was run.
[PreviousOpenID Connect](https://docs.powershelluniversal.com/v3/config/security/openid-connect)
[NextSAML2](https://docs.powershelluniversal.com/v3/config/security/saml2)
Last updated 3 years ago
---
# SAML2 | PowerShell Universal
SAML2 requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
PowerShell Universal can be configured to integrate with a SAML2 identity provider. This documentation provides the details for configuring PSU with such a system.
[](https://docs.powershelluniversal.com/v3/config/security/saml2#identity-provider-settings)
Identity Provider Settings
----------------------------------------------------------------------------------------------------------------------------
You will need to configure your identity provider for the PowerShell Universal application. You will need to setup an acceptable entity ID and map attributes. PowerShell Universal requires that the name attribute is mapped. The attribute name needs to be the following.
Copy
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
You should map this to the user identity you wish to be used within PowerShell Universal.
Additional attributes can be mapped and will be available during [role evaluation](https://docs.powershelluniversal.com/v3/config/security#authorization)
. You will find an example of configuring Shibboleth below.
[](https://docs.powershelluniversal.com/v3/config/security/saml2#entity-id-settings)
Entity ID Settings
------------------------------------------------------------------------------------------------------------
[HTTPS](https://docs.powershelluniversal.com/v3/config/hosting#configuring-https)
is required for SAML2 authentication.
There are several basic settings you can configure in the PowerShell Universal admin console. To add SAML2 support, click Security \\ Authentication. In the top right corner, you can select SAML2 from the drop down.

Once the SAML2 integration has been added, you can configure the basic settings for communicating with your identity provider. You will need at least the Entity ID and Identity Provider Entity ID configured.
Typically, these entity IDs are URLs configured within your identity provider.

Entity ID Settings
The service certificate is used for signing requests. It is not required. This can either be a path local to the PSU service or the distinguished name of a certificate installed in the Personal Computer Certificate store.
[](https://docs.powershelluniversal.com/v3/config/security/saml2#additional-settings)
Additional Settings
--------------------------------------------------------------------------------------------------------------
In addition to the settings available within the admin console, you can also set the following within the `authentication.ps1` config file.
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#servicecertificatepassword)
ServiceCertificatePassword
If you are using a file path for your certificate and it requires a password, you can specify it via the `-ServiceCertificatePassword` of `Set-PSUAuthenticationMethod`. The value of this parameter is a `SecureString`. You can take advantage of the SecretManagement module to load secrets.
Copy
Set-PSUAuthenticationMethod `
-Type "Saml2" `
-EntityId "http://psu.ironman.local/sp" `
-IdentityProviderEntityId 'https://ironman.local/idp' `
-MetadataAddress 'https://idp.ironman.local/idp/shibboleth' `
-CallbackPath "https://localhost:5000/" `
-ServiceCertificate cert.pfx `
-ServiceCertificatePassword (Get-Secret -Name 'certPassword')
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#configure)
Configure
The `-Configure` parameter is a script block that can be used to set additional settings not exposed by the `Set-PSUAuthenticationMethod`. The script block will be called when the provider is configured and will receive a single parameter that contains an object with the options for the SAML2 authentication.
The object is of the type [Saml2Options](https://github.com/Sustainsys/Saml2/blob/develop/Sustainsys.Saml2.AspNetCore2/Saml2Options.cs)
. The sub object of SPOptions can be found [here](https://github.com/Sustainsys/Saml2/blob/20990905ecdcf15f6f76fef80506d53831f7857b/Sustainsys.Saml2/Configuration/SPOptions.cs)
.
Copy
Set-PSUAuthenticationMethod `
-Type "Saml2" `
-EntityId "http://psu.ironman.local/sp" `
-IdentityProviderEntityId 'https://ironman.local/idp' `
-MetadataAddress 'https://idp.ironman.local/idp/shibboleth' `
-Configure {
$options = $args[0]
$options.SPOptions.DiscoveryServiceUrl = 'https://idp.ironman.local/discovery'
}
[](https://docs.powershelluniversal.com/v3/config/security/saml2#example-azure-a-d)
Example: Azure AD
----------------------------------------------------------------------------------------------------------
You will need the following information from Azure AD.
Application (client) ID - Found on the Overview page.
Federation metadata document - Click Endpoints on the Overview page.
SAML-P sign-on endpoint - Click Endpoints on the Overview page.
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#step-by-step)
Step by Step
Click Security \\ Authentication.
Add SAML2 authentication provider.
Click the Edit Properties button.
For Entity ID, you will need to put the Azure AD application ID prefixed with `spn:`
For example: `spn:2cf33625-e312-4659-a7bd-66ade51a0ea2`
For Identity Provider Entity ID, you will need to retrieve the entity ID from the Federation metadata document. Open the document in a web browser.

Entity ID Property
For Metadata Address, insert the Federation metadata document URL.
For the Return URL, insert the URL of your PowerShell Universal server with the `/Saml2/Acs` path.
Copy
https://localhost/Saml2/Acs
For Single Sign-On Service URL, insert the SAML-P sign-on endpoint from Azure.

SAML2 Properties
Once complete, save the settings and enable the SAML provider. Click sign out and navigate to your admin console URL.
Copy
https://localhost/admin
You will be forwarded to Azure for login and redirected back to PowerShell Universal after authentication.
Any errors that occur will be listed in the PowerShell Universal log. If you fail to login, you can navigate to `/login` to login with a local account.
[](https://docs.powershelluniversal.com/v3/config/security/saml2#example-okta)
Example: Okta
-------------------------------------------------------------------------------------------------
This example shows how to configure Okta SAML2 authentication for use with PowerShell Universal.
Within Okta, you will need to configure your application similar to the following. HTTPS is required by SAML2, and you will need to include the URL for your PSU instance in the Single Sign On URL, followed by `/Saml2/Acs`. The path is case sensitive.
The Audience Restriction should be the URL of your PowerShell Universal server.

In order for your users to access PowerShell Universal, you will need to ensure they have been assigned to the Okta application.

Within the Sign On tab of your application, click the View SAML setup instructions button.

You will need to capture the two URLs and download the certificate for configuring PowerShell Universal. See the next step on how to use these URLs within the `authentication.ps1` file.
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#authentication.ps1)
authentication.ps1
The authentication.ps1 file is used for configuring PowerShell Universal.
Copy
Set-PSUAuthenticationMethod -Type "Saml2" `
-EntityId "https://localhost:5001" `
-IdentityProviderEntityId "http://www.okta.com/exk5dvbyzgASPiOFp5d7" `
-CallbackPath "https://localhost:5001" `
-SigningKey "C:\Users\adamr\Downloads\okta.cert" `
-SingleSignOnServiceUrl "https://dev-36706648.okta.com/app/dev-36706648_psusaml_1/exk5dvbyzgASPiOFp5d7/sso/saml"
Parameter
Description
Type
EntityId
This value should match what you put in Audience Restriction within Okta.
string
IdentityProviderEntityId
This is the value that was presented in the View SAML setup instructions page.
string
CallbackPath
This is the path that the user will be redirected to if no redirect path was provided
string
SigningKey
This is the certificate file that was downloaded on the View SAML setup instructions page.
string
SingleSignOnServiceUrl
This is the sign on URL that was provided on the View SAML setup instructions page.
string
[](https://docs.powershelluniversal.com/v3/config/security/saml2#example-shibboleth)
Example: Shibboleth
-------------------------------------------------------------------------------------------------------------
This example shows how to configure Shibboleth for use with PowerShell Universal. It provides the very basic configuration and does not necessarily follow best practices.
This assumes that you have installed Shibboleth Identity Provider v4 with Active Directory integration.
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#ldap.properties)
ldap.properties
LDAP properties have been configured to authentication against the local domain using a Domain Administrator account. The LDAP URL has been configured and TLS has been disabled.
Below you will find the full example of the `ldap.properties` file.
Copy
# LDAP authentication (and possibly attribute resolver) configuration
# Note, this doesn't apply to the use of JAAS authentication via LDAP
## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator
idp.authn.LDAP.authenticator=adAuthenticator
## Connection properties ##
idp.authn.LDAP.ldapURL=ldap://ironman.local:389
idp.authn.LDAP.useStartTLS = false
# Time in milliseconds that connects will block
#idp.authn.LDAP.connectTimeout = PT3S
# Time in milliseconds to wait for responses
#idp.authn.LDAP.responseTimeout = PT3S
# Connection strategy to use when multiple URLs are supplied, either ACTIVE_PASSIVE, ROUND_ROBIN, RANDOM
#idp.authn.LDAP.connectionStrategy = ACTIVE_PASSIVE
## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust
idp.authn.LDAP.sslConfig = jvmTrust
## If using certificateTrust above, set to the trusted certificate's path
idp.authn.LDAP.trustCertificates=%{idp.home}/credentials/ldap-server.crt
## If using keyStoreTrust above, set to the truststore path
idp.authn.LDAP.trustStore=%{idp.home}/credentials/ldap-server.truststore
## Return attributes during authentication
idp.authn.LDAP.returnAttributes=passwordExpirationTime,loginGraceRemaining,sn,mail
## DN resolution properties ##
# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator
# for AD: CN=Users,DC=example,DC=org
idp.authn.LDAP.baseDN=CN=Users,DC=ironman, DC=local
idp.authn.LDAP.subtreeSearch = true
idp.authn.LDAP.userFilter=(sAMAccountName={user})
# bind search configuration
# for AD: [email protected]
[email protected]
# Format DN resolution, used by directAuthenticator, adAuthenticator
# for AD use idp.authn.LDAP.dnFormat=%[email protected]
idp.authn.LDAP.dnFormat=%[email protected]
# pool passivator, either none, bind or anonymousBind
#idp.authn.LDAP.bindPoolPassivator = none
# LDAP attribute configuration, see attribute-resolver.xml
# Note, this likely won't apply to the use of legacy V2 resolver configurations
idp.attribute.resolver.LDAP.ldapURL=%{idp.authn.LDAP.ldapURL}
idp.attribute.resolver.LDAP.connectTimeout=%{idp.authn.LDAP.connectTimeout:PT3S}
idp.attribute.resolver.LDAP.responseTimeout=%{idp.authn.LDAP.responseTimeout:PT3S}
idp.attribute.resolver.LDAP.connectionStrategy=%{idp.authn.LDAP.connectionStrategy:ACTIVE_PASSIVE}
idp.attribute.resolver.LDAP.baseDN=%{idp.authn.LDAP.baseDN:undefined}
idp.attribute.resolver.LDAP.bindDN=%{idp.authn.LDAP.bindDN:undefined}
idp.attribute.resolver.LDAP.useStartTLS=%{idp.authn.LDAP.useStartTLS:true}
idp.attribute.resolver.LDAP.trustCertificates=%{idp.authn.LDAP.trustCertificates:undefined}
idp.attribute.resolver.LDAP.searchFilter=(sAMAccountName=$resolutionContext.principal)
# LDAP pool configuration, used for both authn and DN resolution
#idp.pool.LDAP.minSize = 3
#idp.pool.LDAP.maxSize = 10
#idp.pool.LDAP.validateOnCheckout = false
#idp.pool.LDAP.validatePeriodically = true
#idp.pool.LDAP.validatePeriod = PT5M
#idp.pool.LDAP.validateDN =
#idp.pool.LDAP.validateFilter = (objectClass=*)
#idp.pool.LDAP.prunePeriod = PT5M
#idp.pool.LDAP.idleTime = PT10M
#idp.pool.LDAP.blockWaitTime = PT3S
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#relying-party.xml)
relying-party.xml
The `relying-party.xml` file has been updated to enable open IdP. This means that any entity ID can communicate with the identity provider. You can also configure this to enforce specific entity IDs. The default configure has also been adjusted to use the `SAML2.AttributeQuery` bean.
Copy
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#attribute-resolver.xml)
attribute-resolver.xml
The `attribute-resolver.xml` file has been updated to use the LDAPDirectory Data Connector. It loads the email address, given name, SN, and display name from Active Directory. It then maps the Principal Name, which will be the username of the user logging in, to the required claim type using an attribute encoder.
Copy
###
[](https://docs.powershelluniversal.com/v3/config/security/saml2#attribute-filter.xml)
attribute-filter.xml
The `attribute-filter.xml` file has been updated to release several of the attributes mapped by the LDAPDirectory data connector as well as the user name that will be used as the identity within PowerShell Universal.
Copy
[PreviousPowerShell Protect](https://docs.powershelluniversal.com/v3/config/security/powershell-protect)
[NextWS-Federation](https://docs.powershelluniversal.com/v3/config/security/ws-federation)
Last updated 1 year ago
---
# Running as a Service Account | PowerShell Universal
###
[](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account#application-service-account)
Application Service Account
The following permissions are not required if you are running PowerShell Universal 3.9.10 or 4.0.4 or later.
The PowerShell Universal application can be run as a Service Account. This means that the application will run all of its functions as the service account, including local application tasks, jobs (by default), and dashboards. This is a suggested configuration and is **REQUIRED** to execute jobs as other PSCredentials defined in Secret Variables.
To run Universal Automation as a Service Account, and not the local system account, an additional set of permissions are required for the Service Account. **Windows requires a distinct set of permissions for the Service Account if it is not in the local Administrators group on the host.**
If you are hosting PowerShell Universal in Internet Information Services (IIS) - these permissions **ALSO** are required for the Application Pool Identity account.
You can manually assign the required permissions in the "Local Security Policy" snap-in located here: Control Panel/ Administrative Tools / Local Security Policy / Local Policies / User Rights Assignment.
Add the User or Group to the following Rights to ensure PowerShell Universal Functionality:
* Log on as a service
* Adjust memory quotas for a process
* replace a process level token

Local Security Policy User Rights Assignments for Service
###
[](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account#script-run-as-requirements)
Script Run As Requirements
By using Secret Variables, you can save PSCredentials that can be used to execute scripts as a service account. These service accounts require a specific set of Windows permissions in order to execute jobs properly.
The service account you wish to use must have the "**Log on as batch job**" rights on the Windows host. Administrators on the machine have this by default, so if the service account is **NOT** an Administrator, you must ensure the account has the permission configured.
You can manually assign this permission in the "Local Security Policy" snap-in located here: Control Panel/ Administrative Tools / Local Security Policy / Local Policies / User Rights Assignment.
Add the User or Group to the "Log on as a batch job properties" members to allow the account to properly execute script jobs in PowerShell Universal:

Local Security Policy User Rights Assignments for Run As
Please consider that some of these settings may already be managed by Group Policy Object (GPO) definitions. This may cause these settings to be overwritten or unable to be applied.
###
[](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account#configuring-a-powershell-universal-service-to-run-as-the-account)
Configuring a PowerShell Universal Service to run as the account
Once you have configured the service account to use with PowerShell Universal, you will need to configure the PowerShell Universal Service to use that account.
Open the Services snapin by executing `services.msc` . Find the `PowerShell Universal` service and right click it and then click Properties. Click the Log On tab and enter the credentials for the service account.

Configuring the PowerShell Universal service to run under a specified account
[PreviousRepository](https://docs.powershelluniversal.com/v3/config/repository)
[NextBest Practices](https://docs.powershelluniversal.com/v3/config/best-practices)
Last updated 1 year ago
---
# WS-Federation | PowerShell Universal
WS-Federation requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
WS-Federation supports both Active Directory Federation Services and Azure Active Directory.
You first need to configure ADFS or AzureAD to support Universal.
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#configuring-adfs-for-universal-dashboard)
Configuring ADFS for Universal
------------------------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#service-settings)
Service Settings
These are the current Federation Service settings for our domain.

###
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#relying-parties)
Relying Parties
You need to configure the following Relying Parties settings for Universal. On the Identifiers tab, provide the URL to the Universal website. HTTPS is required.

On the Endpoints tab. You'll need to include a WS-Federation Passive Endpoint. Make sure to include the trailing slash.

Finally, you'll need to configure a Claim Issuance Policy for the Relying Party Trust. Create an Issuance Transform Rule that sends at least the Name and Name ID to Universal.
You can configure additional claims you'd like to use if you are using policies in Universal.
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#configuring-for-azure-active-directory)
Configuring For Azure Active Directory
------------------------------------------------------------------------------------------------------------------------------------------------------------
Follow the documentation for the Azure Active Directory configuration found on this [Microsoft Document](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/ws-federation?view=aspnetcore-2.2#azure-active-directory)
.
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#configuring-universal-dashboard)
Configuring Universal
------------------------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#use-appsettings.json)
Use Appsettings.json
After configuring ADFS or AAD, you can now provide the properties to Universal for the MetadataAddress and Wtrealm. Read about these settings on the our [Settings](https://docs.powershelluniversal.com/v3/config/settings)
page.
Here is an example of how to update the `appsettings.json` file to accommodate the correct settings for WS-Federation.
Copy
{
"Kestrel": {
"Endpoints": {
"HTTP": {
"Url": "http://*:5000"
}
},
"RedirectToHttps": "false"
},
"ApplicationInsights": {
"InstrumentationKey": ""
},
"Logging": {
"Path": "%PROGRAMDATA%/PowerShellUniversal/log.txt",
"RetainedFileCountLimit": 31,
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"CorsHosts": "",
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "%ProgramData%\\UniversalAutomation\\database.db",
"GitRemote": "",
"GitUserName": "",
"GitPassword": "",
"ConfigurationScript": ""
},
"Api": {
"Url": ""
},
"Authentication" : {
"Windows": {
"Enabled": "false"
},
"WSFed": {
"Enabled": "true",
"MetadataAddress": "https://ironman.local:443/FederationMetadata/2007-06/FederationMetadata.xml",
"Wtrealm": "https://ironman.local:12345",
"CallbackPath": "/auth/signin-wsfed"
},
"OIDC": {
"Enabled": "false",
"CallbackPath": "/auth/signin-oidc",
"ClientID": "",
"ClientSecret": "",
"Resource": "",
"Authority": "",
"ResponseType": "",
"SaveTokens": "false"
},
"SessionTimeout": "25"
},
"Jwt": {
"SigningKey": "PleaseUseYourOwnSigningKeyHere",
"Issuer": "IronmanSoftware",
"Audience": "PowerShellUniversal"
},
"UniversalDashboard": {
"AssetsFolder": "%ProgramData%\\PowerShellUniversal\\Dashboard"
},
"ShowDevTools": false,
"HideAdminConsole": false
}
When running your server, you should now be prompted for your credentials either via the Internet Explorer single-sign system or you will be forwarded to the WS-Fed login page.

###
[](https://docs.powershelluniversal.com/v3/config/security/ws-federation#use-authentication.ps1)
Use Authentication.ps1
You can configure WS-Federation authentication in the admin console. To do so, navigate to Security \\ Authentication. Add the WS-Federation provider by selecting it from the drop down in the top right.

Next, edit the properties of the authentication provider and specify the configuration details for your ADFS setup.

Once configured, enable the WS-Federation provider. Then, log out and navigate to `/admin` You will be prompted to login to your WS-Federation provider.
[PreviousSAML2](https://docs.powershelluniversal.com/v3/config/security/saml2)
[NextRepository](https://docs.powershelluniversal.com/v3/config/repository)
Last updated 2 years ago
---
# Repository | PowerShell Universal
The configuration data for PowerShell Universal is primarily stored within the repository. By default, the repository folder can be found in `%ProgramData%\UniversalAutomation\Repository`. You can adjust the location of the repository by editing the `appsettings.json` file.
The repository contains PowerShell scripts and XML files that are produced when using the PowerShell Universal admin console. The repository folder is also watched for changes so any change made on disk will cause the system to reload the file and reconfigure the platform. When using Git integration, the repository folder is what is synchronized with the git remote.
All configuration cmdlets are part of the [Universal](https://www.powershellgallery.com/packages/Universal)
module.
[](https://docs.powershelluniversal.com/v3/config/repository#whats-stored-in-the-repository)
What's Stored in the Repository
---------------------------------------------------------------------------------------------------------------------------------
Files stored in the repository are stored as plain text to allow for easy differencing with source control tools.
* Authentication
* Dashboards
* Endpoints
* Environments
* Licenses
* Login Pages
* Pages
* Published Folders
* Rate Limits
* Roles
* Schedules
* Scripts
* Settings
* Tags
* Triggers
[](https://docs.powershelluniversal.com/v3/config/repository#whats-not-stored-in-the-repository)
What's Not Stored in the Repository
-----------------------------------------------------------------------------------------------------------------------------------------
These entities are stored within the PowerShell Universal database.
* App Tokens
* Identities
* Job History
[](https://docs.powershelluniversal.com/v3/config/repository#editing-the-repository)
Editing the Repository
----------------------------------------------------------------------------------------------------------------
You can edit the repository files directly in the admin console by navigating to Settings \\ Configurations. The editor allows you to create files and folders and edit any file within the repository directory.

[](https://docs.powershelluniversal.com/v3/config/repository#configuration-scripts)
Configuration Scripts
--------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/repository#authentication.ps1)
Authentication.ps1
Stored in `.universal\authentication.ps1`
This script is responsible for configuring f[orms authentication](https://docs.powershelluniversal.com/v3/config/security#forms-authentication)
. If forms authentication is not being used, this file is ignored.
You can use the [`Set-PSUAuthentication`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSUAuthenticationMethod.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#dashboards.ps1)
Dashboards.ps1
Stored in `.universal\dashboards.ps1`
This script is responsible for registering PS1 files are [dashboards](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards)
with the system. Each command contains the meta-data for the dashboard including name, base URL, and environment.
You can use the [`New-PSUDashboard`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUDashboard.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#endpoints.ps1)
Endpoints.ps1
Stored in `.universal\endpoints.ps1`
This script is responsible for defining all the [API endpoints](https://docs.powershelluniversal.com/v3/config/api)
within the PowerShell Universal instance.
You can use the [`New-PSUEndpoint`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUEndpoint.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#environments.ps1)
Environments.ps1
Stored in `.universal\environments.ps1`
This script is responsible for defining all the environments within PowerShell Universal.
You can use the [`New-PSUEnvironment`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUEnvironment.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#licenses.ps1)
Licenses.ps1
Stored in `.universal\licenses.ps1`
This script is responsible for defining the license used in PowerShell Universal.
You can use the [`Set-PSULicense`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSULicense.txt)
cmdlet in this file.
Copy
Set-PSULicense -Key ""
###
[](https://docs.powershelluniversal.com/v3/config/repository#loginpage.ps1)
LoginPage.ps1
Stored in `.universal\loginPage.ps1`
This script is responsible for configuring a custom [login page](https://docs.powershelluniversal.com/v3/config/login-page)
.
You can use the [`New-PSULoginpage`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSULoginPage.txt)
and [`New-PSULoginPageLink`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSULoginPageLink.txt)
in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#initialize.ps1)
Initialize.ps1
Stored in `.universal\initialize.ps1`
This script runs before any configuration is done within PowerShell Universal. The server is running but none of the services have started. This is useful for install modules or configuring secret vaults before discovery of those resources are started.
###
[](https://docs.powershelluniversal.com/v3/config/repository#pages)
Pages
Stored in the `pages` folder.
This folder contains the page XML files. These are not intended to be edited manually and should be edited with the page designer.
###
[](https://docs.powershelluniversal.com/v3/config/repository#publishedfolders.ps1)
PublishedFolders.ps1
Stored in `.universal\publishedFolders.ps1`
This script is responsible for configuring [published folders](https://docs.powershelluniversal.com/v3/platform/published-folders)
.
You can use the [`New-PSUPublishedFolder`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUPublishedFolder.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#ratelimits.ps1)
RateLimits.ps1
Stored in `.universal\rateLimits.ps1`
This script is responsible for configuring [rate limits](https://docs.powershelluniversal.com/v3/api/rate-limiting)
.
You can use the [`New-PSURateLimit`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSURateLimit.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#roles.ps1)
Roles.ps1
Stored in `.universal\roles.ps1`
This script is responsible for configuring [roles](https://docs.powershelluniversal.com/v3/userinterfaces/dashboards/role-based-access)
.
You can use the [`New-PSURole`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSURole.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#schedules.ps1)
Schedules.ps1
Stored in `.universal\schedules.ps1`
This script is responsible for configuring [schedules](https://docs.powershelluniversal.com/v3/automation/schedules)
.
You can use the [`New-PSUSchedule`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUSchedule.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#scripts.ps1)
Scripts.ps1
Stored in `.universal\scripts.ps1`
This script contains the meta-data for [scripts](https://docs.powershelluniversal.com/v3/automation/scripts)
. Actual scripts can be stored anywhere. The path that is included is relative to the repository. Full path names are also allowed.
You can use the [`New-PSUScript`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUScript.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#settings.ps1)
Settings.ps1
Stored in `.universal\settings.ps1`
This script is responsible for configuring system [settings](https://docs.powershelluniversal.com/v3/config/settings)
.
You can use the [`Set-PSUSetting`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/Set-PSUSetting.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#tags.ps1)
Tags.ps1
Stored in `.universal\tags.ps1`
This script is responsible for configuring tags.
You can use the [`New-PSUTag`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUTag.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#triggers.ps1)
Triggers.ps1
Stored in `.universal\triggers.ps1`
This script is responsible for configuring [triggers](https://docs.powershelluniversal.com/v3/automation/triggers)
.
You can use the [`New-PSUTrigger`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUTrigger.txt)
cmdlet in this file.
###
[](https://docs.powershelluniversal.com/v3/config/repository#variables)
Variables
Stored in `.universal\variables.ps1`
This script is responsible for configuring [variables](https://docs.powershelluniversal.com/v3/userinterfaces/pages/variables)
.
You can use the [`New-PSUVariable`](https://github.com/ironmansoftware/universal-docs/blob/master/cmdlets/New-PSUVariable.txt)
cmdlet in this file.
[](https://docs.powershelluniversal.com/v3/config/repository#custom-configuration-script)
Custom Configuration Script
--------------------------------------------------------------------------------------------------------------------------
A custom configuration script can be executed within the configuration process. The path to the configuration script can be defined in `appsettings.json` or as an environment variable.
appsettings.json
Copy
"Data": {
"ConfigurationScript": "customScript.ps1"
}
Environment Variable
Copy
$Env:Data__ConfigurationScript = "customScript.ps1"
You can chose to return items such as endpoints, scripts or dashboards from the script. Additionally, you can use this script to configure resources like modules and secret vaults before the system is started. The custom configuration script is run before any other configuration scripts.
[](https://docs.powershelluniversal.com/v3/config/repository#read-only-configuration-sections)
Read-Only Configuration Sections
------------------------------------------------------------------------------------------------------------------------------------
Read-Only sections allow you to include script in your configuration files that will not be touched by changes in the admin console. This allows you to run additional logic, generate resources dynamically and create classes for use in OpenAPI schemas.
The `PSUHeader` region is placed at the top of your script. `PSUFooter` is placed at the bottom.
Copy
#region PSUHeader
1..100 | ForEach-Object {
New-PSUEndpoint -Url "/endpoint/$_" -Endpoint {
}
}
#endregion
New-PSUEndpoint -Url "/user" -Endpoint {
}
#region PSUFooter
#endregion
[PreviousWS-Federation](https://docs.powershelluniversal.com/v3/config/security/ws-federation)
[NextRunning as a Service Account](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account)
Last updated 2 years ago
---
# Best Practices | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/config/best-practices#general)
General
--------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#avoiding-writing-to-the-repository-directory)
Avoiding Writing to the Repository Directory
The repository directory defaults to `C:\ProgramData\UniversalAutomation\Repository`
Writing files directly to the repository directory in your scripts can have adverse side effects on performance of the system. PowerShell Universal employs a file system watcher to check for changes to files made on disk. Any changes made within the directory trigger the watcher and configuration file reload verification.
In some instances, writing files can result in configuration reloads that may restart dashboards or cause internal caches to be cleared.
It's recommended to avoid writing to this directory directly in a default configuration. If you would like to write to the directory, consider disabling the server-wide Auto Reload setting. This will disable the file system watcher and you will no longer risk impacting the configuration of the system.

###
[](https://docs.powershelluniversal.com/v3/config/best-practices#favor-non-integrated-environments)
Favor Non-Integrated Environments
While the integrated environment is fast and easy to use, it runs all of your PowerShell operations within the PowerShell Universal service. Issues with a single script or endpoint can affect the stability of the system.
When using non-integrated environments, an external PowerShell process is started. For APIs and Dashboards, that process can be long running but can be restarted without affecting the rest of the system. With jobs and terminals, a new process is started for each instance of the job and terminal. As jobs and terminals are stopped, the process is terminated, and any resources consumed by that process are reclaimed by the system.
Additionally, when loading modules into the integrated environment, the process space may become polluted with different versions of common DLLs that PSU may be using itself. This can cause assembly binding problems that may cause the imported modules to fail to function as expected.
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#isolate-problematic-modules)
Isolate Problematic Modules
Complex PowerShell modules can cause problems with PowerShell Universal. Certain modules are not designed to be hosted in a long running process like PowerShell Universal. You will want to use these modules in transient operations like jobs.
For example, dbatools may leak database connections when used directly within PowerShell Universal's integrated environment. To avoid this, you can start an external process by running a PowerShell Universal job in a non-integrated environment. The script will run, the process will terminate, and the database connection will be reclaimed automatically.
Below is a list of some modules we have experienced issues with.
* dbatools - Memory usage and leaked database connections
* PSFramework - Memory usage
* VMware PowerCLI - Connection management is scoped to the process
* Az - Connection management is scoped to the process
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#leverage-custom-modules)
Leverage Custom Modules
Building custom modules ensures that you can use the same functionality throughout the PowerShell Universal platform without duplicating code. You can use the same functions in APIs, scripts and dashboards without having to duplicate the logic.
Reducing the amount of script an any of these places can help you to better test and isolate issues that are caused by integrating with the platform or by the module itself.
Also consider building functions to wrap complex dashboard components. This reduces the overall complexity of the dashboard script and makes it easy to debug and read.
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#set-a-cache-lifetime)
Set a Cache Lifetime
When using `Set-PSUCache`, ensure that you set some sort of lifetime to the cache. This is especially important if you have data that isn't being used all the time and is large in size. Data set into the cache without a lifetime is never returned to the system.
For example, you can use the sliding expiration to expire cache data if it isn't used for some time for one hour.
Copy
Set-PSUCache -Key 'Data' -Value (Get-Date) -SlidingExpiration (New-Timespan -Hours 1)
[](https://docs.powershelluniversal.com/v3/config/best-practices#apis)
APIs
--------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#avoid-returning-highly-complex-objects)
Avoid Returning Highly Complex Objects
By default, API endpoints will serialize returned objects to JSON using `ConvertTo-Json`. Although the platform restricts the depth of the JSON, highly complex objects can cause the cmdlet to spin out of control and consume high amounts of CPU. PowerShell Universal will attempt to cancel this processing if it is detected but it will still cause issues with your API environment.
Make sure you understand the complexity of the objects you are returning. If objects are too complex, consider using `Select-Object` to select a subset of the data returned. You can also call `ConvertTo-Json` yourself to control the `-Depth` parameter.
An example of this would be returning Process objects with `Get-Process` . Due to the complexity of the Process type, it causes problems during serialization. Instead, select only a subset of the properties that are required.
Copy
Get-Process | Select-Object Name,Id
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#avoid-long-running-processes-in-apis)
Avoid Long Running Processes in APIs
The HTTP thread pool is limited in size. Long running processes in APIs can cause the pool to become exhausted which can cause problems for the entire PowerShell Universal server. If you plan to have an API that takes more than a few seconds, consider having the API start a job. You can then create a second API to check the state of jobs returned by the first API. This will ensure that the operation continues to process but the HTTP thread pool reclaims the available connection.
For example, you could have the following APIs. The first endpoint starts a job and returns the job ID. The second endpoint retrieves the pipeline output for the specified job.
Copy
New-PSUEndpoint -Url '/createReport' -Method POST -Endpoint {
(Invoke-PSUScript -Name CreateReport.ps1 -Integrated)
}
New-PSUEndpoint -Url '/createReport/:id' -Method GET -Endpoint {
Get-PSUJob -Id $Id -Integrated | Get-PSUJobPipelineOutput -Integrated
}
To call these endpoints, we could do the following with `Invoke-RestMethod`.
Copy
$Id = Invoke-RestMethod http://localhost:5000/createReport -Method POST
Start-Sleep 5
Invoke-RestMethod http://localhost:5000/createReport/$Id -Method GET
[](https://docs.powershelluniversal.com/v3/config/best-practices#automation)
Automation
--------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#reduce-unnecessary-job-output)
Reduce Unnecessary Job Output
While storing job output is useful for auditing, storing all job output can cause your storage to balloon in size which in turn will slow the performance of your PowerShell Universal system. Some steps you can take to keep job output in check are as follows.
####
[](https://docs.powershelluniversal.com/v3/config/best-practices#discard-pipeline-output)
Discard Pipeline Output
If you aren't going to use pipeline output, you can instruct PowerShell Universal to discard it. This will reduce the amount of data stored as well as increase the performance of your jobs because the system doesn't need to serialize all output to for storage. You will still see your output streams in the job log.
####
[](https://docs.powershelluniversal.com/v3/config/best-practices#take-advantage-of-streams)
Take Advantage of Streams
Using Debug, Warning and Error streams can help to reduce what is shown in the job by default. Setting the action preference per stream can allow you to disable certain streams for regular operations but enable streams when the job is experience problems.
For example, if you use `Write-Debug` throughout your script, you can disable that via the `$DebugActionPreference` variable by setting it to `SilentlyContinue`. If the job were to start to experience problems, you could set it to `Continue` to view the output in the log.
####
[](https://docs.powershelluniversal.com/v3/config/best-practices#utilize-out-null)
Utilize Out-Null
`Out-Null` can capture would-be pipeline output and discard it. If you don't want to discard all pipeline output, you can discard some of it by using `Out-Null`. This will improve performance and reduce the size of your job data.
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#aggressively-groom-unimportant-jobs)
Aggressively Groom Unimportant Jobs
Some jobs, like a trigger that is used for notifications, may almost never been reviewed. Consider setting the job history very low in this case.
[](https://docs.powershelluniversal.com/v3/config/best-practices#dashboards)
Dashboards
--------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#use-functions-in-dashboards)
Use Functions in Dashboards
When creating complex sections of a dashboard, it's advised to wrap it in a function to better organize and isolate that complex section. Highly nested dashboards are hard to debug and make it easy to introduce syntax errors that will affect the entire dashboard.
We also recommend using modules to store your functions to further reduce the size and complexity of your core dashboard script. Additionally, modules can then be shared across dashboards.
An example would be to wrap the logic of a table within a function and then use the function within the dashboard.
Copy
function New-ProcessTable {
$Data = Get-Process
$Columns = @(
New-UDTableColumn -Title 'Name' -Property 'Name'
New-UDTableColumn -Title 'Id' -Property 'Id'
)
New-UDTable -Data $Data -Columns $Columns -ShowSearch
}
New-UDDashboard -Content {
New-ProcessTable
}
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#consider-leveraging-jobs)
Consider Leveraging Jobs
Jobs are useful because they start an external process and can be used to audit interactions with the dashboard. Since dashboards are long running, certain operations and modules can begin to cause memory or other resource problems if used under load. Starting jobs ensures that the environment is reclaimed after each execution.
Jobs make sense for operations that make changes (e.g. creating a VM or user), but their performance characteristics won't work for every scenario.
An example would be calling a job from a form.
Copy
New-UDForm -Content {
New-UDTextbox -Id 'UserName' -Label 'UserName'
} -OnSubmit {
Invoke-PSUScript -Name 'CreateUser.ps1' -UserName $EventData.UserName -Environment PS7 -Integrated -Wait
Show-UDToast "User $($EventData.UserName) was created!"
}
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#schedule-dashboard-restarts)
Schedule Dashboard Restarts
If you are experience issues with dashboard resources, you can restart dashboards using a scheduled job that runs during non-business hours. You can use the `Get-PSUDashboard`, `Stop-PSUDashboard` and `Start-PSUDashboard` cmdlets to restart the individual dashboards. This technique is only valid when dashboards are running in non-integrated environments.
###
[](https://docs.powershelluniversal.com/v3/config/best-practices#be-aware-of-render-performance-with-new-udtable)
Be Aware of -Render Performance with New-UDTable
One feature of `New-UDTable` and`New-UDTableColumn`, is the ability to render columns to contain any component that you wish to display based on the row of data that you are providing to the table. This is usually useful for customizing the look and feel or by providing actions for the row's data. Rendering can become a performance issue if used incorrectly. Rendering many rows at once or using the render ScriptBlock to run long running processes will cause problems.
####
[](https://docs.powershelluniversal.com/v3/config/best-practices#rendering-too-many-rows)
Rendering Too Many Rows
If you are using the `-Data` parameter of `New-UDTable`, the `-Render` ScriptBlock will be called for each item you pass into the data parameter. If you have hundreds or thousands of items, this will cause page load times to increase.
Consider using `-LoadData` to load and display only a page of data at a time. This only calls `-Render` for the displayed items and not the entire data set.
####
[](https://docs.powershelluniversal.com/v3/config/best-practices#long-running-renders)
Long Running Renders
Due to the implementation details of `-Render`, it's not suggested to use long running render operations. If you expect your `-Render` to take more than a few milliseconds, consider using `New-UDDynamic` to off load the render back to the server and display a loading skeleton. The server can efficiently schedule the rendering operation using the runspace pool in this case.
An example of this is shown below.
Copy
$Data = @(
@{Dessert = 'Frozen yoghurt'; Calories = 1; Fat = 6.0; Carbs = 24; Protein = 4.0 }
@{Dessert = 'Ice cream sandwich'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
@{Dessert = 'Eclair'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
@{Dessert = 'Cupcake'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
@{Dessert = 'Gingerbread'; Calories = 200; Fat = 6.0; Carbs = 24; Protein = 4.0 }
)
$Columns = @(
New-UDTableColumn -Property Dessert -Title Dessert -Render {
New-UDDynamic -Content {
Start-Sleep (Get-Random -Min 1 -Max 5)
New-UDButton -Text "Click for Dessert!" -OnClick { Show-UDToast -Message $EventData.Dessert } -Variant 'text'
} -LoadingComponent {
New-UDSkeleton
}
}
New-UDTableColumn -Property Calories -Title Calories
New-UDTableColumn -Property Fat -Title Fat
New-UDTableColumn -Property Carbs -Title Carbs
New-UDTableColumn -Property Protein -Title Protein
)
The result is a table that loads immediately but displays loading skeletons in the slow-to-render columns.

[PreviousRunning as a Service Account](https://docs.powershelluniversal.com/v3/config/running-as-a-service-account)
[NextDebugging Scripts](https://docs.powershelluniversal.com/v3/development/debugging-scripts)
Last updated 2 years ago
---
# Debugging Scripts | PowerShell Universal
Scripts that run within Universal run within background processes or runspaces which may make it hard to debug what is happening within a script. You can use cmdlets like Write-Debug and Write-Verbose to provide more information in logs for dashboards and jobs.
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#integrated-debugger)
Integrated Debugger
----------------------------------------------------------------------------------------------------------------------
Requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
. Debugging is not supported in Windows PowerShell.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#enable-debugger)
Enable Debugger
In order to use the debugger, you need to enable it in the environment to wish to use it within. Click Settings \\ Environment and select Enable Debugger.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#use-the-debugger)
Use the Debugger
PowerShell Universal integrates directly with the PowerShell debugger. You can include `Wait-Debugger` within your scripts to cause them to pause. Once paused, you will be able to access the runspace by navigating to Platform \\ Debugging
For example, assume you have a dashboard with a `Wait-Debugger` call included.
Copy
New-UDDashboard -Title "Dashboard" -Content {
Wait-Debugger
$Data = @(
@{Dessert = 'Frozen yoghurt'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0}
@{Dessert = 'Ice cream sandwich'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0}
@{Dessert = 'Eclair'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0}
@{Dessert = 'Cupcake'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0}
@{Dessert = 'Gingerbread'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0}
)
New-UDTable -Data $Data -Paging -PageSize 2 -PaginationLocation 'top'
}
You'll notice that loading the page will result in the dashboard hanging. This is because the debugger is paused.

Paused Dashboard
You can then view the paused scripts in the debugging table.

Breakpoints
You can then click the Debug button to open a debug terminal.

Debug Button
Once within the debug terminal, you can execute commands as well as continue, step into, step out of and step over lines in the script.

Debug Terminal
Executing commands will execute them directly in the PowerShell Universal runspace. You can inspect variables or execute additional commands in the runspace's context.

Debug Terminal Commands
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#logging-scripts)
Logging Scripts
--------------------------------------------------------------------------------------------------------------
Certain aspects of Universal will log their scripts automatically. Other features may require you log yourself.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#apis)
APIs
You can use the Live Log view on the Log tab to view logs for the selected API.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#jobs)
Jobs
Jobs log extensively. You will see console and pipeline output. If you set`$DebugPreference` or `$VerbosePreference` , you will also see those streams in the console output. You can add additional log messages using `Write-Debug` or `Write-Verbose` .
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#dashboards)
Dashboards
See dashboard Development for information on how to use VS Code for development.
Dashboards log informational, warning and error messages to their log. It's recommended to use logging when starting a dashboard rather than trying to attach a debugger. You can also use the `$DebugPreference` variable to get additional information during your dashboard startup.
Copy
$DebugPreference = 'Continue'
New-UDDashboard -Title 'Test' -Content {
Write-Debug "My dashboard is loading. I have am $user with $roles"
New-UDTypography -Text 'Hello, world'
}
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#authentication-and-authorization)
Authentication and Authorization
You can use the Live Log view on the authentication and role pages to see PowerShell stream output.
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#debugging-scripts-from-a-powershell-console)
Debugging Scripts from a PowerShell Console
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
You can debug any script within Universal (or any PowerShell process, really) using the debugging cmdlets that are available in PowerShell. These cmdlets allow you to connect to local PowerShell processes, like Universal, and step through your scripts right in the terminal.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#pausing-the-script)
Pausing the Script
First, you will need to ensure that the script will wait for you to connect the debugger before continuing. This means that you'll need to include a `Wait-Debugger` command somewhere in your script.
Dashboards will only wait 10 seconds during startup so putting a Wait-Debugger in them may not work. You should rely on the use of $DebugPreference and Write-Debug to diagnosis dashboard startup issues.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#executing-your-script)
Executing your script
Now that you have your script setup to pause and wait for the debugger, you will want to execute your script. For jobs, just start the job. For APIs, you will need to make a request to the API via the endpoint you are trying to test. For dashboards, you will want to load the page in your browser. For authentication and authorization, you will want to login.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#finding-your-process-id)
Finding your process ID
Once you have your `Wait-Debugger` command in the script that you want to debug, you'll need to start the script and determine the process it is running within.
####
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#jobs-1)
Jobs
Jobs run in their own isolated process within Universal. All you will have to do is start the job and it will start the process and wait on your `Wait-Debugger` command. Once your job has started, you can use the `Get-UAJob` cmdlet to find that job's process ID.
####
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#apis-1)
APIs
APIs run in a single PowerShell process. It does not start a new process for each API call. You can locate the API process by finding the pwsh or PowerShell process with the command line that includes `StartApi`.
####
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#dashboards-1)
Dashboards
Dashboards run in their own isolated PowerShell process. The process ID is listed in the dashboard table within the Admin Console.
####
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#authentication-and-authorization-1)
Authentication and Authorization
Authentication and authorization scripts run within the Universal server. You can find the `Universal.Server.exe` process and attach to that.
**Integrated Environment**
Any feature running within the integrated environment will be running within the `Universal.Server.exe` process. You will need to attach to this process in order to debug them.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#attaching-to-the-process-and-debugging-the-runspace)
Attaching to the Process and Debugging the Runspace
Once you have the process that you want to attach to, you can do so by using `Enter-PSHostProcess` . Simply specify the process ID that you found in the previous step.
Copy
Enter-PSHostProcess -id 1231
Enter-PSHostProcess uses named pipes and requires that you have permission to the process that you are accessing. If you are running Universal as a service you may need to run it as your local account to properly connect to the process.
Once you have attached to the process, you will now want to find the runspace where your code is running. To do so, you can use the `Get-Runspace` cmdlet. This will return a list of runspaces currently active in your process. Look for the runspace marked `InBreakpoint`. This is the runspace waiting on the `Wait-Debugger` command.
Now that you found your runspace, use `Debug-Runspace` to attached to the runspace. You will now have the opportunity to issue debugging commands against that runspace. You can view the status of variables, issue commands and even step through the script.
For a full list of debugging commands, you can see the [Microsoft documentation here](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_debuggers?view=powershell-7#starting-and-stopping-the-debugger)
.
###
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#example-of-connecting-to-api-process)
Example of Connecting to API Process
The following is an example of how to connect to an API process.
Copy
$Process = Get-Process pwsh | Where-Object { $_.CommandLine.Contains('StartApi') }
Enter-PSHostProcess -Id $Process.Id
Get-Runspace
Debug-Runspace -Id 2
[](https://docs.powershelluniversal.com/v3/development/debugging-scripts#debugging-with-visual-studio-code)
Debugging with Visual Studio Code
--------------------------------------------------------------------------------------------------------------------------------------------------
To debug a script, you can use the Wait-Debugger cmdlet within your script to pause the script until a debugger is attached. You can then use a debugger, like VS Code, to attach to the process and runspace to view variables, step through code and execute debugging commands.
You can also debug scripts using the built in `Enter-PSHostProcess`, `Get-Runspace` and `Debug-Runspace` cmdlets.
[PreviousBest Practices](https://docs.powershelluniversal.com/v3/config/best-practices)
[NextEditor](https://docs.powershelluniversal.com/v3/development/editor)
Last updated 3 years ago
---
# Editor | PowerShell Universal
The editor controls within the PowerShell Universal admin console provide a rich editing experience for PowerShell users. You will be able to take advantage of IntelliSense, formatting and parser error support.
[](https://docs.powershelluniversal.com/v3/development/editor#intellisense)
IntelliSense
---------------------------------------------------------------------------------------------

IntelliSense
All editors within PowerShell Universal will provide IntelliSense. You should be able to complete commands, parameters, built-in variables, and paths.
There are a couple of caveats with IntelliSense.
**IntelliSense runs within the PowerShell Universal server**
It does not rely on a configured environment to function. It runs within the PowerShell server process so will be using the current version of PowerShell 7 referenced by the server.
**Universal Modules are Available**
Modules provided with PowerShell Universal are automatically included. You will see IntelliSense for the following modules.
* Universal
**Modules included in PSModulePath are Available**
Any module installed into a PSModulePath will be available in IntelliSense.
**Live Variables are Not Supported**
You will have access to built-in variables such as `ConfirmPreference` and `Host` but will not see variables specific to PowerShell Universal.
[](https://docs.powershelluniversal.com/v3/development/editor#formatting)
Formatting
-----------------------------------------------------------------------------------------

Formatting
You can use the `Invoke-Formatter` command of `PSScriptAnalyzer` within your scripts. You will need to install `PSScriptAnalyzer` to your PSModulePath in order to use this functionality. You can format by right clicking within the editor and selecting Format or by pressing F8.
[](https://docs.powershelluniversal.com/v3/development/editor#syntax-errors)
Syntax Errors
-----------------------------------------------------------------------------------------------
Syntax errors will be shown as red squiggles within the editor. Hovering over them will provide information about why the syntax error is present.

Syntax Errors
[](https://docs.powershelluniversal.com/v3/development/editor#psscriptanalyzer-integration)
PSScriptAnalyzer Integration
-----------------------------------------------------------------------------------------------------------------------------
The PowerShell Universal editor automatically integrates with PSScriptAnalyzer when it is installed on the PSU server. PSScriptAnalyzer will run against PowerShell scripts while you author them in the admin console. Warnings will be presented inline as well as an alert at the top of the editor.
Click the alert to be navigated to the first error or warning.
[PreviousDebugging Scripts](https://docs.powershelluniversal.com/v3/development/debugging-scripts)
[NextHangfire](https://docs.powershelluniversal.com/v3/development/hangfire)
Last updated 2 years ago
---
# Hangfire | PowerShell Universal
[Hangfire](https://www.hangfire.io/)
is the scheduling library that PowerShell Universal uses to execute and schedule jobs. It may be useful to view the status of the Hangfire job execution queues. This is typically useful if you have jobs that aren't running or schedules not starting at the proper times.
You can access the Job Details dashboard by clicking the Job Details button in Settings \\ General \\ Diagnostics.

Job Details
[](https://docs.powershelluniversal.com/v3/development/hangfire#scheduled-jobs)
Scheduled Jobs
---------------------------------------------------------------------------------------------------
Scheduled jobs will display jobs that you have scheduled yourself. You will see other jobs scheduled for internal tasks within PowerShell Universal.

Scheduled Jobs
[](https://docs.powershelluniversal.com/v3/development/hangfire#jobs)
Jobs
-------------------------------------------------------------------------------
You can use the Jobs tab to view jobs that are running, have executed or have failed. Jobs should typically not be marked as failed within Hangfire. This is a sign of an internal error within PowerShell Universal.

Jobs Tab
[PreviousEditor](https://docs.powershelluniversal.com/v3/development/editor)
[NextLogging](https://docs.powershelluniversal.com/v3/development/logging)
Last updated 3 years ago
---
# Logging | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/development/logging#admin-console)
Admin Console
------------------------------------------------------------------------------------------------
Logging levels can be changed within the Settings \\ General \\ Diagnostics page.
The Log Level setting configures PowerShell Universal logging settings. The Microsoft Log Level setting controls more low-level components within the web server. This is useful for debugging issues with authentication or authorization.

Clicking Download Logs will provide a zip archive of all the log files in the log directory on the server.
[](https://docs.powershelluniversal.com/v3/development/logging#appsettings.json)
appsettings.json
------------------------------------------------------------------------------------------------------
Logging is controlled back the [application settings](https://docs.powershelluniversal.com/v3/config/settings)
. By default, logging is enabled for the Information level and above. Also by default, logs are written to the `%ProgramData%\PowerShellUniversal` folder.
###
[](https://docs.powershelluniversal.com/v3/development/logging#changing-the-logging-level)
Changing the Logging Level
To adjust the logging level, change the values in the `appsettings.json` file in the Logging LogLevel section.
For example, to enable debug logging, set all the levels to debug.
Copy
"Logging": {
"Path":"%HOME%/.PowerShellUniversal/log.txt",
"LogLevel": {
"Default": "Debug",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Debug"
}
},
This setting can also be set using environment variables. These values need to be set before starting the Universal server.
Copy
$Env:Logging__LogLevel__Default = "Debug"
###
[](https://docs.powershelluniversal.com/v3/development/logging#changing-the-logging-path)
Changing the Logging Path
To adjust the logging path, change the values in the `appsettings.json` file in the Logging Path section.
Copy
"Logging": {
"Path":"C:\log.txt",
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
This setting can also be set using environment variables. These values need to be set before starting the Universal server.
Copy
$Env:Logging__Path = "C:\log.txt"
[](https://docs.powershelluniversal.com/v3/development/logging#logging-in-iis)
Logging in IIS
--------------------------------------------------------------------------------------------------
In addition to the logs produced by the Universal server, you can also retrieve log files produced by IIS. Log files for IIS are configured in the `web.config` file that is provided by Universal. By default, these logs are in the base website directory's log folder.
You can disable these logs by setting `stdoutLogEnabled` to false.
Copy
[](https://docs.powershelluniversal.com/v3/development/logging#event-logs)
Event Logs
------------------------------------------------------------------------------------------
Universal will create event log entries for Warning and Error logs. These logs are typically produced by unhandled exceptions that crash the process or by errors thrown by the Universal web host.
These logs can be found by looking for Warning and Error level messages produced by the .NET Runtime source.

[](https://docs.powershelluniversal.com/v3/development/logging#common-logging-scenarios)
Common Logging Scenarios
----------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/development/logging#out-of-process-startup-failure-in-iis)
Out of Process Startup Failure in IIS
This error is produced when the IIS server fails to start Universal. The problem can be diagnosed by looking in the [stdout logs produced by IIS](https://docs.powershelluniversal.com/v3/development/logging#logging-in-iis)
and the [logs produced by Universal](https://docs.powershelluniversal.com/v3/development/logging)
.
It may also be helpful to run the Universal server outside of IIS to validate that the server can properly run Universal.
###
[](https://docs.powershelluniversal.com/v3/development/logging#did-not-receive-port-from-client-process)
Did not receive port from client process
Universal uses gRPC to communicate with external PowerShell processes that are started by the system. These processes run jobs, dashboards and the API server. This error indicates that the PowerShell process did not start correctly.
To diagnosis this issue, [enable Debug logging](https://docs.powershelluniversal.com/v3/development/logging#changing-the-logging-level)
for the Universal server. Debug logging will record the stdout from the PowerShell process to capture any startup errors that may be occurring in the process.
[PreviousHangfire](https://docs.powershelluniversal.com/v3/development/hangfire)
[NextProfiling](https://docs.powershelluniversal.com/v3/development/profiling)
Last updated 3 years ago
---
# Profiling | PowerShell Universal
Available in PowerShell Universal 2.8.2 or later. Profiling only works for the integrated environment.
PowerShell Universal provides a performance profiler for debugging issues where the platform may exhibit slow responses. This is primarily useful when building Dashboards.
[](https://docs.powershelluniversal.com/v3/development/profiling#enable-profiling)
Enable Profiling
--------------------------------------------------------------------------------------------------------
Profiling will increase memory usage as profiling data is stored in memory. You can enable profiling by configuring the `Profiling` appsettings.json property. It is `false` by default. You will need to restart PowerShell Universal after enabling or disabling profiling.
Copy
"Profiling": true
[](https://docs.powershelluniversal.com/v3/development/profiling#access-profiling-data)
Access Profiling Data
------------------------------------------------------------------------------------------------------------------
You can access profiling data by navigating to `/profiler/results-index` . You will need to be logged in as administrator before being able to access this URL.
You will see a list of requests and their timings.

Result Index
Clicking on the request will display a break-down of the timings.

Timings
[](https://docs.powershelluniversal.com/v3/development/profiling#profiling-an-api-endpoint)
Profiling an API Endpoint
--------------------------------------------------------------------------------------------------------------------------
You can profile an API endpoint using `Measure-PSUBlock`. The API will be listed by URL in the result index.
For example, assume an API called `/process`.
Copy
New-PSUEndpoint -Url "/process" -Endpoint {
Measure-PSUBlock -Name 'Api' -ScriptBlock {
Get-Process | Select-Object name
}
} -Authentication -Timeout 0
The result of profiling this API would be listed by URL.

Viewing the profile for this API would list the block we measured.

[](https://docs.powershelluniversal.com/v3/development/profiling#profiling-a-dashboard)
Profiling a Dashboard
------------------------------------------------------------------------------------------------------------------
`Measure-UDBlock` is an alias for `Measure-PSUBlock`
You can use the built-in profiler with Dashboards. By default, certain internal action timings are recorded. You can also use the `Measure-PSUBlock` cmdlet to measure specific blocks within your dashboard.
For example, this dashboard uses `Measure-UDBlock` to measure the performance of the `Start-Sleep` cmdlet. The result is the block will take one second to execute.
Copy
New-UDDashboard -Title 'Dashboard' -Content {
New-UDDynamic -Id 'MyElement' -Content {
Measure-UDBlock -Name 'WithinDashboard' -ScriptBlock {
Start-Sleep 1
}
}
}
When reviewing requests within the profiler, you will want to look for `UDComponent\ElementPost` and `UDComponent\Element`. These are requests for elements within Dashboards.
Below is the example output from the dashboard shown above. Notice that the URL includes the element's ID `MyElement`. You'll also notice that the `WithinDashboard` block takes about 1 second.

Dashboard Timing
Not all timing will be displayed by default. You can click `show trivial` to expand all timings.

All Timings
[](https://docs.powershelluniversal.com/v3/development/profiling#profiling-a-job)
Profiling a Job
------------------------------------------------------------------------------------------------------
You can profile jobs by using `Measure-PSUBlock` within your script.
For example, assume we have a script that calls `Get-Service`.
Copy
Measure-PSUBlock -ScriptBlock {
Get-Service
} -Name 'Get-Service'
Running a profile on this script will list the job as `JobProfiler/{id}`. The id will match the job ID shown in the admin console.

The profile will include the block that was measured.

[PreviousLogging](https://docs.powershelluniversal.com/v3/development/logging)
[NextVisual Studio Code Extension](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension)
Last updated 3 years ago
---
# Visual Studio Code Extension | PowerShell Universal
PowerShell Universal can be managed with the PowerShell Universal Visual Studio Code extension. It allows you to connect to a local Universal instance and manage APIs, dashboards and scripts.
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#installation)
Installation
-------------------------------------------------------------------------------------------------------------------
You can download the extension from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ironmansoftware.powershell-universal)
. You can also download the extension from within the Visual Studio Code extension pane. Search for PowerShell Universal and click Install.

[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#configuration)
Configuration
---------------------------------------------------------------------------------------------------------------------
The extension will prompt you for the URL and App Token used to connect to your PowerShell Universal instance. Follow the instructions within the extension when it starts up.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#configure-from-powershell-universal)
Configure From PowerShell Universal
You can configure the extension by navigating to your PowerShell Universal admin console and then logging in. Navigate to Settings \\ Configurations and click Edit with VS Code. A new app token will be generated, and the URL will be set automatically.

Configure From the Admin Console
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#configure-multiple-connections)
Configure Multiple Connections
You can configure multiple connections by using the Connections setting. Click the Add Connection button to open Settings.

Add Connection
Next, click the Edit settings.json link underneath the Connections setting.

Settings
The connections array can have zero to many connections. You can provide names for each connection.
Copy
"powerShellUniversal.connections": [\
{\
"name": "Remote",\
"url": "http://localhost:5000",\
"appToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoIjoiOGNiMjAxYzAtZWQxMy00M2YyLThiMjItNmY1ODkxNjRhZWM2Iiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYmYiOjE2NDQxODMxMzIsImV4cCI6MjEwMjA5OTUyMCwiaXNzIjoiSXJvbm1hblNvZnR3YXJlIiwiYXVkIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCJ9.6Y9Bgwaw8GTpRrH3Qp7TCW-UGdPm85E9NClOCyGBVA8"\
}\
],
Once you have defined a connection, you can connect to that instance by clicking the Connect to Instance button within the Connections tree view.

Connect to Instance
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#features)
Features
-----------------------------------------------------------------------------------------------------------
The PowerShell Universal extension adds a new activity pane panel for PowerShell Universal. It has the following sections.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#apis)
APIs
You can manage APIs with the extension. You will see a list of APIs. You can click the `Open endpoints.ps1` button to view the endpoints file and add new endpoints. Clicking the refresh button will reload any endpoints you add. You can click the `Insert Invoke-RestMethod to Console` to add a call to the endpoint to the PowerShell Integrated Console.

###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#dashboards)
Dashboards
You can manage dashboards with the extension. You will see a list of dashboards underneath this section. You can open the dashboards.ps1 script, open the a single dashboard's script, restart a dashboard and view dashboards. When you open a dashboard script, the dashboard modules will automatically be loaded so that IntelliSense works in VS Code.

####
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#debug-dashboard-process)
Debug Dashboard Process
Debugging a dashboard process only works when running PowerShell Universal locally and as the same user you are logged in as.
You can connect the Visual Studio debugger to the dashboard process by right clicking on the dashboard and click Debug Dashboard Process. This requires the PowerShell extension for Visual Studio Code.

After connecting the debugger, you can run commands such as `Get-Runspace` and `Debug-Runspace` to begin debugging aspects of your dashboard.
####
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#view-dashboard-logs)
View Dashboard Logs
You can view dashboard logs by right clicking on the dashboard and clicking View Logs. They will open in a new tab.

###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#scripts)
Scripts
You can manage scripts with the extension. You will see a list of available scripts underneath this section. You can edit the scripts.ps1, edit an individual script and run scripts. When running scripts, you will receive feedback about the status of the script. Scripts with parameters are not supported in VS Code. You can still run them in PowerShell Universal.

[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#sample-browser)
Sample Browser
-----------------------------------------------------------------------------------------------------------------------
The sample browser can be used to insert samples from the PowerShell Universal Sample Repository into your PowerShell Universal instance. Just save the files it updates and your PowerShell Universal system will reflect the changes.
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#settings)
Settings
-----------------------------------------------------------------------------------------------------------
Settings can be found within the Visual Studio Code Settings dialog. You can open the settings dialog by press `Ctrl+,`
PowerShell Universal settings can be found under Extensions \\ PowerShell Universal.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#app-token)
App Token
The App Token is used for communicating with the PowerShell Universal management API. You can create an App Token manually by navigating to Security \\ Tokens within the PowerShell Universal admin console.
You can also automatically configure an App Token by click Edit with VS Code within Settings \\ Configurations.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#check-modules)
Check Modules
The extension will check the version of the Universal and UnviersalDashboard PowerShell modules found on the system. If they aren't installed or are not the latest version, new versions will be installed.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#connections)
Connections
The Connections array allow for defining multiple PowerShell Universal instance connections.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#local-editing)
Local Editing
Local editing causes files to be edited locally rather than via the management API. It will open files from the repository folder on disk and edit those files. PowerShell Universal will listen to file changes and reload those files accordingly.
When local editing is disabled, the contents of the files will be sent to the management API. This is required for remote systems or on systems where PowerShell Universal is not running as the same user as the on you are logged in as.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#samples-directory)
Samples Directory
This is the directory to store the PowerShell Universal samples.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#sync-samples)
Sync Samples
Whether to download samples from GitHub so they are available within the samples browser.
###
[](https://docs.powershelluniversal.com/v3/development/visual-studio-code-extension#url)
Url
The URL of the PowerShell Universal service. This should be the root URL, such as `http://localhost:5000`. This will be set automatically when clicking Edit in VS Code.
[PreviousProfiling](https://docs.powershelluniversal.com/v3/development/profiling)
[NextChangelog](https://docs.powershelluniversal.com/v3/changelog)
Last updated 3 years ago
---
# About | PowerShell Universal
[Download Universal for free](https://ironmansoftware.com/downloads)
Universal is a cross-platform solution for developing web-based tools with PowerShell. It currently provides three main features which include APIs, Automation and Dashboards.
Universal provides an Administrator console, management REST API, PowerShell cmdlets and a idempotent configuration system using PowerShell scripts.
**APIs**
* Build REST endpoints with PowerShell
* Accept common HTTP verbs
* Process request bodies
* Build dynamic URLs with route parameters and query strings
**Automation**
* Run scripts and view output, pipeline output, and parameters
* Respond to feedback from cmdlets like Read-Host
* Schedule scripts with CRON or one-time schedules
* Automatically build input forms based on param blocks
* Set variables and secrets that can be used throughout scripts
**Dashboard**
* Build web pages with PowerShell script
* Include input forms, charts and tables
* Build interactive websites with buttons, message boxes and more
**Platform**
* Cross-platform and supported on Windows and Linux
* Git integration for configuration files, scripts and dashboards
* Built-in authentication and authorization
* Support for Windows PowerShell as well as PowerShell

[](https://docs.powershelluniversal.com/v1#licensing)
Licensing
--------------------------------------------------------------------
Universal is licensed per feature and per server. You do not need to buy the entire platform if you would like to use a single piece of functionality. Visit our [website for more information](https://ironmansoftware.com/powershell-universal/)
on pricing.
[](https://docs.powershelluniversal.com/v1#free-to-use)
Free to Use
------------------------------------------------------------------------
Universal offers a lot of functionality for free. Below is a list of the features that require a paid license.
###
[](https://docs.powershelluniversal.com/v1#api)
API
You can run as many APIs are you want for free. You will need to purchase a license if you would like to enable authentication, authorization and rate limiting.
###
[](https://docs.powershelluniversal.com/v1#automation)
Automation
With the free version of Automation you can run up to 25 jobs a day with 2 jobs running concurrently. You will need a license to use [triggers](https://docs.powershelluniversal.com/v1/automation/triggers)
.
###
[](https://docs.powershelluniversal.com/v1#dashboard)
Dashboard
With the free version of dashboard, you can run unauthenticated dashboards. You will not have access to the diagnostics or console pages.
[NextGet Started](https://docs.powershelluniversal.com/v1/get-started)
Last updated 4 years ago
Was this helpful?
---
# Extension Changelog | PowerShell Universal
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-3.1.0-9-14-2022)
3.1.0 - 9/14/2022
---------------------------------------------------------------------------------------------------------
* Extension no longer installs the UniversalDashboard module
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-3.0.1-8-3-2022)
3.0.1 - 8/3/2022
-------------------------------------------------------------------------------------------------------
* Fixed an issue where the extension would fail to activate
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-3.0.0-6-14-2022)
3.0.0 - 6/14/2022
---------------------------------------------------------------------------------------------------------
* Added support for viewing all files in the repository
* Added a notification if a script fails to save
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.8.2-2-13-2022)
2.8.2 - 2/13/2022
---------------------------------------------------------------------------------------------------------
* Fixed an issue where saving an endpoint would not work
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.8.1-2-10-2022)
2.8.1 - 2/10/2022
---------------------------------------------------------------------------------------------------------
* Fixed an issue where endpoints would update multiple times when saved
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.8.0-2-8-2022)
2.8.0 - 2/8/2022
-------------------------------------------------------------------------------------------------------
* Added support for multiple PowerShell Universal connections
* Simplified extension initialization.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.5.0-11-10-2021)
2.5.0 - 11/10/2021
-----------------------------------------------------------------------------------------------------------
* Added support for editing individual endpoints
* Removed settings for starting the PSU server from the extension.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.3.0-9-14-2021)
2.3.0 - 9/14/2021
---------------------------------------------------------------------------------------------------------
* Aligned PSU version with extension version
* Fixed an issue where an error would be shown when loading the extension
* Fixed an issue where the wrong URL was used for viewing scripts
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.1.1-7-22-2021)
2.1.1 - 7/22/2021
---------------------------------------------------------------------------------------------------------
* Fixed an issue with module updates
* Fixed an issue with Connect-PSUServer being called before modules were installed
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.1.0-7-22-2021)
2.1.0 - 7/22/2021
---------------------------------------------------------------------------------------------------------
* Added support for view job status, logs, and pipeline output
* Force PowerShell extension to initialize when starting Universal
* Connect to the PowerShell Universal server (if configured) during startup
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.0.1-7-21-2021)
2.0.1 - 7/21/2021
---------------------------------------------------------------------------------------------------------
* Fixed an issue where remote editing of dashboards would not work
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-2.0.0-7-20-2021)
2.0.0 - 7/20/2021
---------------------------------------------------------------------------------------------------------
* Added 'Connect via Admin Console' to the connection dialog
* Added support for dashboard components and frameworks
* Added commands to install dashboard components and frameworks
* Added a check during startup for the current version of the Universal and UniversalDashboard modules
* Added a setting to disable the update module check (Check Modules)
* Improved the error message generated when the extension fails to connect to the server
* Fixed an issue with the URL for viewing jobs
* Fixed an issue with the URL for viewing the admin console page
* Dropped support for Universal 1.5
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.9.0-6-1-2021)
1.9.0 - 6/1/2021
-------------------------------------------------------------------------------------------------------
* Added support for self configuration in PowerShell Universal v2
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.8.2-4-15-2021)
1.8.2 - 4/15/2021
---------------------------------------------------------------------------------------------------------
* Fixed an issue where endpoints.ps1 and dashboards.ps1 could not be opened remotely
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.8.1-3-4-2021)
1.8.1 - 3/4/2021
-------------------------------------------------------------------------------------------------------
* Fixed an issue where the Local Editing setting was on by default
* Added an error message when a local file isn't found
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.8.0-3-1-2021)
1.8.0 - 3/1/2021
-------------------------------------------------------------------------------------------------------
* Added Local Editing Setting to edit files locally rather than via the REST API.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.5-2-25-2021)
1.7.5 - 2/25/2021
---------------------------------------------------------------------------------------------------------
* Scripts are now sorted by name alphabetically
* An error is now shown when the extension cannot connect to PowerShell Universal
* Removed the auto-import of UD and PSU modules. We recommend you install these from the PowerShell Gallery
Copy
Install-Module Universal
Install-Module UniversalDashboard
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.4-1-21-2021)
1.7.4 - 1/21/2021
---------------------------------------------------------------------------------------------------------
* Fixed an issue where the extension would fail to initialize on non-internet connected machines.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.3-12-31-2020)
1.7.3 - 12/31/2020
-----------------------------------------------------------------------------------------------------------
**Changed**
* Simplified first-time start up to attempt to connect with default settings to avoid having to do any configuration manually.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.2-12-30-2020)
1.7.2 - 12/30/2020
-----------------------------------------------------------------------------------------------------------
**Added**
* Settings for controlling the sample browser
**Changed**
* Improved the error message returned when attempting to automatically grant an app token and it fails.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.1-12-29-2020)
1.7.1 - 12/29/2020
-----------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#added)
Added
* Added a Sample Browser for inserting samples from the PowerShell Universal Samples Repository
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.7.0-12-28-2020)
1.7.0 - 12/28/2020
-----------------------------------------------------------------------------------------------------------
Breaking Change: This version of the extension only works with version 1.5.0 or later of PowerShell Universal
**Added**
* Added a version check for notification there is a new version of Universal
* Added a URL setting for connecting to PowerShell Universal
* Added new connection workflow to make it easier and more clear on how to connect to Universal.
**Changed**
* The extension now uses the REST API to make changes to configuration scripts
* Deprecated the Port and Computer name settings in favor of the URL setting
* The extension no longer automatically downloads PowerShell Universal
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.6.1)
\[1.6.1\]
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#changed)
Changed
* Fixed issue when attempting to download on Windows or Mac
* Fixed issue where extension would not work with Mac OS X
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.6.0)
\[1.6.0\]
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#added-1)
Added
* Added support for Debug-PSUDashboard
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#changed-1)
Changed
* Replaced PowerShell Versions with Environments in the configuration tree view
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.5.1)
\[1.5.1\]
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#changed-2)
Changed
* Fixed an issue where the extension wouldn't activate correctly.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.5.0)
\[1.5.0\]
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#added-2)
Added
* Add a command for manually refreshing the PSU configuration
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#changed-3)
Changed
* Fixed an issue where components wouldn't import correctly
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.4.0)
\[1.4.0\]
---------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#added-3)
Added
* Added a setting to disable starting the PowerShell Universal server on extension activation.
###
[](https://docs.powershelluniversal.com/v3/extension-changelog#changed-4)
Changed
* Extension will fail to activate after a number of retries while connecting to the Universal server.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.3.0)
\[1.3.0\]
---------------------------------------------------------------------------------------
* Added support configuration files.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.2.0)
\[1.2.0\]
---------------------------------------------------------------------------------------
* Added support for scripts and jobs.
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.1.0)
\[1.1.0\]
---------------------------------------------------------------------------------------
* Added support for APIs
[](https://docs.powershelluniversal.com/v3/extension-changelog#id-1.0.0)
\[1.0.0\]
---------------------------------------------------------------------------------------
* Initial release
[PreviousChangelog](https://docs.powershelluniversal.com/v3/changelog)
Last updated 1 year ago
---
# Additional Resources | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#downloads)
[Downloads](https://ironmansoftware.com/downloads)
-----------------------------------------------------------------------------------------------------------------------------------------------
Download the latest version of PowerShell Universal.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#blog)
[Blog](https://blog.ironmansoftware.com/tags/powershelluniversal/)
----------------------------------------------------------------------------------------------------------------------------------------------------------
The Ironman Software blog has articles about PowerShell Universal.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#forums)
[Forums](https://forums.ironmansoftware.com/)
---------------------------------------------------------------------------------------------------------------------------------------
Connect with the PowerShell Universal community.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#discord)
[Discord](https://discord.gg/csWyH2arD3)
-----------------------------------------------------------------------------------------------------------------------------------
Chat with other PowerShell Universal users.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#purchasing)
[Purchasing](https://ironmansoftware.com/pricing)
-----------------------------------------------------------------------------------------------------------------------------------------------
Purchase a license for the features of PowerShell Universal.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#issue-tracker)
[Issue Tracker](https://github.com/ironmansoftware/powershell-universal)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
File a bug report or feature request for PowerShell Universal.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#samples)
[Samples](https://github.com/ironmansoftware/universal-samples)
----------------------------------------------------------------------------------------------------------------------------------------------------------
Samples that can be inserted into your PowerShell Universal system using the [PowerShell Universal extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ironmansoftware.powershell-universal)
.
[](https://docs.powershelluniversal.com/v1/get-started/additional-resources#videos)
[Videos](https://www.youtube.com/watch?v=LaZA90UzLPw&list=PL-0mHH7DlSiQ5q66FXHerWv2vOOodD2U9)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Check out video tutorials for PowerShell Universal.
[PreviousGet Started](https://docs.powershelluniversal.com/v1/get-started)
[NextInstallation](https://docs.powershelluniversal.com/v1/get-started/getting-started)
Last updated 4 years ago
Was this helpful?
---
# Installation | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#getting-started)
Getting Started
------------------------------------------------------------------------------------------------------------
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#powershell-module)
PowerShell Module
----------------------------------------------------------------------------------------------------------------
You can use the PowerShell Universal PowerShell module to install the Universal server. To install the module, use `Install-Module`.
Copy
Install-Module Universal
To install the Universal server, you can use `Install-PSUServer`.
Copy
Install-PSUServer -LatestVersion
You can configure the path that the server is stored in by using the `-Path` parameter.
Copy
Install-PSUServer -Path (Join-Path $Env:AppData "PSU")
You can add the PSU server to the PATH environment variable by use the `-AddToPath` parameter.
Copy
Install-PSUServer -AddToPath
Once the server has been installed, you can use `Start-PSUServer` to start it.
Copy
Start-PSUServer -Port 8080
You can specify the path to the executable using the `-ExecutablePath` parameter. If you have set the location of the server to `-AddToPath` with `Install-PSUServer`, `Start-PSUServer` should find the executable automatically.
Copy
Start-PSUServer -Port 8080 -ExecutablePath (Join-Path $MyPath "Universal.Server.exe")
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#chocolatey-package-windows)
Chocolatey Package (Windows)
------------------------------------------------------------------------------------------------------------------------------------
You can install PowerShell Universal using the [Chocolatey package](https://chocolatey.org/packages/powershelluniversal)
. The package runs the MSI install. It will install Universal as a service and open a web browser after the install.
You can login with the "admin" user and any password.
Copy
choco install powershelluniversal
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#winget-windows)
Winget (Windows)
------------------------------------------------------------------------------------------------------------
You can install PowerShell Universal using Winget. It will run the MSI and install as a service.
Copy
winget install ironmansoftware.powershelluniversal
You can also specify the `--silent` flag to prevent the installer from showing and the web browser from opening at the end of the install.
Copy
winget install ironmansoftware.powershelluniversal --silent
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#zip-install)
ZIP Install
----------------------------------------------------------------------------------------------------
You can also download the ZIP from our [Downloads page](https://ironmansoftware.com/downloads/)
if you would like to xcopy deploy the files on Windows or Linux.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#windows)
Windows
You can start Universal by unzipping the contents, unblocking the files and then executing `Universal.Server.exe`.
Copy
Expand-Archive -Path .\Universal.zip -DestinationPath .\Universal
Get-ChildItem .\Universal -Recurse | Unblock-File
Start-Process .\Universal\Universal.Server.exe
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#linux)
Linux
On Linux, start the process `Universal.Server`. You may need to `chmod +x` the file if it does not start.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#docker)
Docker
See the [Docker page](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#installation)
.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#msi-install-windows)
MSI Install (Windows)
----------------------------------------------------------------------------------------------------------------------
The MSI install will create a PowerShell Universal service and open the admin console after installation.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#properties)
Properties
####
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#suppressbrowser)
SUPPRESSBROWSER
Setting the SUPPRESBROWSER MSI property to true will prevent the browser from opening after installation.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started#next-steps)
Next Steps
--------------------------------------------------------------------------------------------------
At this point, Universal is up and running. Please consult other sections in this documentation for instructions on how to configure, secure, and start using PowerShell Universal. Happy Scripting!
[PreviousAdditional Resources](https://docs.powershelluniversal.com/v1/get-started/additional-resources)
[NextDocker](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker)
Last updated 4 years ago
Was this helpful?
---
# Get Started | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started#install-powershell-universal)
Install PowerShell Universal
----------------------------------------------------------------------------------------------------------------------
You'll need to install the PowerShell Universal server. [There are a lot of ways to do so](https://docs.powershelluniversal.com/v1/get-started/getting-started)
but you can use the command line below to get started quickly.
Windows
[](https://docs.powershelluniversal.com/v1/get-started#tab-windows)
Linux
[](https://docs.powershelluniversal.com/v1/get-started#tab-linux)
Mac OS X
[](https://docs.powershelluniversal.com/v1/get-started#tab-mac-os-x)
You can install PowerShell Universal as a service using Chocolatey.
Copy
choco install powershelluniversal
You can install PowerShell Universal using the Universal PowerShell module.
Copy
Install-Module Universal
Install-PSUServer -AddToPath
Start-PSUServer -Port 5000
You can install PowerShell Universal using the Universal PowerShell module.
Copy
Install-Module Universal
Install-PSUServer -AddToPath
Start-PSUServer -Port 5000
[](https://docs.powershelluniversal.com/v1/get-started#open-powershell-universal)
Open PowerShell Universal
----------------------------------------------------------------------------------------------------------------
By default, PowerShell Universal is running on port 5000 of localhost. You can access the admin console with the user name `admin` and any password.

[](https://docs.powershelluniversal.com/v1/get-started#powershell-universal-visual-studio-code-extension)
PowerShell Universal Visual Studio Code Extension
----------------------------------------------------------------------------------------------------------------------------------------------------------------
We recommend installing the [PowerShell Universal Visual Studio Code Extension](https://marketplace.visualstudio.com/items?itemName=ironmansoftware.powershell-universal)
to provide the best possible editing experience.
You can connect to your instance of PowerShell Universal, browse and insert samples and get up and running right away.
###
[](https://docs.powershelluniversal.com/v1/get-started#install-the-extension)
Install the Extension
Install the extension by searching for it in the extension page and clicking Install.

###
[](https://docs.powershelluniversal.com/v1/get-started#connect-to-powershell-universal)
Connect to PowerShell Universal
Click the PowerShell Universal icon on the left hand side and the extension will attempt to connect using the default URL and user name. The extension will notify you once it has connected.

###
[](https://docs.powershelluniversal.com/v1/get-started#inserting-a-sample)
Inserting a Sample
[Samples](https://github.com/ironmansoftware/universal-samples)
are available via the sample browser. You can select a sample and insert it into your PowerShell Universal instance. You'll need to save the file that is opened by Visual Studio Code for the sample to be inserted.

Learn more about the various features of PowerShell Universal
* [APIs](https://docs.powershelluniversal.com/v1/api/about)
* [Automation](https://docs.powershelluniversal.com/v1/automation/about)
* [Dashboards](https://docs.powershelluniversal.com/v1/dashboard/about)
[PreviousAbout](https://docs.powershelluniversal.com/v1)
[NextAdditional Resources](https://docs.powershelluniversal.com/v1/get-started/additional-resources)
Last updated 4 years ago
Was this helpful?
---
# Docker | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#installation)
Installation
-------------------------------------------------------------------------------------------------------------
Our docker image is available on [Docker Hub](https://hub.docker.com/r/ironmansoftware/universal)
. You can start it by pulling and then running with the default port bound.
Copy
docker pull ironmansoftware/universal
docker run --name 'PSU' -it -p 5000:5000 ironmansoftware/universal
####
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#tags)
Tags
Tag
Platform
1.3.0
linux/amd64
1.3.0-windowsservercore-1909
windows/amd64
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#persistent-data)
Persistent Data
-------------------------------------------------------------------------------------------------------------------
To create a Docker image that can persist the Universal data, you can create a dockerfile like the one below.
This dockerfile exposes port 5000, creates a `/data` volume, sets configuration environment variables to store the Universal repository and database in the volume and then sets the Universal.Server as the entry point to the container.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#linux)
Linux
Copy
FROM ironmansoftware/universal:latest
LABEL description="Universal - The ultimate platform for building web-based IT Tools"
EXPOSE 5000
VOLUME ["/data"]
ENV Data__RepositoryPath ./data/Repository
ENV Data__ConnectionString ./data/database.db
ENV UniversalDashboard__AssetsFolder ./data/UniversalDashboard
ENV Logging__Path ./data/logs/log.txt
ENTRYPOINT ["./home/Universal/Universal.Server"]
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker#windows)
Windows
Copy
FROM ironmansoftware/universal:1.3.1-windowsservercore-1809
LABEL description="Universal - The ultimate platform for building web-based IT Tools"
EXPOSE 5000
VOLUME ["C:/data"]
ENV Data__RepositoryPath C:/data/Repository
ENV Data__ConnectionString C:/data/database.db
ENV UniversalDashboard__AssetsFolder C:/data/UniversalDashboard
ENV Logging__Path C:/data/logs/log.txt
ENTRYPOINT ["C:/ProgramData/Universal/Universal.Server.exe"]
You can run a build with the build command.
Copy
docker build . --tag=universal-persistent
You can start the docker container with the run command and make sure to specify the volume to mount.
Copy
docker run --name powershelluniversal --mount source=psudata,target=/data --rm -d -p 5000:5000/tcp universal-persistent:latest
[PreviousInstallation](https://docs.powershelluniversal.com/v1/get-started/getting-started)
[NextUpgrading](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading)
Last updated 4 years ago
Was this helpful?
---
# Upgrading | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#general)
General
------------------------------------------------------------------------------------------------------
The Universal application binaries can generally be upgraded without having to change the configuration or database manually. This document will cover how to upgrade the application and some caveats to be aware of in regards to configuration and data persistence.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#data-persistence)
Data Persistence
Data is persisted in a LiteDB database with a default location of `%ProgramData%\UniversalAutomation\database.db`. The database will not be deleted during an upgrade of any kind. Any schema updates to the database will happen the first time you start up the new version of Universal. You may wish to backup your database before performing an upgrade.
###
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#configuration-persistence)
Configuration Persistence
Configuration files are stored by default in `%ProgramData%\UniversalAutomation`. Configuration files may be updated or transformed during an update. This will happen the first time that the new version of Universal server is started. You may wish to backup your configuration files before performing an upgrade.
If you are using git, changes to the Universal files will be synchronized after the server starts up.
####
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#appsettings.json)
appsettings.json
The `appsettings.json` file that is included in the application installation directory will be overwritten during upgrades. To avoid losing your settings in this file, consider installing it into the `%ProgramData%\PowerShellUniversal` folder. Universal will look at this folder first for [configuration settings.](https://docs.powershelluniversal.com/v1/config/settings#programdata-appsettings-json)
####
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#web.config)
web.config
The `web.config` file that is included in the application installation directory will be overwritten during upgrades. If you have moved your web.config file to an alternate location, it will not be overwritten. When creating an IIS website, you can simply include the `web.config` file in the web app's directory and have the [binaries stored in a different location](https://docs.powershelluniversal.com/v1/config/hosting/hosting-iis)
.
####
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#dashboard-components-and-frameworks)
Dashboard Components and Frameworks
New versions of Universal may include new versions of Universal Dashboard Frameworks or Components. By default, these components and frameworks are deployed to `%ProgramData%\PowerShellUniversal` during startup of the Universal server. During an upgrade, these files are not deleted. This ensures that dashboards will continue to run on the previous dashboard framework and component versions.
You should have multiple versions of the dashboard frameworks and components available when you start the new version of Universal.
By default, new dashboards are set to always use the latest version of the dashboard framework. You can chose to set it to a specific version if you would like but will have to manually change the version during an upgrade.
**Repository**
Most of the settings for PowerShell Universal are stored within the repository folder. By default, this is in `%ProgramData%\UniversalAutomation\Repository`. While the upgrade should not affect these files, you may want to backup the files before upgrading.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#zip-upgrade)
ZIP Upgrade
--------------------------------------------------------------------------------------------------------------
Always ensure to run `Unblock-File` on Windows to unblock all the files extracted the ZIP. If you do not, PowerShell Universal will not function properly.
When upgrading an manual ZIP file installation, you will need to stop the application, delete the entire binary folder and replace it with the new binary folder. When you start the new version of Universal, new dashboard frameworks and components will be deployed and the existing database will be loaded.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#msi-upgrade)
MSI Upgrade
--------------------------------------------------------------------------------------------------------------
To upgrade using the MSI, you can simply run the new version of the MSI. The MSI is setup to always perform a major upgrade. This means it will stop and remove the service, delete the entire installation directory, reinstall with the new files and then install and start the new service.
You will want to follow the guide on data and configuration persistence above to ensure all your settings are saved.
If you have configured a service account for your MSI installation, you will need to set the service account after upgrading.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#iis-upgrade)
IIS Upgrade
--------------------------------------------------------------------------------------------------------------
When upgrading with IIS, you will need to first stop your application pool to ensure that the binaries used by IIS are no longer in use and then replace the binaries with the new ones. Ensure that you follow the configuration persistence recommendations above with regards to the `web.config` file.
[](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading#litedb-v5-upgrade)
LiteDB v5 Upgrade
--------------------------------------------------------------------------------------------------------------------------
PowerShell Universal uses LiteDB to store jobs, app tokens, identities and git sync history. The original version of LiteDB included with PSU is version 4. We will be moving to version 5 in a future version. We have added version 5 support but are not yet upgrading users databases. You can choose to upgrade your database to version 5 by adjusting your connection string to perform an upgrade on the database. We suggest backing up your database file before doing so.
In `appsettings.json`, you will need to change the database type to `LiteDBv5` and add the upgrade parameter to the connection string.
Copy
"Data": {
"RepositoryPath": "%ProgramData%\\UniversalAutomation\\Repository",
"ConnectionString": "filename=%ProgramData%\\UniversalAutomation\\database.db;upgrade=true",
"DatabaseType": "LiteDBv5",
[PreviousDocker](https://docs.powershelluniversal.com/v1/get-started/getting-started/docker)
[NextLicensing](https://docs.powershelluniversal.com/v1/get-started/licensing)
Last updated 4 years ago
Was this helpful?
---
# System Requirements | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/get-started/system-requirements#windows)
Windows
------------------------------------------------------------------------------------------------
* [Windows PowerShell v5.1](https://www.microsoft.com/en-us/download/details.aspx?id=54616)
or greater or PowerShell v7.0 or greater
* [.NET Framework v4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)
(only for Windows PowerShell)
[](https://docs.powershelluniversal.com/v1/get-started/system-requirements#linux)
Linux
--------------------------------------------------------------------------------------------
* PowerShell v7.0 or great
* Validated Distributions: Ubuntu 18.04
[](https://docs.powershelluniversal.com/v1/get-started/system-requirements#mac-os-x)
Mac OS X
--------------------------------------------------------------------------------------------------
[PreviousLicensing](https://docs.powershelluniversal.com/v1/get-started/licensing)
[NextSupported Browsers](https://docs.powershelluniversal.com/v1/get-started/supported-browsers)
Last updated 4 years ago
Was this helpful?
---
# Licensing | PowerShell Universal
PowerShell Universal is licensed per server. We provide licenses for individuals and organizations.
You can purchase a license on [our website](https://store.ironmansoftware.com/pricing/powershell-universal)
.
###
[](https://docs.powershelluniversal.com/v1/get-started/licensing#whats-a-server)
What's a server?
A server is a single running instance of PowerShell Universal.
[](https://docs.powershelluniversal.com/v1/get-started/licensing#free-use-restrictions)
Free Use Restrictions
------------------------------------------------------------------------------------------------------------------
Universal can be used forever for free with the following limitations.
###
[](https://docs.powershelluniversal.com/v1/get-started/licensing#universal-api)
Universal API
* No authentication
* No Rate Limiting
###
[](https://docs.powershelluniversal.com/v1/get-started/licensing#universal-automation)
Universal Automation
* 25 jobs per day
* 2 concurrent jobs
* No Triggers
###
[](https://docs.powershelluniversal.com/v1/get-started/licensing#universal-dashboard)
Universal Dashboard
* No authentication
* No access to diagnostic tools
[PreviousUpgrading](https://docs.powershelluniversal.com/v1/get-started/getting-started/upgrading)
[NextSystem Requirements](https://docs.powershelluniversal.com/v1/get-started/system-requirements)
Last updated 4 years ago
Was this helpful?
---
# Supported Browsers | PowerShell Universal
Universal uses a variety of modern web frameworks and can have issues with older browsers such as Internet Explorer.
The current version of the following web browsers are supported: [Chrome](https://www.google.com/chrome/)
, [Firefox](http://www.mozilla.org/firefox/)
, [Safari](http://www.apple.com/safari/)
, and [Microsoft Edge](https://www.microsoft.com/en-us/windows/microsoft-edge)
We make a best effort to support Internet Explorer 11 for Universal Dashboard. IE11 is not supported for the Admin Console. There may be issues with certain components as we do not extensively test each change in IE11. If you desire particular functionality in IE11, please [file an issue](https://github.com/ironmansoftware/powershell-universal)
.
[PreviousSystem Requirements](https://docs.powershelluniversal.com/v1/get-started/system-requirements)
[NextVisual Studio Code Extension](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension)
Last updated 4 years ago
Was this helpful?
---
# Examples | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/examples#component-examples)
Component Examples
-----------------------------------------------------------------------------------------------
We maintain several component libraries that you can use in your dashboards directly or as examples.
* [Active Directory](https://github.com/ironmansoftware/powershell-universal/blob/master/Components/ActiveDirectory/UniversalDashboard.ActiveDirectory.psm1)
* [Azure](https://github.com/ironmansoftware/powershell-universal/tree/master/Components/Azure)
* [Hyper-V](https://github.com/ironmansoftware/powershell-universal/tree/master/Components/Hyper-V)
* [Monitoring](https://github.com/ironmansoftware/powershell-universal/tree/master/Components/Monitoring)
* [Network](https://github.com/ironmansoftware/powershell-universal/tree/master/Components/Network)
* [SQL](https://github.com/ironmansoftware/powershell-universal/tree/master/Components/SQL)
[](https://docs.powershelluniversal.com/v1/examples#single-file-configuration-examples)
Single-File Configuration Examples
-------------------------------------------------------------------------------------------------------------------------------
This page contains examples of PowerShell Universal configurations. All examples are built using single-file hosting and configuration. These examples assume that you have PowerShell Universal installed. To install PowerShell Universal, use the following command line.
Copy
Install-Module Universal
Install-PSUServer -AddToPath
You can login to PowerShell Universal using the username `admin` and any password.
Have an example of an API, Dashboard or Script that you think would fit nicely on this page? Feel free to open a pull-request on our [documentation repository](https://github.com/ironmansoftware/universal-docs)
.
[](https://docs.powershelluniversal.com/v1/examples#table-of-contents)
Table of Contents
---------------------------------------------------------------------------------------------
* Active Directory
* [Reset Password](https://docs.powershelluniversal.com/v1/examples/active-directory#reset-password)
* [List Locked Accounts](https://docs.powershelluniversal.com/v1/examples/active-directory#list-locked-accounts)
* [Restore Deleted User](https://docs.powershelluniversal.com/v1/examples/active-directory#restore-deleted-user)
* Hyper-V
* [Virtual Machine Creator](https://docs.powershelluniversal.com/v1/examples/hyper-v#virtual-machine-creator)
* Image Processing
* [Convert JPEG to PNG](https://docs.powershelluniversal.com/v1/examples/image-processing#convert-jpeg-to-png)
* [Convert JPEG to PNG API](https://docs.powershelluniversal.com/v1/examples/image-processing#convert-jpeg-to-png-api)
* [Rate Limited API](https://docs.powershelluniversal.com/v1/examples/image-processing#rate-limited-conversion-api)
* Monitoring
* [Windows Performance Counter Dashboard](https://docs.powershelluniversal.com/v1/examples/monitoring#windows-performance-counter-charts)
* Slack
* [Send a Message to Slack](https://docs.powershelluniversal.com/v1/examples/slack#send-message-to-slack)
* [Send a Message to Slack when a Script Fails](https://docs.powershelluniversal.com/v1/examples/slack#send-slack-message-on-failed-job)
[PreviousVisual Studio Code Extension](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension)
[NextActive Directory](https://docs.powershelluniversal.com/v1/examples/active-directory)
Last updated 4 years ago
Was this helpful?
---
# Active Directory | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/examples/active-directory#list-locked-accounts)
List Locked Accounts
--------------------------------------------------------------------------------------------------------------------
This example uses [Universal Automation](https://docs.powershelluniversal.com/v1/automation/about)
.
Shows an example of how to list locked Active Directory accounts. This example assumes that the user running PowerShell Universal has access to the local Active Directory environment.
Copy
Start-PSUServer -Port 8080 -Configuration {
New-PSUScript -Name 'LockedAccounts' -ScriptBlock {
Search-ADAccount -LockedOut
}
}
Locked accounts will be listed on the job page's pipeline output.

You can also access the locked accounts by using the Universal PowerShell module.
Copy
$Job = Get-PSUJob -Script (Get-PSUScript -name 'LockedAccounts.ps1') -First 1 -OrderDirection Descending
Get-PSUJobPipelineOuptut -Job $Job
[](https://docs.powershelluniversal.com/v1/examples/active-directory#reset-password)
Reset Password
--------------------------------------------------------------------------------------------------------
This example uses [Universal Automation](https://docs.powershelluniversal.com/v1/automation/about)
.
Shows an example of how to reset an Active Directory user account using PowerShell Universal Automation. This script accepts the identity of the account to reset, the password to set, whether to unlock the account and whether to require the user to change their password on logon.
Copy
Start-PSUServer -Port 8080 -Configuration {
New-PSUScript -Name 'Reset Password' -ScriptBlock {
param(
[String]$Identity,
[String]$Password,
[Switch]$Unlock,
[Switch]$ChangePasswordOnLogon
)
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
Set-ADAccountPassword -Identity $Identity -NewPassword $SecurePassword -Reset -Server $ComputerName -Credential $Domain
if ($Unlock)
{
Unlock-ADAccount –Identity $Identity -Server $ComputerName -Credential $Domain
}
if ($ChangePasswordOnLogon)
{
Set-ADUser –Identity $Identity -ChangePasswordAtLogon $true -Server $ComputerName -Credential $Domain
}
}
}

[](https://docs.powershelluniversal.com/v1/examples/active-directory#restore-deleted-user)
Restore Deleted User
--------------------------------------------------------------------------------------------------------------------
This account users PowerShell Universal [Dashboard](https://docs.powershelluniversal.com/v1/dashboard/about)
and [Automation](https://docs.powershelluniversal.com/v1/automation/about)
.
In this example, we use Universal Dashboard to create a dashboard that displays a table that includes all the deleted user accounts for the domain. It creates a custom column with a button that includes a Restore button that executes a script to restore the specified account. This example assumes that the identity running the script is capable of accessing Active Directory.
Copy
Start-PSUServer -Port 8080 -Configuration {
New-PSUScript -Name 'Restore User.ps1' -ScriptBlock {
param($DistinguishedName)
Restore-ADObject -Identity $DistinguishedName
}
New-PSUDashboard -Name 'Restore User' -BaseUrl '/' -Framework 'UniversalDashboard:Latest' -Content {
New-UDDashboard -Title 'Restore User' -Content {
$Columns = @(
New-UDTableColumn -Property Name -Title "Name"
New-UDTableColumn -Property DistinguishedName -Title "Distinguished Name"
New-UDTableColumn -Property Restore -Title Restore -Render {
$Item = $EventData
New-UDButton -Id "btn$($Item.ObjectGuid)" -Text "Restore" -OnClick {
Show-UDToast -Message "Restoring user $($Item.Name)" -Duration 5000
Invoke-UAScript -Name 'Restore User.ps1' -DistinguishedName $Item.DistinguishedName | Tee-Object -Variable job | Wait-UAJob
$Job = Get-UAJob -Id $Job.Id
if ($Job.Status -eq 'Completed')
{
Show-UDToast -Message "Restored user $($Item.Name)" -Duration 5000
}
else
{
$Output = Get-UAJobOutput -JobId $Job.Id | Select-Object -Expand Message
Show-UDToast -Message "Failed to restore user. $($Output -join "`n")" -BackgroundColor red -MessageColor white -Duration 5000
}
}
}
)
$DeletedUsers = Get-ADObject -Filter 'IsDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects | ForEach-Object {
@{
distinguishedname = $_.DistinguishedName
name = $_.Name
}
}
New-UDTable -Data $DeletedUsers -Columns $Columns
}
}
}

[PreviousExamples](https://docs.powershelluniversal.com/v1/examples)
[NextHyper-V](https://docs.powershelluniversal.com/v1/examples/hyper-v)
Last updated 4 years ago
Was this helpful?
---
# Visual Studio Code Extension | PowerShell Universal
PowerShell Universal can be managed with the PowerShell Universal Visual Studio Code extension. It allows you to connect to a local Universal instance and manage APIs, dashboards and scripts.
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#installation)
Installation
-------------------------------------------------------------------------------------------------------------------
You can download the extension from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ironmansoftware.powershell-universal)
. You can also download the extension from within the Visual Studio Code extension pane. Search for PowerShell Universal and click Install.

[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#configuration)
Configuration
---------------------------------------------------------------------------------------------------------------------
The extension will prompt you for the URL and App Token used to connect to your PowerShell Universal instance. Follow the instructions within the extension when it starts up.
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#features)
Features
-----------------------------------------------------------------------------------------------------------
The PowerShell Universal extension adds a new activity pane panel for PowerShell Universal. It has the following sections.
###
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#apis)
APIs
You can manage APIs with the extension. You will see a list of APIs. You can click the `Open endpoints.ps1` button to view the endpoints file and add new endpoints. Clicking the refresh button will reload any endpoints you add. You can click the `Insert Invoke-RestMethod to Console` to add a call to the endpoint to the PowerShell Integrated Console.

###
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#dashboards)
Dashboards
You can manage dashboards with the extension. You will see a list of dashboards underneath this section. You can open the dashboards.ps1 script, open the a single dashboard's script, restart a dashboard and view dashboards. When you open a dashboard script, the dashboard modules will automatically be loaded so that IntelliSense works in VS Code.

####
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#debug-dashboard-process)
Debug Dashboard Process
You can connect the Visual Studio debugger to the dashboard process by right clicking on the dashboard and click Debug Dashboard Process. This requires the PowerShell extension for Visual Studio Code.

After connecting the debugger, you can run commands such as `Get-Runspace` and `Debug-Runspace` to begin debugging aspects of your dashboard.
####
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#view-dashboard-logs)
View Dashboard Logs
You can view dashboard logs by right clicking on the dashboard and clicking View Logs. They will open in a new tab.

###
[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#scripts)
Scripts
You can manage scripts with the extension. You will see a list of available scripts underneath this section. You can edit the scripts.ps1, edit an individual script and run scripts. When running scripts, you will receive feedback about the status of the script. Scripts with parameters are not supported in VS Code. You can still run them in PowerShell Universal.

[](https://docs.powershelluniversal.com/v1/get-started/visual-studio-code-extension#sample-browser)
Sample Browser
-----------------------------------------------------------------------------------------------------------------------
The sample browser can be used to insert samples from the PowerShell Universal Sample Repository into your PowerShell Universal instance. Just save the files it updates and your PowerShell Universal system will reflect the changes.
[PreviousSupported Browsers](https://docs.powershelluniversal.com/v1/get-started/supported-browsers)
[NextExamples](https://docs.powershelluniversal.com/v1/examples)
Last updated 4 years ago
Was this helpful?
---
# Hyper-V | PowerShell Universal
[](https://docs.powershelluniversal.com/v1/examples/hyper-v#virtual-machine-creator)
Virtual Machine Creator
-----------------------------------------------------------------------------------------------------------------
This example uses [PowerShell Universal Dashboard](https://docs.powershelluniversal.com/v1/dashboard/about)
.
This example can be used to create virtual machines on a Hyper-V host. This dashboard assumes it's being run on the host in question. You could adjust the dashboard script to run on a remote host.
Copy
Start-PSUServer -Port 8080 -Configuration {
New-PSUDashboard -Name 'Hyper-V' -BaseUrl '/' -Framework 'UniversalDashboard:Latest' -Content {
$HostRam = Get-WMIObject -class Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | % {[Math]::Round(($_.sum / 1GB *0.97),0)-1}
$HostName=hostname
$SwitchList = @()
Get-VMSwitch | Select-Object -ExpandProperty name | ForEach-Object {
$SwitchList += $_
}
function Run-Checks
{
$VMHostInfo= Get-VMHost
$BootISOTextBoxText = (Get-UDElement -Id 'VMBootISO')['value']
$VHDRootTextBoxText = (Get-UDElement -Id 'VMVHDRoot')['value']
$VMNameTextBoxText = (Get-UDElement -Id 'VMName')['value']
$Generation = (Get-UDElement -Id 'VMGeneration')['value']
$SwitchNameComboBoxText = (Get-UDElement -Id 'VMSwitch')['value']
$RAMinGBTextBoxText = (Get-UDElement -Id 'VMRam')['value']
$CPUCountTextBoxText = (Get-UDElement -Id 'VMCPU')['value']
[int64]$VLANIDTextBoxText = (Get-UDElement -Id 'VMVLan')['value']
#Paths and Gen Sets
if ($BootISOTextBoxText -and $BootISOTextBoxText -ne "") {$ISOFilePathValid = test-path $BootISOTextBoxText}
if ($VHDRootTextBoxText -and $VHDRootTextBoxText -ne "") {$VHDBootPathValid = test-path $VHDRootTextBoxText}
if ($Generation -eq 'Gen1') { $VMGeneration = 1 } else { $VMGeneration = 2 }
if ($VMNameTextBoxText.Length -ne 0) { $VMExists = Get-VM -name $VMNameTextBoxText -ErrorAction SilentlyContinue }
if (-not (Test-Path $VMHostInfo.VirtualMachinePath) ) {Show-UDToast -Message "Default Virtual Machine path is not valid in HyperV Host Settings"}
elseif (-not (Test-Path $VMHostInfo.VirtualHardDiskPath) ) {Show-UDToast -Message "Default Virtual Harddisk path is not valid in HyperV Host Settings"}
elseif ($VMExists) {Show-UDToast -Message "VM with that name already exists"}
elseif ($VMNameTextBoxText.Length -eq 0) {Show-UDToast -Message "Please Enter VM Name"}
elseif ($SwitchNameComboBoxText -eq "Switch Name") {Show-UDToast -Message "Please Select a Switch Name"}
elseif ($ISOFilePathValid -eq $False) {Show-UDToast -Message "ISO File path in invaild"}
elseif ($VHDRootTextBoxText -eq "") {Show-UDToast -Message "VHD Root path is blank. Please enter a valid path"}
elseif ($VHDBootPathValid -eq $False) {Show-UDToast -Message "VHD Root path in invaild"}
elseif ($RAMinGBTextBoxText.Length -eq 0) {Show-UDToast -Message "Please Enter Ram Amount in GB"}
elseif ([int64]$RAMinGBTextBoxText -lt 1) {Show-UDToast -Message "Please Enter Ram Amount of at least 1GB"}
elseif ([int64]$RAMinGBTextBoxText -gt $HostRam) {Show-UDToast -Message "Please Enter Ram Amount of "+ $HostRam + "GB or bellow"}
elseif ($CPUCountTextBoxText.Length -eq 0) {Show-UDToast -Message "Please Enter a CPU Count"}
elseif ([int64]$CPUCountTextBoxText.Length -eq 0) {Show-UDToast -Message "Please Enter a CPU Count"}
elseif ([int64]$CPUCountTextBoxText -lt 1) {Show-UDToast -Message "Please Enter a CPU Count of at least 1"}
elseif ([int64]$CPUCountTextBoxText -gt 64) {Show-UDToast -Message "Please Enter a CPU Count of 64 or below"}
elseif ([int64]$VLANIDTextBoxText -gt 999 -or [int64]$VLANIDTextBoxText -lt 1) {Show-UDToast -Message "Please Enter VLAN ID between 1 and 999."}
else
{
(65..90) | ForEach-Object {
$DriveLetter = [char]$_
[int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']
if ($value -gt 65536)
{
Show-UDToast -Message "For $DriveLetter Drive please Enter a Disk Size of 65536 GB or below"
return $false
}
}
Show-UDToast -Message "Looking Good Man ;)"
return $true
}
return $false
}
function Create-VMs
{
Run-Checks
$BootISOTextBoxText = (Get-UDElement -Id 'VMBootISO')['value']
$VHDRootTextBoxText = (Get-UDElement -Id 'VMVHDRoot')['value']
$VMNameTextBoxText = (Get-UDElement -Id 'VMName')['value']
$Generation = (Get-UDElement -Id 'VMGeneration')['value']
[int]$SwitchNameComboBoxIndex = (Get-UDElement -Id 'VMSwitch')['value']
$SwitchNameComboBoxText = $SwitchList[$SwitchNameComboBoxIndex]
Show-UDToast -message ((Get-UDElement -Id 'VMSwitch') | ConvertTo-Json)
$RAMinGBTextBoxText = (Get-UDElement -Id 'VMRam')['value']
$CPUCountTextBoxText = (Get-UDElement -Id 'VMCPU')['value']
$VLANIDTextBoxText = (Get-UDElement -Id 'VMVLan')['value']
if ($Generation -eq 'Gen1') { $VMGeneration = 1 } else { $VMGeneration = 2 }
#Create VM
try
{
New-VM -Name $VMNameTextBoxText -MemoryStartupBytes ([int]$RAMinGBTextBoxText*1073741824) -SwitchName $SwitchNameComboBoxText -Generation $VMGeneration -ErrorAction Stop
}
catch
{
$VMCrateFailed=$True
Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Failed to Create :( $($_.Exception.Message)")
}
if (-Not($VMCrateFailed -eq $True))
{
(65..90) | ForEach-Object {
$DriveLetter = [char]$_
[int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']
if ($value -gt 0)
{
$Path = $VHDRootTextBoxText+"\"+$VMNameTextBoxText+"\"+$VMNameTextBoxText+"-"+$value+".vhdx"
if (-not (test-path $Path))
{
New-VHD -Path $Path -SizeBytes (Invoke-Expression ("$($Value)GB")) -Dynamic
}
else
{
$VHDPathExisted = $true
}
}
}
Get-VM $VMNameTextBoxText | Set-VMProcessor -Count $CPUCountTextBoxText
Get-VM $VMNameTextBoxText | set-VMNetworkAdapterVlan -Access -vlanId $VLANIDTextBoxText
(65..90) | ForEach-Object {
$DriveLetter = [char]$_
[int64]$value = (Get-UDElement -Id "Drive$DriveLetter")['value']
$Path = $VHDRootTextBoxText+"\"+$VMNameTextBoxText+"\"+$VMNameTextBoxText+"-"+$value+".vhdx"
if (Test-Path $Path)
{
Add-VMHardDiskDrive -VMName $VMNameTextBoxText -Path $Path -ControllerType SCSI -ControllerNumber 0
}
}
#
# REMOVING NETWORK FROM THE BOOT ORDER
#Set New Boot order
if ($VMGeneration -eq "2")
{
$old_boot_order = Get-VMFirmware -VMName $VMNameTextBoxText -ComputerName $HostName | Select-Object -ExpandProperty BootOrder
$new_boot_order = $old_boot_order | Where-Object { $_.BootType -ne "Network" }
Set-VMFirmware -VMName $VMNameTextBoxText -ComputerName $HostName -BootOrder $new_boot_order
}
# ADD DVD Drive with ISO Attached
if ($BootISOTextBoxText -ne "")
{
Get-VM $VMNameTextBoxText | Add-VMDvdDrive -Path $BootISOTextBoxText
}
if ($VHDPathExisted) {
Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Created OK, but at least one VHD already existed and was just reattached")
}
else
{
Show-UDToast -Message ("VM " + $VMNameTextBoxText + " Created OK")}
}
}
New-UDDashboard -Title "Hyper-V VM Creator" -Content {
New-UDContainer -Children {
New-UDTypography -Text "Hyper-V VM Creator" -Variant h3
New-UDRow -Columns {
New-UDColumn -LargeSize 6 -Content {
New-UDRow -Columns {
New-UDTextbox -Label 'VM Name' -Id 'VMName'
}
New-UDRow -Columns {
New-UDTextbox -Id 'VMRam' -Label 'RAM in GB' -Value $HostRam
}
New-UDRow -Columns {
New-UDTextbox -Id 'VMCPU' -Label 'CPU Count' -Value 2
}
New-UDRadioGroup -Label 'Generation' -Id 'VMGeneration' -Children {
New-UDRadio -Label 'Gen 1' -Value 'Gen1'
New-UDRadio -Label 'Gen 2' -Value 'Gen2'
} -Value 'Gen1'
}
New-UDColumn -LargeSize 6 -Content {
New-UDRow -Columns {
New-UDSelect -Id 'VMSwitch' -Label 'Switch Name' -Option {
$i = 0
$SwitchList | ForEach-Object {
New-UDSelectOption -Value $i -Name $_
$i++
}
}
}
New-UDTextbox -Id 'VMVLan' -Label 'VLAN ID'
}
}
New-UDRow -Columns {
New-UDColumn -LargeSize 12 -Content {
New-UDTextbox -Id 'VMBootISO' -Label 'Boot ISO'
}
}
New-UDRow -Columns {
New-UDColumn -LargeSize 12 -Content {
New-UDTextbox -Id 'VMVHDRoot' -Label 'VHD Root'
}
}
New-UDTypography -Text 'Drives' -Variant h4
New-UDRow -Columns {
New-UDColumn -LargeSize 6 -Content {
New-UDRow -Columns {
# Loop through each letter of the alphabet
(65..90) | ForEach-Object {
New-UDColumn -LargeSize 6 -Content {
$DriveLetter = [char]$_
New-UDTextbox -Id "Drive$DriveLetter" -Placeholder $DriveLetter
}
}
}
}
New-UDColumn -LargeSize 6 -Content {
New-UDButton -Text 'Do Some Checks' -OnClick { Run-Checks }
New-UDButton -Text 'Im feeling lucky Create Vm' -OnClick { Create-VMs }
}
}
}
}
}
}

[PreviousActive Directory](https://docs.powershelluniversal.com/v1/examples/active-directory)
[NextImage Processing](https://docs.powershelluniversal.com/v1/examples/image-processing)
Last updated 4 years ago
Was this helpful?
---
# Custom Status Codes | PowerShell Universal
Copy
New-PSUEndpoint -Url '/status' -Endpoint {
New-PSUApiResponse -StatusCode 418
}
This sample returns the [I am a teapot status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418)
.
[PreviousAPIs](https://docs.powershelluniversal.com/v4-beta/samples/apis)
[NextApps](https://docs.powershelluniversal.com/v4-beta/samples/apps)
Last updated 1 year ago
Was this helpful?
---
# APIs | PowerShell Universal
[Custom Status Codes](https://docs.powershelluniversal.com/v4-beta/samples/apis/custom-status-codes)
[PreviousVisual Studio Code Extension](https://docs.powershelluniversal.com/v4-beta/development/visual-studio-code-extension)
[NextCustom Status Codes](https://docs.powershelluniversal.com/v4-beta/samples/apis/custom-status-codes)
Was this helpful?
---
# Apps | PowerShell Universal
[Active Directory Tree View](https://docs.powershelluniversal.com/v4-beta/samples/apps/active-directory-tree-view)
[Export-CSV Download](https://docs.powershelluniversal.com/v4-beta/samples/apps/export-csv-download)
[Dynamic Select Dropdown](https://docs.powershelluniversal.com/v4-beta/samples/apps/dynamic-select-dropdown)
[Textbox Length Validation](https://docs.powershelluniversal.com/v4-beta/samples/apps/textbox-length-validation)
[Tree View Font Size](https://docs.powershelluniversal.com/v4-beta/samples/apps/tree-view-font-size)
[SQL Data Grid](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid)
[PreviousCustom Status Codes](https://docs.powershelluniversal.com/v4-beta/samples/apis/custom-status-codes)
[NextActive Directory Tree View](https://docs.powershelluniversal.com/v4-beta/samples/apps/active-directory-tree-view)
Was this helpful?
---
# Active Directory Tree View | PowerShell Universal
Copy
New-UDApp -Title "New-UDTree Active Directory Example" -Content {
$RootDN = "OU=Users,DC=ironman,DC=local"
$OUList = Get-ADOrganizationalUnit -Filter * -SearchBase $RootDN -SearchScope Subtree -Properties ParentGuid -ErrorAction SilentlyContinue | Sort-Object Name | Select-Object Name, DistinguishedName, ParentGuid
$AllOrganizationalUnits = @()
foreach ($OU in $OUList) {
if (!($OU.DistinguishedName -eq $RootDN)) {
$ParentGuid = ([GUID]$OU.ParentGuid).Guid
$ParentOU = Get-ADObject -Identity $ParentGuid -ErrorAction SilentlyContinue
if ($ParentOU) {
$AllOrganizationalUnits += [PSCustomObject]@{
Name = $OU.Name
DistinguishedName = $OU.DistinguishedName
ParentDn = $ParentOU.DistinguishedName
}
}
}
}
New-UDTreeView -Node {
foreach ($ou in $AllOrganizationalUnits) {
if ( $ou.ParentDn -eq $RootDN ) {
New-UDTreeNode -Name $ou.Name -id $ou.DistinguishedName
}
}
} -OnNodeClicked {
$SubOUs = $AllOrganizationalUnits | Where-Object { $_.ParentDn -eq $eventdata.id } | Sort-Object Name
foreach ($SubOU in $SubOUs) {
New-UDTreeNode -Name $SubOU.Name -Id $SubOU.DistinguishedName
}
$SelectedOU = $(ConvertFrom-Json $body).Id
Show-UDToast -Message $SelectedOU -Duration 6000
}
}
[PreviousApps](https://docs.powershelluniversal.com/v4-beta/samples/apps)
[NextExport-CSV Download](https://docs.powershelluniversal.com/v4-beta/samples/apps/export-csv-download)
Last updated 1 year ago
Was this helpful?
---
# Export-CSV Download | PowerShell Universal
Copy
New-UDButton -Text 'Generate Report' -OnClick {
$TempFile = New-TemporaryFile
Get-Process | Select-Object -First 5 | Export-CSV -Path $TempFile
$Csv = Get-Content -Path $TempFile -Raw
Remove-Item $TempFile
Start-UDDownload -StringData $Csv -FileName 'processes.csv' -ContentType 'text/csv'
} -ShowLoading
This sample collects the first 5 processes and outputs them to a temporary CSV using Export-CSV and then uses `Start-UDDownload` to send the data to the end user.
Note that the CSV is saved to the server using a temporary file and then read into memory using `Get-Content`. That content is then downloaded via the end user's browser.
`-ShowLoading` is used on the button to display feedback to the user while the download is prepared.
[PreviousActive Directory Tree View](https://docs.powershelluniversal.com/v4-beta/samples/apps/active-directory-tree-view)
[NextDynamic Select Dropdown](https://docs.powershelluniversal.com/v4-beta/samples/apps/dynamic-select-dropdown)
Last updated 1 year ago
Was this helpful?
---
# Dynamic Select Dropdown | PowerShell Universal
This sample creates a dynamic select drop down where the second select changes based on the first.

Dynamic dropdown
Copy
$Session:Cities = @()
New-UDSelect -Option {
New-UDSelectOption -Name 'Idaho' -Value 'Idaho'
New-UDSelectOption -Name 'Michigan' -Value 'Michigan'
New-UDSelectOption -Name 'Wisconsin' -Value 'Wisconsin'
} -Label 'State' -OnChange {
# Create session data based on the state selected
if ($EventData -eq 'Idaho')
{
$Session:Cities = @("Boise", "Hailey", "Stanley")
}
if ($EventData -eq 'Michigan')
{
$Session:Cities = @("Ann Arbor", "Detroit", "Ironwood")
}
if ($EventData -eq 'Wisconsin')
{
$Session:Cities = @("Madison", "Milwaukee", "Irma")
}
# Refresh the city dynamic region
Sync-UDElement -Id 'city'
}
New-UDDynamic -Id 'city' -Content {
# if we don't have any cities, disable the select
$Disabled = $Session:Cities.Length -eq 0
New-UDSelect -Option {
$Session:Cities | Foreach-Object {
New-UDSelectOption -Name $_ -Value $_
}
} -Disabled:$Disabled -Label 'City'
}
[PreviousExport-CSV Download](https://docs.powershelluniversal.com/v4-beta/samples/apps/export-csv-download)
[NextTextbox Length Validation](https://docs.powershelluniversal.com/v4-beta/samples/apps/textbox-length-validation)
Last updated 1 year ago
Was this helpful?
---
# Textbox Length Validation | PowerShell Universal
This sample demonstrates how to validate the length of text entered by a user. The button is disabled until at least 2 characters are entered. OnEnter will not reload the dynamic until the test matches the length.
Copy
New-UDCard -Title "Search" -Style @{height = 850 } -Content {
New-UDTextbox -Id 'UsernameBox' -Label "Initials or Name" -OnEnter {
if ($EventData.Length -gt 2)
{
Sync-UDElement -Id 'SearchForUserValidationID'
}
} -OnChange {
$Disabled = (Get-UDElement -Id 'UsernameBox').value.Length -lt 2
Set-UDElement -Id 'search' -Properties @{
disabled = $Disabled
}
}
New-UDButton -OnClick {
Sync-UDElement -Id 'SearchForUserValidationID'
} -Text "Search" -Id 'search' -Disabled
New-UDDynamic -Id 'SearchForUserValidationID' -Content {
$UsernameBoxValue = (Get-UDElement -Id 'UsernameBox').value
New-UDTypography $UsernameBoxValue
} -LoadingComponent {
New-UDProgress
New-UDTypography -Text "Loading users..."
}
}
[PreviousDynamic Select Dropdown](https://docs.powershelluniversal.com/v4-beta/samples/apps/dynamic-select-dropdown)
[NextTree View Font Size](https://docs.powershelluniversal.com/v4-beta/samples/apps/tree-view-font-size)
Last updated 1 year ago
Was this helpful?
---
# Tree View Font Size | PowerShell Universal
In this example, we use UDStyle to change the font size of the tree item labels. You can view a full list of CSS classes for the [tree view here](https://mui.com/material-ui/api/tree-item/#css)
.

Copy
New-UDStyle -Content {
New-UDTreeView -Id "Tree1" -Expanded -Node {
New-UDTreeNode -Name "Pre-Project" -Children {
New-UDTreeNode -Name "Recorded Walkthrough of Process"
}
New-UDTreeNode -Name "Project Kick-Off" -Children {
New-UDTreeNode -Name "Create project kickoff slide deck"
New-UDTreeNode -Name "Verify Development Environment" -Children {
New-UDTreeNode -Name "Verify client VPN connectivity"
New-UDTreeNode -Name "Verify client internal network access"
New-UDTreeNode -Name "Verify development Windows Device"
}
}
} -Style @{
"width" = 800
}
} -Style ".MuiTreeItem-label { font-size: 25px }"
[PreviousTextbox Length Validation](https://docs.powershelluniversal.com/v4-beta/samples/apps/textbox-length-validation)
[NextSQL Data Grid](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid)
Last updated 1 year ago
Was this helpful?
---
# SQL Data Grid | PowerShell Universal
This example uses `Invoke-DbaQuery` from dbatools to query and update data in a SQL database. It implements paging, sorting and filtering via the data grid's `-LoadRows` event handler. It also renders buttons within the table that updates the database based on selections.
Additionally, bulk actions are performed using checkbox selection.
This example requires the following table.
Copy
CREATE TABLE [dbo].[Certificates](
[CertificateId] [int] NULL,
[Decision] [varchar](255) NULL,
[UserName] [varchar](255) NULL,
[GroupName] [varchar](255) NULL,
[AppName] [varchar](255) NULL
) ON [PRIMARY]
The data grid is defined within a dynamic region with some basic properties.
Copy
New-UDDynamic -Id "DynamicTable" {
New-UDDataGrid -ShowPagination -PageSize 10 -RowsPerPageOptions @(10, 25, 50, 100, 200) -CheckboxSelection -LoadRows {
The `-LoadRows` event handler does much of the work but custom columns also provide an avenue for updating the database. We'll break down this example below.
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#columns)
Columns
The columns used in this example are basic, aside from a decision column that is used to update the SQL database.
The basic columns to display look like this. Properties that are returned from the SQL query will be available in render methods but will not be displayed.
Copy
New-UDDataGridColumn -HeaderName 'User' -Field 'UserName' -Filterable -Sortable -Description 'UserName'
New-UDDataGridColumn -HeaderName 'Group' -Field 'GroupName' -Filterable -Sortable
New-UDDataGridColumn -HeaderName 'App' -Field 'AppName' -Filterable -Sortable
We will implement a complex column to update the SQL database. The `$EventData` variable will include the entire row's data. We can use this data to render buttons based on its state. If the certificate is approved, we will create green buttons. If the certificate is revoked, we will create red buttons. Clicking the buttons will run an UPDATE command and then reload the dynamic region.
Copy
New-UDDataGridColumn -HeaderName 'Decision' -Field 'Decision' -MinWidth 300 -Render {
New-UDDynamic -Id $EventData.CertificateId -Content {
function New-DecisionButton {
param(
$Text,
$Icon,
$Style,
$CertificateId,
$Decision
)
New-UDButton -Text $Text -Icon $Icon -Style $Style -OnClick {
$Session:updateButton = $true
$Query = @"
UPDATE Certificates
SET Decision = $Decision
WHERE CertificateId = $CertificateId;
"@
Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query $Query
Sync-UDElement -Id $CertificateId
} -ShowLoading
}
if ($Session:updateButton) {
$item = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query ('SELECT * FROM [dbo].[Certificates] WHERE CertificateId = {0}' -f $EventData.CertificateId)
$EventData.Decision = $item.Decision
$Session:updateButton = $false
}
if ($EventData.Decision -eq 1) {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApprove -Style $Page:BtnGreenApprove -CertificateId $EventData.CertificateId -Decision 'NULL'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevokeNeutral -Style $Page:BtnWhiteRevoke -CertificateId $EventData.CertificateId -Decision '0'
}
elseif ($EventData.Decision -eq 0) {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApproveNeutral -Style $Page:BtnWhiteApprove -CertificateId $EventData.CertificateId -Decision '1'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevoke -Style $Page:BtnRedRevoke -CertificateId $EventData.CertificateId -Decision 'NULL'
}
else {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApproveNeutral -Style $Page:BtnWhiteApprove -CertificateId $EventData.CertificateId -Decision '1'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevokeNeutral -Style $Page:BtnWhiteRevoke -CertificateId $EventData.CertificateId -Decision '0'
}
}
}
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#filtering)
Filtering
Filtering is performed by accessing the `$EventData` variable (assigned to `$Context` in this example). Filters are available as a property of the context. Filters also include the logic operator used. This will be a and or or operator. We construct a SQL where expression and populate a hashtable of parameters.
Copy
$SqlFilter = ""
$Parameters = @{}
if ($Context.Filter.Items.Count -gt 0) {
$count = 1
$ParameterName = "P$count"
foreach ($filter in $Context.Filter.Items) {
if ($count -gt 1) {
$SqlFilter += " $($Context.Filter.logicOperator) "
}
else {
$SqlFilter += " WHERE "
}
$Value = $Filter.Value
switch ($filter.Operator) {
"contains" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE CONCAT('%', @$ParameterName, '%') " }
"equals" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) = @$ParameterName " }
"startsWith" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE CONCAT(@$ParameterName, '%') " }
"endsWith" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE CONCAT('%', @$ParameterName) " }
"isAnyOf" {
$Value = $Value -join ','
$SqlFilter += " $(ConvertTo-ProperCase $filter.Field) IN (SPLIT_STRING(@$ParameterName)) "
}
"isempty" { $SqlFilter += " TRIM ($(ConvertTo-ProperCase $filter.Field)) IS NULL " }
"isnotempty" { $SqlFilter += " TRIM ($(ConvertTo-ProperCase $filter.Field)) IS NOT NULL " }
"notequals" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) != @$ParameterName " }
"notcontains" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) NOT LIKE CONCAT('%', @$ParameterName,'%') " }
}
$Parameters[$ParameterName] = $Value
$count += 1
}
}
The `ConvertTo-ProperCase` function adjusts the field name, which will be lower case, into the correct case used for the SQL server columns.
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#paging)
Paging
Paging data is also sent via the context. We can calculate the offset and page size using the following code.
Copy
$PageSize = $Context.PageSize
$Offset = $Context.Page * $PageSize
$sqlPage = "OFFSET $Offset ROWS FETCH NEXT $($Context.PageSize) ROWS ONLY;"
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#sorting)
Sorting
Columns used for sorting and their direction are also included in the context. This example uses single column sorting but the sort value is an array if multi-column sort is enabled.
Copy
if ($Context.Sort[0].field -ne $null) {
$sqlSort = "ORDER BY $(ConvertTo-ProperCase $Context.Sort[0].field) $($Context.Sort[0].sort) "
}
else {
$sqlSort = "ORDER BY (SELECT NULL)"
}
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#execution)
Execution
Once we have constructed the SQL query portions and the parameters from the context, we can invoke our query. First, we need to get a total count of rows.
Copy
$Query = '{0} {1}' -f $Query, "$SqlFilter $sqlSort $sqlPage"
$Count = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -As SingleValue -Query "SELECT COUNT(*) as count FROM dbo.Certificates $SqlFilter" -SqlParameter $Parameters
Once we have our count, the next step is to run the query. We return the rows as PSObjects. We need to format the return data to include the rows and the count.
Copy
$Data = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -As PSObjectArray -Query $Query -SqlParameter $Parameters
@{
rows = [Array]$Data
rowCount = $Count
}
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#bulk-actions)
Bulk Actions
Using the selection feature of the data grid, we can record the row selections and then perform bulk actions using a select dropdown.
The first step is to store the selections in session state. The `$EventData` variable of `OnSelectionChanged` is a list of the IDs of the rows. The data grid requires an ID to be defined for each row. If no ID property is found on a row, a random one is generated. Since we want deterministic selections, we use the CertificateID property as an ID in the select to allow for us to use that in queries. Below we store the selected IDs in a session variable and update a label for the select dropdown.
Copy
-OnSelectionChange {
$Session:Selections = $EventData
if ($Session:Selections.Count -le 0) {
$Page:TickedCount = ''
}
else {
$Page:TickedCount = ' ({0})' -f $Session:Selections.Count
}
Sync-UDElement -Id 'DropDownDynamic'
}
The select drop down uses the selections and then issues an UPDATE command for each of this. This could be optimized to execute a single command with a list of IDs. Once the code the OnChange is run, the table is updated and the drop down is refreshed.
Copy
New-UDDynamic -Id "DropDownDynamic" {
New-UDSelect -Id 'DropDown' -DefaultValue 'Bulk Decisions' -Option {
New-UDSelectOption -Name "Bulk Decisions$Page:TickedCount" -Value "Bulk Decisions"
New-UDSelectOption -Name 'Approve' -Value 'Approve'
New-UDSelectOption -Name 'Revoke' -Value 'Revoke'
} -OnChange {
$Choice = $EventData
$DecisionBit = if ($Choice -eq 'Approve') { 1 } else { 0 }
$Selected = $Session:Selections
# Show-UDToast ('{0}' -f $Session:Selections | Out-String) -Persistent
foreach ($Row in $Selected) {
$Query = @"
UPDATE Certificates
SET Decision = $DecisionBit
WHERE CertificateId = $Row;
"@
Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query $Query
}
Start-Sleep -Seconds 1
$Page:TickedCount = ''
$Session:Selection = @()
Sync-UDElement -Id 'DropDownDynamic'
Sync-UDElement -Id 'DynamicTable'
}
}
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#demo)
Demo
Below is a demo of this app.
Demo of SQL Data Grid
###
[](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid#complete-example)
Complete Example
The entire implementation of the app can be found below.
Copy
New-UDApp -Content {
$Session:Selections = @()
#endregion ID Verification and Database Connection
#region Button and Chip Values and Styles
$Session:SaveBtnClickedFromOpen = $false
$Session:SaveBtnClickedFromReview = $false
$Session:ChipLabelUnderOpen = ''
$Session:ChipLabelUnderReview = ''
# White
$Page:BtnWhiteApprove = @{'background-color' = '#FFFFFF'; 'color' = '#717171'; Width = "90px"; Height = "28px"; 'margin-left' = '0px'; 'margin-right' = '2px' }
$Page:BtnWhiteRevoke = @{'background-color' = '#FFFFFF'; 'color' = '#717171'; Width = "90px"; Height = "28px"; 'margin-left' = '2px'; 'margin-right' = '0px' }
# Green
$Page:BtnGreenApprove = @{'background-color' = '#00842b'; 'color' = '#FFFFFF'; Width = "90px"; Height = "28px"; 'margin-left' = '0px'; 'margin-right' = '2px' }
# Red
$Page:BtnRedRevoke = @{'background-color' = '#EB0A1E'; 'color' = '#FFFFFF'; Width = "90px"; Height = "28px"; 'margin-left' = '2px'; 'margin-right' = '0px' }
# Modal
$Page:BtnWhiteModal = @{'background-color' = '#FFFFFF'; 'color' = '#717171'; Width = "10px"; Height = "28px"; 'margin-left' = '5px'; 'margin-right' = '0px'; 'min-width' = '10px' }
$Page:IconModal = New-UDIcon -Icon 'bars' -Color '#717171' -Title 'Approve' -Solid
$Page:IconApproveNeutral = New-UDIcon -Icon 'thumbs-up' -Color '#717171' -Title 'Approve' -Solid
$Page:IconApprove = New-UDIcon -Icon 'thumbs-up' -Color '#FFFFFF' -Title 'Approve' -Solid
$Page:IconRevokeNeutral = New-UDIcon -Icon 'thumbs-down' -Color '#717171' -Title 'Revoke' -Solid
$Page:IconRevoke = New-UDIcon -Icon 'thumbs-down' -Color '#FFFFFF' -Title 'Revoke' -Solid
$Page:TextApprove = 'Approve'
$Page:TextRevoke = 'Revoke'
#endregion Button and Chip Values and Styles
#region CSS Styles
New-UDHtml -Markup ''
#endregion CSS Styles
# Adding line breaks to push the content down
New-UDHtml -Markup '
' # Open container div
#region Grid Container (2) Dropdown and Button
New-UDGrid -Container -Content {
New-UDPaper -Elevation 1 -Content {
#endregion Grid Item (2) Dropdown and Button
#region Grid Item (2.1) Dropdown and Button
New-UDGrid -Item -ExtraSmallSize 3 -Content {
#endregion Grid Item (2.1) Dropdown and Button
#region Dropdown Select
New-UDDynamic -Id "DropDownDynamic" {
New-UDSelect -Id 'DropDown' -DefaultValue 'Bulk Decisions' -Option {
New-UDSelectOption -Name "Bulk Decisions$Page:TickedCount" -Value "Bulk Decisions"
New-UDSelectOption -Name 'Approve' -Value 'Approve'
New-UDSelectOption -Name 'Revoke' -Value 'Revoke'
} -OnChange {
$Choice = $EventData
$DecisionBit = if ($Choice -eq 'Approve') { 1 } else { 0 }
$Selected = $Session:Selections
# Show-UDToast ('{0}' -f $Session:Selections | Out-String) -Persistent
foreach ($Row in $Selected) {
$Query = @"
UPDATE Certificates
SET Decision = $DecisionBit
WHERE CertificateId = $Row;
"@
Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query $Query
}
Start-Sleep -Seconds 1
$Page:TickedCount = ''
$Session:Selection = @()
Sync-UDElement -Id 'DropDownDynamic'
Sync-UDElement -Id 'DynamicTable'
}
}
}
#endregion Dropdown Select
}
}
#region Grid Container (3) Table
New-UDGrid -Container -Content {
#endregion Grid Container (3) Table
#region Grid Item (3.1) Table
New-UDGrid -Item -ExtraSmallSize 12 -Content {
New-UDPaper -Elevation 1 -Content {
#endregion Grid Item (3.1) Table
#region Table + Filter and Sorts
New-UDDynamic -Id "DynamicTable" {
New-UDDataGrid -ShowPagination -PageSize 10 -RowsPerPageOptions @(10, 25, 50, 100, 200) -CheckboxSelection -LoadRows {
function ConvertTo-ProperCase {
param($Field)
switch ($Field) {
"username" { "UserName" }
"groupname" { "GroupName" }
}
}
$Context = $EventData
$SqlFilter = ""
if ($Context.Filter.Items.Count -gt 0) {
$count = 1
foreach ($filter in $Context.Filter.Items) {
if ($count -gt 1) {
$SqlFilter += " $($Context.Filter.logicOperator) "
}
else {
$SqlFilter += " WHERE "
}
switch ($filter.Operator) {
"contains" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE '%$($filter.Value)%' " }
"equals" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) = '$($filter.Value)' " }
"startsWith" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE '$($filter.Value)%' " }
"endsWith" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) LIKE '%$($filter.Value)' " }
"isAnyOf" {
$count = 1
foreach ($val in $filter.Value) {
if ($count -gt 1) {
$list += ", '$val'"
}
else {
$list += "'$val'"
}
$count += 1
}
$SqlFilter += " $(ConvertTo-ProperCase $filter.Field) IN ($($list)) "
}
"isempty" { $SqlFilter += " TRIM ($(ConvertTo-ProperCase $filter.Field)) IS NULL " }
"isnotempty" { $SqlFilter += " TRIM ($(ConvertTo-ProperCase $filter.Field)) IS NOT NULL " }
"notequals" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) != '$($filter.Value)' " }
"notcontains" { $SqlFilter += " $(ConvertTo-ProperCase $filter.Field) NOT LIKE '%$($filter.Value)%' " }
}
$count += 1
}
}
$PageSize = $Context.PageSize
# Calculate the number of rows to skip
$Offset = $Context.Page * $PageSize
#endregion Table + Filter and Sorts
#region Create Table Query Herestring
$Query = @"
SELECT
CertificateId,
CertificateId as id,
Decision,
GroupName,
UserName,
AppName
FROM
dbo.Certificates
"@
#endregion Create Table Query Herestring
#region Table Construct Database Query with `Where`, `Paging`, and `Count`
if ($Context.Sort[0].field -ne $null) {
$sqlSort = "ORDER BY $(ConvertTo-ProperCase $Context.Sort[0].field) $($Context.Sort[0].sort) "
}
else {
$sqlSort = "ORDER BY (SELECT NULL)"
}
$sqlPage = "OFFSET $Offset ROWS FETCH NEXT $($Context.PageSize) ROWS ONLY;"
$Query = '{0} {1}' -f $Query, "$SqlFilter $sqlSort $sqlPage"
$Count = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -As SingleValue -Query "SELECT COUNT(*) as count FROM dbo.Certificates $SqlFilter"
Show-UDToast $Query -Persistent
#endregion Table Construct Database Query with `Where's` and `Paging`
#region Query the Database and Pass `$Session:Data` to Out-UDTableData
$Session:Data = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -As PSObjectArray -Query $Query
@{
rows = [Array]$Session:Data
rowCount = $Count
}
#endregion Query the Datbase and Pass `$Session:Data` to Out-UDTableData
#region Table Columns
} -Columns @(
New-UDDataGridColumn -HeaderName 'User' -Field 'UserName' -Filterable -Sortable -Description 'UserName'
New-UDDataGridColumn -HeaderName 'Group' -Field 'GroupName' -Filterable -Sortable
New-UDDataGridColumn -HeaderName 'App' -Field 'AppName' -Filterable -Sortable
New-UDDataGridColumn -HeaderName 'Decision' -Field 'Decision' -MinWidth 300 -Render {
New-UDDynamic -Id $EventData.CertificateId -Content {
function New-DecisionButton {
param(
$Text,
$Icon,
$Style,
$CertificateId,
$Decision
)
New-UDButton -Text $Text -Icon $Icon -Style $Style -OnClick {
$Session:updateButton = $true
$Query = @"
UPDATE Certificates
SET Decision = $Decision
WHERE CertificateId = $CertificateId;
"@
Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query $Query
Sync-UDElement -Id $CertificateId
} -ShowLoading
}
if ($Session:updateButton) {
$item = Invoke-DbaQuery -SqlInstance '(localdb)\MSSQLLocalDB' -Database PSU -Query ('SELECT * FROM [dbo].[Certificates] WHERE CertificateId = {0}' -f $EventData.CertificateId)
$EventData.Decision = $item.Decision
$Session:updateButton = $false
}
if ($EventData.Decision -eq 1) {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApprove -Style $Page:BtnGreenApprove -CertificateId $EventData.CertificateId -Decision 'NULL'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevokeNeutral -Style $Page:BtnWhiteRevoke -CertificateId $EventData.CertificateId -Decision '0'
}
elseif ($EventData.Decision -eq 0) {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApproveNeutral -Style $Page:BtnWhiteApprove -CertificateId $EventData.CertificateId -Decision '1'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevoke -Style $Page:BtnRedRevoke -CertificateId $EventData.CertificateId -Decision 'NULL'
}
else {
New-DecisionButton -Text 'Approve' -Icon $Page:IconApproveNeutral -Style $Page:BtnWhiteApprove -CertificateId $EventData.CertificateId -Decision '1'
New-DecisionButton -Text 'Revoke' -Icon $Page:IconRevokeNeutral -Style $Page:BtnWhiteRevoke -CertificateId $EventData.CertificateId -Decision '0'
}
}
}
#region Table OnRowSelection
) -OnSelectionChange {
$Session:Selections = $EventData
if ($Session:Selections.Count -le 0) {
$Page:TickedCount = ''
}
else {
$Page:TickedCount = ' ({0})' -f $Session:Selections.Count
}
Sync-UDElement -Id 'DropDownDynamic'
}
}
}
}
}
#endregion Table OnRowSelection
}
}
}
}
[PreviousTree View Font Size](https://docs.powershelluniversal.com/v4-beta/samples/apps/tree-view-font-size)
[NextChangelog](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog)
Last updated 1 year ago
Was this helpful?
---
# Extension Changelog | PowerShell Universal
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.2.3-5-21-2024)
4.2.3 - 5/21/2024
-------------------------------------------------------------------------------------------------------------------------
* Added support for version 5 of PowerShell Universal
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.2.2-5-8-2024)
4.2.2 - 5/8/2024
-----------------------------------------------------------------------------------------------------------------------
* Fixed an issue where an error would be thrown during extension activation
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.2.1-12-8-2023)
4.2.1 - 12/8/2023
-------------------------------------------------------------------------------------------------------------------------
* Fixed an issue where updating dashboard or pages would cause issues if the service was restarted while the extension was activated.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.2.0-12-6-2023)
4.2.0 - 12/6/2023
-------------------------------------------------------------------------------------------------------------------------
* Added remote debugger support (requires PSU 4.2.6 or later)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.1.0-9-12-2023)
4.1.0 - 9/12/2023
-------------------------------------------------------------------------------------------------------------------------
* Added support for creating and editing app pages
* Added support for app terminals
* Added support for viewing app sessions and tabs
* Added support viewing modules
* Added support for creating and editing custom modules
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.0.2-6-20-2023)
4.0.2 - 6/20/2023
-------------------------------------------------------------------------------------------------------------------------
* Fixed an issue working with multiple connections
* Fixed an issue with loading job output
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.0.1-6-13-2023)
4.0.1 - 6/13/2023
-------------------------------------------------------------------------------------------------------------------------
* Fixed an issue where the Configurations node would not work properly with v4
[](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog#id-4.0.0-6-13-2023)
4.0.0 - 6/13/2023
-------------------------------------------------------------------------------------------------------------------------
* Added support for PSU v4
* Remove Dashboard Frameworks and Components
[PreviousChangelog](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog)
Last updated 1 year ago
Was this helpful?
---
# What's New in v5? | PowerShell Universal
[](https://docs.powershelluniversal.com/whats-new-in-v5#new-admin-console)
New Admin Console
-------------------------------------------------------------------------------------------------
The admin console has been rebuilt using Blazor for ASP.NET. The look and feel are the same but more tightly associated with the backend Universal platform.
[](https://docs.powershelluniversal.com/whats-new-in-v5#portal)
Portal
---------------------------------------------------------------------------
The [PowerShell Universal Portal](https://github.com/ironmansoftware/universal-docs/blob/v5/broken-reference/README.md)
provides a simple-to-use access point for consumers of PSU resources. You can assign resources by role, and they will be grouped by tags in a searchable interface without the complexities of the admin console.
###
[](https://docs.powershelluniversal.com/whats-new-in-v5#pages-and-widgets)
Pages and Widgets
Portal [Pages](https://docs.powershelluniversal.com/portal/portal-pages)
and [Widgets](https://docs.powershelluniversal.com/portal/portal-widgets)
provide easy-to-use UI components that you can visually position on pages, which can be assigned to roles. Widgets are built using Blazor and PowerShell accept parameters, and they are interactive.
[](https://docs.powershelluniversal.com/whats-new-in-v5#powershell-universal-gallery)
PowerShell Universal Gallery
-----------------------------------------------------------------------------------------------------------------------
The PowerShell Universal Gallery is now integrated directly in PowerShell Universal. Access pre-built solutions for your PowerShell Universal environment.
You can view the [Gallery repository here](https://github.com/ironmansoftware/gallery)
.
[](https://docs.powershelluniversal.com/whats-new-in-v5#granular-permissions)
Granular Permissions
-------------------------------------------------------------------------------------------------------
Authorization within the platform is now configured via a [granular permission system](https://docs.powershelluniversal.com/security/enterprise-security/permissions)
that controls which users have access to which resources. This also includes new roles for specific feature groups, so administrators do not need to configure privileges for every scenario.
[](https://docs.powershelluniversal.com/whats-new-in-v5#postgresql-support)
PostgreSQL Support
---------------------------------------------------------------------------------------------------
PostgreSQL is now supported as a persistence store. PostgreSQL is open source and free.
[](https://docs.powershelluniversal.com/whats-new-in-v5#updated-runtimes)
Updated Runtimes
-----------------------------------------------------------------------------------------------
PowerShell Universal v5 is built on .NET 9 and PowerShell 7.5.
[](https://docs.powershelluniversal.com/whats-new-in-v5#grpc-cmdlets)
gRPC Cmdlets
---------------------------------------------------------------------------------------
The Universal module now uses gRPC for all communication with the system. gRPC is an interprocess communication technology that is fast and runs over HTTP. By unifying on a single technology, the cmdlets now take advantage of all the granular privileges and help reduce technical debt in the platform.
[](https://docs.powershelluniversal.com/whats-new-in-v5#windows-powershell-5.1-and-powershell-7-environments)
Windows PowerShell 5.1 and PowerShell 7 Environments
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Agent environment has been replaced with Windows PowerShell 5.1 and PowerShell 7 environments. These environments host the PowerShell engine, but they allow for better control of assembly loading to ensure more modules are compatible with PowerShell Universal.
[PreviousAbout](https://docs.powershelluniversal.com/)
[NextGet Started](https://docs.powershelluniversal.com/get-started)
Last updated 3 months ago
Was this helpful?
---
# Changelog | PowerShell Universal
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#downloads)
[Downloads](https://ironmansoftware.com/release/powershell-universal)
-----------------------------------------------------------------------------------------------------------------------------------------------------------
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.5-7-25-2025)
4.5.5 - 7/25/2025
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#cve)
CVE
* \[CVE-2025-54552\] - Apps Docs > Variables includes database connection string with plain text password [#5026](https://github.com/ironmansoftware/powershell-universal/issues/5026)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.4-6-3-2025)
4.5.4 - 6/3/2025
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis)
APIs
* \[4.5.3\] Restarting API Button Not Available in One Way Git Sync [#4704](https://github.com/ironmansoftware/powershell-universal/issues/4704)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps)
Apps
* Fixed an issue with the Sync-UDElement docs [#4443](https://github.com/ironmansoftware/powershell-universal/issues/4443)
* Add Excel Filter Pattern to select more than on filter to New-UDTableColumn -FilterType [#4694](https://github.com/ironmansoftware/powershell-universal/issues/4694)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation)
Automation
* Added Running to job status filter selector [#4534](https://github.com/ironmansoftware/powershell-universal/issues/4534)
* Fixed an issue displaying error message from Invoke-PSUScript [#4563](https://github.com/ironmansoftware/powershell-universal/issues/4563)
* \[4.5.2\] Editing schedule results in invalid parameter when using ValidateSet [#4450](https://github.com/ironmansoftware/powershell-universal/issues/4450)
* AppToken with Reader role can archive jobs [#4755](https://github.com/ironmansoftware/powershell-universal/issues/4755)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#module)
Module
* Added -AsObject to Get-PSUJobOutput [#4496](https://github.com/ironmansoftware/powershell-universal/issues/4496)
* Parameter defined multiple times when calling New-PSUSchedule [#4359](https://github.com/ironmansoftware/powershell-universal/issues/4359)
* Added Add-PSUComputerTag\\Remove-PSUComputerTag
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.3-2-27-2025)
4.5.3 - 2/27/2025
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-1)
APIs
* Built-in variables are now read-only
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#admin-console)
Admin Console
* Fixed an issue where Executor and Reader roles could not view scripts (#4302, #3486)
* Fixed an issue with the re-run job button not populating the correct job parameters (#4303)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-1)
Automation
* Fixed an error thrown when running scripts (#4235)
* Added -DefaultScriptListView to Set-PSUSettings (#4204)
* Fixed an issue with one-time schedules in schedules.ps1 (#4428)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.2-1-29-2025)
4.5.2 - 1/29/2025
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#cve-1)
CVE
* [Fixed a directory traversal issue with Published Folders (CVE TBD)](https://docs.powershelluniversal.com/changelogs/cves#cve-tbd-1-29-2025-information-disclosure)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#installer)
Installer
* Fixed an issue where the installer would log the service account in plain text (#4246)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.1-1-15-2025)
4.5.1 - 1/15/2025
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-2)
APIs
* Fixed an issue with event hub client reconnect (#4126)
* Fixed an issue with endpoint paths (#4194)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-1)
Apps
* Fixed an issue with New-UDDataGrid quick filters (#3951)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-2)
Automation
* Fixed an issue creating scripts with periods in the name (#4077)
* Fixed an issue with multiple default values for string array parameters (#4181)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform)
Platform
* Fixed an issue with -SessionTimeout not being honored (#4175)
* Added error script stack trace to logs (#4198)
* Fixed an issue with the file system watcher and apps without file paths (#4166)
* Fixed an issue with Revoke-PSUAppToken (#4205)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.5.0-12-10-2024)
4.5.0 - 12/10/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-3)
APIs
* Added support for API parameter sets (#3798)
* Fixed an issue where event hub connections didn't list the remote computer name (#3980)
* Fixed an issue with event hub client logging
* Added automatic reconnect to event hub client
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-2)
Apps
* New-UDTooltip now sets a CSS class name based on the type of tooltip (#3899)
* Removed the need to call Invoke-UDEndpoint with -Session for it to work (#2139)
* Fixed an issue setting default app theme (#3943)
* Fixed an issue with the admin console logged out page (#4090)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-3)
Automation
* Fixed an issue copying pipeline output (#3825)
* Added -Silent to Invoke-PSUScript and Wait-PSUJob
* Fixed an issue with grooming child jobs (#3884)
* Fixed an issue with Wait-PSUJob returning duplicate output (#4013)
* Fixed an issue where Get-PSUJob would not include the identity or parameters (#4063)
* Fixed an issue where module scripts would disappear when adding\\removing other scripts (#4112)
* Fixed an issue with module scripts and Script Base Folder (#4092)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-1)
Platform
* Fixed an issue where the Reader role could clear logs (#3880)
* Fixed an issue where errors in configuration files could cause them to disappear (#3850)
* Fixed an issue with case sensitivity and logging target scopes (#3998)
* Fixed an issue where the service could crash if losing connection to the database (#4012)
* Fixed an issue where licenses would duplicate when installed as an environment variable (#3984)
* Fixed an issue with variable types when stored in the database (#4113)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.4.1-10-1-2024)
4.4.1 - 10/1/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-4)
APIs
* Fixed an issue with OpenAPI docs default value for properties (#3430)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-3)
Apps
* Added example to New-UDEditor (#3410)
* Added -PreventCollapse to New-UDTreeView (#2252)
* Fixed an issue were logging out in a nested IIS site would redirect to the root site (#3229)
* Fixed Ant Design styling of New-UDExpansionPanel and New-UDTreeView (#3408)
* Fixed a rendering issue with dropdown buttons in a data grid cell (#3327)
* Fixed an issue with New-UDFloatingActionButton not staying in the bottom right corner of the screen (#3720)
* Fixed an issue with -IdentityColumn in New-UDDataGrid (#3832)
* Fixed an issue rendering a nested table.
* Fixed an issue with Nivo chart tool tips (#3718)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-4)
Automation
* Fixed an issue with running one-time schedules in multi-node environments
* Fixed an issue with running scripts over 30 minutes
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#cmdlets)
Cmdlets
* Fixed an issue with New-PSUVariable where it wouldn't create a string secret unless the type was explicitly set (#3656)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#git)
Git
* Fixed an issue with running git pack on an empty repository folder (#3744)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-2)
Platform
* Fixed an issue with the log configuration system (#3261)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.4.0-9-4-2024)
4.4.0 - 9/4/2024
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-4)
Apps
* Fixed an issue with transfer list documentation (#3506)
* Added -Enhanced to New-UDTransferList (#2888)
* Added search box to the right hand list in New-UDTransferList
* Fixed an issue with New-UDTimePicker documentation (#3505)
* Added dark mode support for New-UDEditor (#3502)
* Fixed an issue with New-UDCard -Image example (#3509)
* Fixed an issue with autocomplete formatting (#3570)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-5)
Automation
* Fixed an issue where Invoke-PSUScript -Wait would not return the correct output (#3508)
* Fixed an issue with exception output in Python (#3586)
* Fixed an issue with excessive database growth when using LiteDB (#3672)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-3)
Platform
* Fixed an issue where the ComputerTag collection will fill when using LiteDB (#3671)
* Fixed an issue with background job scheduling when using multi-node configurations
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.3.4-7-29-2024)
4.3.4 - 7/29/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-6)
Automation
* Fixed an issue where an unauthorized error would be shown when using Invoke-PSUScript (#3491)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-5)
Apps
* Fixed an issue with data grid columns not rendering properly (#3443)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-4)
Platform
* Fixed an issue where online module help was not being updated correctly. (#3475)
* Added -MaximumTokenLifetime to settings.ps1
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.3.3-7-22-2024)
4.3.3 - 7/22/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-7)
Automation
* Fixed an issue where calling Get-PSUJob over HTTP would return all child jobs (#3445)
* Moved Script Base Folder setting from Data to Automation (#3447)
* Fixed an issue where new jobs would not pass roles when the logged if user was Policy Defined (#3452)
* Fixed an issue creating schedules on some machines (#3453)
* Fixed an issue where jobs would queue up when all computers were in maintenance mode (#3458)
* Fixed an issue where paused schedules would still run in some circumstances (#3450)
* Fixed an issue where job parameters were not provided in triggers (#3382)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-6)
Apps
* Fixed an issue filtering rows with a space in the field name (#3432)
* Fixed an issue where app pages would not update properly during git sync (#3436)
* Fixed an issue where all apps would reload when anything changed in the repository (#3442)
* Fixed an issue where New-UDEditor image uploads wouldn't work when hosted in a nested IIS site (#3449)
* Fixed an issue loading the app designer (#3454)
* Fixed an issue using filters with number columns in New-UDDataGrid (#3459)
* Added deprecation warning for app designer
* Fixed an issue where it wasn't possible to link to a tab wish a hash in the URL (#3426)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-5)
Platform
* Fixed an issue with the /api/v1/notification POST API (#3462)
* Added a clearer error message to the IIS WebSocket health check when it fails (#3404)
* Fixed an issue with adding files with spaces in the name when using git sync and an external client (#3465)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.3.2-7-2-2024)
4.3.2 - 7/2/2024
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-8)
Automation
* Fixed an issue with Get-PSUJob not returning child jobs (#3433)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-7)
Apps
* Fixed an issue with route parameters in pages (#3434)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-6)
Platform
* Fixed an issue with the author in git commits using external git client (#3431)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.3.1-6-26-2024)
4.3.1 - 6/26/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#api)
API
* Fixed an issue with wildcard rate limits (#3420)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-9)
Automation
* Fixed an issue with the job table becoming locked when grooming jobs when using SQL (#3414)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-8)
Apps
* Fixed an issue with Add-UDElement and New-UDGrid (#3413)
* Fixed an issue with query strings and page navigation (#3355, #3405)
* Fixed an issue with -Options on New-UDTableColumn when using -FilterType autocomplete
* Fixed an issue with the default values for -Views in New-UDDatePicker (#3429)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-7)
Platform
* Added Kestrel\_\_AddServerHeader appsettings option (#3417)
* Fixed an issue grooming log entries
* Fixed an issue where the git service could attempt to pull\\push before the server was completely started
* Added Kestrel\_\_Headers to appsettings.json (#3418)
* Fixed an issue with Get-PSUStats when using -Integrated (#3428)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.3.0-6-17-2024)
4.3.0 - 6/17/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-5)
APIs
* Added -AnonymousApiDocumentation to Set-PSUSettings (#3294)
* Added support for bool parameters in API docs (#3349)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-10)
Automation
* Fixed an issue with module parameters
* Fixed an issue with deleting a terminal (#3358)
* Fixed an issue with error stack traces on the jobs page (#3380)
* Fixed an issue with access controls and scripts (#3385)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps)
PowerShell Apps
* Added -StripedRows to New-UDDataGrid (#3212)
* Added -HeaderFilters to New-UDDataGrid (#3214)
* Added -AutoSizeColumns to New-UDDataGrid (#3296)
* Fixed an issue with Nivo line charts (#3318)
* Added -ArcLinkLabel to New-UDNivoChart (#3293)
* Added -ShowLoading, -LoadingIndicator, and -LoadingPosition to New-UDButtonGroupItem (#3247)
* Fixed an error updating app pages (#3333)
* Added -Sx and -Style to New-UDTabs and New-UDTab
* Fixed an issue when viewing All items in a UDDataGrid (#3334)
* Fixed an issue with case sensitivity in New-UDDataGrid (#3354)
* Added a progress bar to New-UDTab when -Dynamic was used (#3357)
* Fixed an issue with Get-UDTheme where it would not work without any parameters specified (#3363)
* Fixed an issue with UDDataGrid -OnEdit duplicate IDs (#3316)
* Fixed an issue with -ShowQuickFilter in New-UDDataGrid (#3394)
* Added -Sx and -Style to New-UDListItem
* Fixed an issue with boolean header filters in New-UDDataGrid (#3395)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-8)
Platform
* Fixed an issue with commit author when using git and external git clients (#3322)
* Fixed an issue initializing an empty git repository (#3335)
* Fixed an issue that could cause PSU to fail to start properly (#3351)
* Added logging to debugging service
* Fixed an issue with the copy button and published folders in nested IIS sites (#2655)
* Fixed a case-sensitivity issue with the default environment and scripts
* Fixed an issue with SQL connection string exhaustion in multi-node environments.
* Fixed an issue deleting computers (#3364)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.21-5-6-2024)
4.2.21 - 5/6/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-6)
APIs
* Fixed an issue with the roles field in the endpoint docs modal (#3303)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-11)
Automation
* Fixed an issue where error messages would be written twice in the output log (#3305)
* Added -ComputerGroup alias for -Queue on Invoke-PSUScript
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-9)
Platform
* Fixed an issue where the system would open an unnecessary amount of runspaces on startup
* Fixed an issue where runspaces would not always be garbage collected
* Added Jwt\_\_RoleClaimType to appsettings.json to support alternate claim types for roles
* Fixed an issue where configuration scripts would run twice (#3304)
* Fixed an issue where system logs would be verbose if SystemLogLevel was not defined (#3282)
* Fixed an issue with CookiePrefix and BasePath (#3307)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.20-4-30-2024)
4.2.20 - 4/30/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-7)
APIs
* Fixed an issue with the default endpoints.json Swagger documentation (#3287)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-12)
Automation
* Fixed an issue where Invoke-PSUScript -Wait wouldn't work with -UseDefaultCredentials (#3290)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps-1)
PowerShell Apps
* Fixed an issue with including -1 in -RowsPerPageOptions to create an All option (#3240)
* Fixed an issue with default pagination info and New-UDTable -LoadRows (#3228)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-10)
Platform
* Added Authentication:OIDC:AcceptAnyServerCertificate to appsettings.json (#3285)
* Fixed a memory leak
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.19-4-22-2024)
4.2.19 - 4/22/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-8)
APIs
* Fixed an issue where swagger types could show up in multiple documents (#2830)
* Fixed an issue with OpenAPI types in Swagger documents (#2948)
* Fixed an issue with authenticated OpenAPI docs and JWT tokens
* Fixed an issue with OpenAPI docs not reloading types properly (#3193)
* Fixed an issue using tabs in OpenAPI docs (#3180)
* Added error messages when OpenAPI docs fail to load
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-13)
Automation
* Added -InformationAction and -ErrorAction support for Invoke-PSUScript -Wait
* Added script name to the Script \\ Jobs page to support nested jobs (#3272)
* Fixed an issue where showing the timestamp in a job log would cause an error (#3277)
* Fixed an issue where canceled job could get stuck in cancelling state even after a server restart (#3164)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps-2)
PowerShell Apps
* Fixed an issue where scheduled endpoints would not run properly (#3273)
* Fixed an issue using -OnRowStyle, OnRowExpand and -LoadData with New-UDTable (#2848)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-11)
Platform
* Setting git sync interval to 0 will now disable the automatic sync (#3232)
* Fixed an issue with proxy configuration
* Fixed an issue where Remove-PSUVariable would not work in -Integrated mode (#3281)
* Fixed an issue with logs for roles (#3227)
* Fixed an issue with log entry timestamp display in the admin console
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.18-4-15-2024)
4.2.18 - 4/15/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-9)
APIs
* Fixed an issue where the endpoint doc page didn't have an authorize button (#3262)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-14)
Automation
* Fixed an issue viewing job log files.
* Changed the language of the Jobs run stat on the homepage (#3235)
* Fixed an issue where Wait-PSUJob could throw an error based on job output (#3260)
* Fixed an issue where the Get-PSJobOutput cmdlet returned a different data format in v4.2.16 (#3259)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps-3)
PowerShell Apps
* Fixed an issue with how memory usage was reported (#3217)
* Fixed an issue with $Query scoping (#3267)
* Fixed an issue with New-UDTextbox object result formats (#2838)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-12)
Platform
* Fixed an issue with variables stored in the database (#3250)
* New PSU versions are now automatically published to WinGet
* Fixed Set-PSUCache example (#3265)
* Fixed a display issue with app token expiration (#3097)
* Fixed an issue where $UserInfo was not defined in role scripts when using Okta (#3241)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.17-4-8-2024)
4.2.17 - 4/8/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-15)
Automation
* Fixed an issue with Wait-PSUJob and Get-PSUJobOutput (#3249)
* Fixed an issue where jobs may be cancelled if Hangfire reset server status between heartbeats
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-13)
Platform
* Fixed an issue with the logging documentation link (#3236)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.16-4-5-2024)
4.2.16 - 4/5/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-16)
Automation
* Fixed an issue with computer maintenance mode (#3198)
* Fixed a performance problem with job logs in SQL
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps-4)
PowerShell Apps
* Fixed an issue with New-UDDataGridColumn code completion (#3147)
* Fixed an issue with -TimeZone on New-UDTimePicker and New-UDDatePicker (#3126)
* Fixed an issue with spacing of icons in New-UDList (#3173)
* Added -Style to New-UDTransition (#2836)
* Fixed a JavaScript error with New-UDTable (#3234)
* Added -MaximumLength to -New-UDTextbox (#3239)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.15-3-28-2024)
4.2.15 - 3/28/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-17)
Automation
* Fixed an issue with Invoke-PSUScript -Wait and Wait-PSUJob (#3226)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-10)
APIs
* Fixed an issue where roles weren't displayed in the API Docs or the Event Hub modal (#3194)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#powershell-apps-5)
PowerShell Apps
* Added -Hide to New-UDDataGridColumn (#3213)
* Fixed an issue with New-UDDataGrid -ShowQuickFilter and wildcards (\*) (#3211)
* Added -DefaultSortDirection example to docs for New-UDTable (#3216)
* Fixed an issue where apps could be duplicated in multi-node SQL setups (#3102)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-14)
Platform
* Fixed an issue with displaying git commit timestamps (#3206)
* Added an error message when the database encryption key was missing (#3222)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.14-3-22-2024)
4.2.14 - 3/22/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-11)
APIs
* Fixed route matching for variable routes that also match static routes (#3181)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-18)
Automation
* Fixed an issue where app tokens could duplicate due to schedules
* Fixed an issue with the Hide Run As setting (#3187)
* Fixed a performance issue with writing job logs to SQL (#3200)
* Fixed an issue with calling Get-Acl (#2482)
* Fixed an issue loading Microsoft.PowerShell.Utility (#2423)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-9)
Apps
* Fixed an issue where -Style wouldn't apply when using -Disabled with New-UDCheckbox (#2144)
* Fixed an issue where the $Query hashtable was case sensitive (#3169)
* Added -Views to New-UDDatePicker (#2005)
* Fixed an issue with a stepper with no steps (#3188)
* Fixed an issue with the docs app stopping when editing other apps (#3174)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-15)
Platform
* Pinned to the Az.Accounts 2.12.5 version to avoid breaking changes in the module container image
* Fixed an issue with manually reloading dashboards.ps1
* Fixed documentation links (#3178)
* Removed manual garbage collection that could cause a service hang
* Fixed an issue with creating file system items in Linux (#3136)
* Fixed an issue with the Disabled Drives option for Disk Space Health Check (#3137)
* Encrypted git token\\password in database (#3182)
* Fixed an issue with storing the git repository in the database (#3127)
* Fixed an issue with installing modules on a nested IIS site (#3186)
* Fixed an issue with computers being marked offline (#3197)
* Added computer name to notifications in multi-node setups (#3195)
* Computers are now listed under computer groups (#3196)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.13-3-6-2024)
4.2.13 - 3/6/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#api-1)
API
* Fixed an issue where gRPC commands and endpoint could fail when a proxy was configured (#3086)
* Added logging to event hub client (#3114)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-10)
Apps
* Added -PaperStyle to Show-UDModal (#2832)
* Fixed an issue where -Sx would not apply to New-UDTooltip (#3095)
* Added -ValueOptions to New-UDDataGrid
* Fixed an issue where when a PSU node was stopped, apps would stop on all other running nodes (#3119)
* Fixed an issue where nested navigation more than one level deep would not expand when navigating to a page (#3107)
* Fixed an issue with duplicate app pages and deleting app pages (#3120)
* Fixed an issue where page icons might not be shown in the header (#3105)
* Fixed an issue where New-UDRadioGroup -Label would have no affect (#3111)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-19)
Automation
* Fixed an issue where $Job.Script was null in triggers (#3087)
* Added support for -InformationAction on Invoke-PSUScript.
* Improved performance when loading many scripts at startup (#2859)
* Fixed an issue where an invalid app token could be selected when running scripts.
* Fixed an issue where the job page could throw a JavaScript error in the admin console (#3109)
* Fixed an issue where default values for DateTime objects would not be honored in the admin console schedules (#2802)
* Fixed an issue where Get-PSUJob wouldn't work in Windows PowerShell with certain parameter sets (#3138)
* Fixed an issue where One Time schedules would not survive a restart in SQL (#3135)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-16)
Platform
* Fixed an issue where resources in read-only regions could be duplicated (#3082/#3090)
* Fixed a race condition with module discovery that could cause inconsistent IDs and duplicate modules (#3088)
* Fixed an issue where the version field would be empty on the computers page (#3089)
* Fixed an issue when displaying large variable values (#3074)
* Fixed an issue where Computer Groups would not show in the admin console (#3101)
* Fixed an issue where INSTALLPATH wasn't honored when specified on the command line of the MSI (#1494/#3028)
* Fixed an error deleting app tokens in the groom job
* Fixed an issue where git bundles would not work with SQLite (#3108)
* Fixed an issue where computers could fail to delete (#2812)
* Fixed an issue where the ARM64/v8 docker image had the wrong platform set (#1024)
* Fixed an issue launching PSU from the Okta dashboard when using SAML2
* Fixed an issue were a service in a multi-node setup may not start when upgrading (#3103)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.12-2-1-2024)
4.2.12 - 2/1/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-12)
APIs
* Fixed an issue with nested IIS sites and the API tester with variables (#3051)
* Fixed an issue where syntax errors in endpoint docs would cause them to disappear from the admin console (#3056)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-11)
Apps
* Fixed an issue where New-UDChartJS would ignore -Options when using -Line (#2871)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-20)
Automation
* Added Set-PSUSchedule (#3055)
* Fixed an issue where Max Job Memory would roll over if set above 2GB causing all jobs to terminate
* Fixed an issue updating a terminal (#3070)
* Fixed an issue where jobs could be stuck in a running state after finishing successfully
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-17)
Platform
* Fixed an issue where $UserInfo would be $null when using Auth0 and OIDC
* Fixed an issue where basic auth wouldn't correctly apply claims to the user
* Added better reporting of when the admin console is disabled
* Fixed an issue where configuration files would re-load twice when saved
* Fixed an issue where New-PSUVariable wouldn't correctly create PSCredential's in some circumstances
* Fixed an issue where disabling Local Account in an identity wouldn't change the status (#3077)
* Fixed an issue where identities could duplicate when using SQL persistence (#3054)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.11-1-22-2024)
4.2.11 - 1/22/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#api-2)
API
* Fixed an issue where APIs could only return a maximum of 4MB of data when using an external environment
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-21)
Automation
* **CRITICAL:** Fixed an issue where the Server Started trigger could cause PowerShell Universal to fail to start (#3065)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.10-1-20-2024)
4.2.10 - 1/20/2024
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-13)
APIs
* Fixed an issue where $ClaimsPrincipal would be $null in endpoints when using Basic authentication
* Fixed an issue where swagger documentation would show required if Mandatory was set to false (#3040)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-12)
Apps
* Status Description is now displayed when using Write-Progress in an app (#2768)
* Fixed an example in the New-UDDatePicker documentation (#3041)
* Fixed an issue with $AppFullUrl when using HTTPS with the default port (#3013)
* Fixed an issue where New-UDAutocomplete with empty options would return a JavaScript error
* Fixed an issue where New-UDDatePicker would not always send a DateTime object
* Fixed an issue where a UDTransferList with no items would display a JavaScript error (#3048)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-22)
Automation
* Added -RandomDelayMaximum to New-PSUSchedule (#2886)
* Added $Job variable to the Job Timed Out trigger (#2704)
* Fixed an issue where One Time schedules would be deleted before run when using One-Way Git Sync and SQL persistence
* Fixed an issue where canceling a job could result in an exception and the job becoming stuck in a canceling state
* Fixed an issue where the job status sort and filter icons would overlap (#2893)
* Fixed an issue where jobs would still run on computers in maintenance mode (#3034)
* Fixed an issue where jobs listed on a script page wouldn't link properly to a JobRunId (#2852)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-18)
Platform
* Retrying module lookup during startup when it fails due to an internal PowerShell state (#2813)
* Added Run Schedule and Job Diagnostics to the admin console when git one-way and manual mode are enabled (#3032)
* Fixed an issue where -SessionTimeout for New-PSUSetting would not be applied (#2914)
* Fixed an issue where the login page logo would fail to load over HTTP (#3037)
* Fixed an issue where health checks wouldn't be shown on the home page in some cases (#3043)
* Added PowerShell Universal version to the computer table (#3050)
* Removed license check for installing modules from the PowerShell Gallery
* Fixed an issue where updates to authentication methods could update the wrong method and cause authentication to fail (#3033)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.9-1-10-2024)
4.2.9 - 1/10/2024
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-14)
APIs
* Added Event Hub Client installer (#3003)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-13)
Apps
* Fixed an issue where the New-UDButton -Loading would not display properly in the dark theme (#2875)
* Fixed an issue where the UDApp variable is null (#3014)
* Fixed an issue where the create page dialog would clear on refocus (#2725)
* Fixed an issue where $AppFullUrl would not be correct for nested IIS sites (#3013)
* Fixed an issue where refreshing a Dynamic with a Table with an ID wouldn't refresh the table data (#2782)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-23)
Automation
* Fixed an issue expanding errors in the admin console (#3017)
* Fixed an issue where Reader and Execute roles could view the contents of a script by typing in the URL
* Improved the performance of the schedules page when using SQL persistence.
* Fixed an issue where retried jobs would queue forever when using SQL persistence
* Added HangfireWorkerCount configuration option to appsettings.json
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-19)
Platform
* Fixed an error the groom job could fail clearing child jobs when using LiteDB (#3021)
* Added support for local files as admin console login page logos (#2705)
* Fixed warnings on server startup (#3023)
* Libgit2sharp now logs to the system log (#3026)
* Filters for health checks in the admin console (#3016)
* Fixed an issue where Get-PSUComputer -Integrated would return a gRPC error when using SQL persistence (#3018)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.8-1-3-2024)
4.2.8 - 1/3/2024
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-15)
APIs
* Fixed an issue where the API tester in the admin console wouldn't work in a nested IIS site (#3004)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-14)
Apps
* Fixed an issue where -Locale on New-UDDatePicker and New-UDTimePicker had no effect (#2988)
* Added Variables page to live documentation (#2991)
* Added -IgnoreResult to Invoke-UDJavaScript to work around a hang in certain circumstances (#2922)
* Fix issue with New-UDTextbox date hand enter (#3006)
* Fixed an issue with one of the examples for New-UDDataGrid
* Fixed an issue with one of the examples for New-UDForm (#2990)
* Added -DisableArcLinkLabels and -DisableArcLabels to New-UDNivoChart (#2907)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-24)
Automation
* Fixed an issue where the System Event page would show an error in the admin console (#2996)
* Fixed an issue where the job timer wouldn't display days (#3008)
* Fixed an issue where the admin console would display an error viewing a job (#2361)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-20)
Platform
* Fixed an issue where Azure DevOps git repositories could lose there tracking branch when clicking Synchronize Now
* Fixed a warning at startup about Computer Groups (#2989)
* Fixed an issue where the User Name computer tag would duplicate (#2997)
* Changed the default sort direction for Notifications (#3000)
* Fixed an issue with HTTPS certificate thumbprint lookups (#3002)
* Added support for custom computer tags (#2998)
* Fixed an issue where an extra new line character would be added to script scripts when splatting was enabled (#2995)
* Added the git repo link to the git commit page (#2956)
* Partial git commits now perform a git push (#2957)
* Fixed an issue where users could create app tokens for the system account (#3010)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.7-12-18-2023)
4.2.7 - 12/18/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-15)
Apps
* Fixed an issue with -Schema parameter of New-UDForm's example in cmdlet help (#2896)
* Added Start Time and Deploy Time to app information (#2950)
* Added $AppRoot and $AppFullUrl variables (#2928)
* Fixed an issue where integrated apps didn't report memory usage (#2969)
* Value must be unique for New-UDTransferList (#2952)
* Fixed an issue where New-UDMap did not work with Get-UDElement (#2971)
* Fixed an issue where New-UDMap did not work with Add-UDElement (#2973)
* Fix issue with value on date type New-UDTextbox (#2961)
* Fixed an issue where where the PSU icon would not show up in in the app live docs in a nested IIS site (#2953)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-25)
Automation
* Fixed an issue where scheduled jobs run using schedules without a name would not behave properly when filtering scheduled jobs (#2955)
* Fixed an issue where rerunning jobs with date\\time parameters would not populate correctly (#2944)
* Fixed an issue where Get-PSUJob -Id would not return the identity of the user that ran the script (#2945)
* Fixed an issue where the Job Completed trigger would not run on failed jobs (#2967)
* Fixed an issue concurrency issue that could occur when starting jobs using SQL persistence (#2964)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-21)
Platform
* Fixed an issue with SQL errors while grooming jobs with child jobs (#2894)
* Fixed an issue grooming idle terminals instances when the terminal was deleted (#2960)
* Added Delete All Notifications button (#2959)
* Fixed an issue where SQLite logging wouldn't work when using environment variables in the connection string (#2966)
* Added CertificateTypes configuration option for Certificate Authentication (#2985)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.6-12-11-2023)
4.2.6 - 12/11/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-16)
APIs
* Fixed an issue where $Body was not available if param was specified (#2923)
* Fixed an issue where the Roles property didn't populate properly when editing an endpoint in the Admin Console (#2920)
* Fixed an issue where API Docs wouldn't handle basic types property for .INPUT and .OUTPUT (#2935)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-16)
Apps
* Fixed an issue where the live docs page logo wouldn't load properly in a nested site (#2919)
* Fixed an issue where the live docs page would not render properly when a user had many roles (#2919)
* Improved uncached client-side load time (#2926)
* Fixed an issue where apps memory would usage was miscalculated (#2941)
* Fixed an issue where pages would disappear if a PSU module with pages was installed (#2942)
* Fixed an issue where the PSU service could crash when attempting to serialize the results of Get-Service (#2940)
* Added support for custom app and page templates (#2927)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-26)
Automation
* Fixed an issue where the groom job could delete one time schedules before they ran (#2912)
* Removed Suspend from Error Action script property (#2924)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-22)
Platform
* Fixed an issue where not all cookies would be prefixed by the Kestrel \\ CookiePrefix setting (#2846)
* Fixed an issue where git sync could lose its remote tracking branch
* Authentication and Role pages now use the log viewer (#2929)
* Log viewer defaults to text. Setting is now sticky (#2930)
* Fixed an issue where JWT, Cookies and Basic auth would not work against APIs when Windows Auth was enabled (#2254)
* Fixed an issue where PSEditorServices module was missing files
* Fixed an issue where adding Computer Groups wouldn't update in the Admin Console until refreshing the page (#2938)
* Fixed an issue where published folders would not work on Unix systems (#2947)
* Added View Repository and Status buttons on the git commit page (#2917)
* Verified PowerShell 7.4 support (#2860)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.5-12-4-2023)
4.2.5 - 12/4/2023
---------------------------------------------------------------------------------------------------------------
**Known Issues**
* [KB0054 - Git Sync: There is no tracking information for the current branch](https://support.ironmansoftware.com/portal/en/kb/articles/git-sync-there-is-no-tracking-information-for-the-current-branch)
* [KB0055 - Blank Admin Console or No Updates After Upgrade](https://support.ironmansoftware.com/portal/en/kb/articles/kb0055-blank-admin-console-or-no-updates-after-upgrade)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-17)
APIs
* Fixed an issue where endpoint docs would not show the required tag on required parameters
* Fixed an issue where endpoint docs would not show array parameters properly
* Fixed an issue where Connect-PSUEventHub would not work in Windows PowerShell
* Fixed an issue with using basic authentication with endpoints
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-17)
Apps
* Fixed an issue where Write-Progress wouldn't work properly with multiple connected clients (#2881)
* Fixed an issue where apps would not remain running on multi-node systems (#2854)
* Fixed an issue where New-UDUpload data would not be available in New-UDStepper (#2865)
* Fixed an issue where dashboards would not start if they had ps1 files in the pages folder that did not return New-UDPage
* Fixed an issue were the date filter type did not work in New-UDTable (#2898)
* Fixed an issue where New-UDDatePicker and New-UDTimePicker could not be cleared (#2892)
* Fixed an issue where New-UDDatePicker and New-UDTimePicker -TimeZone would have no effect. -TimeZone requires an IANA time zone ID. See https://mui.com/x/react-date-pickers/timezone/#supported-timezones for a list of valid time zones. (#2891)
* Fixed an issue with UDMap not rendering properly (#2535)
* Fixed an issue where New-UDSelect would fail when only a single item was present (#2916)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-27)
Automation
* Fixed an issue where certain views would not show scheduled jobs
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-23)
Platform
* Fixed an issue where old git statuses would not be removed when resetting the git settings (#2884)
* Fixed an issue where /api/v1/cache/keys returned keys with a PSUCache prefix.
* Fixed an issue where logging targets would not honor the minimum level
* Disabled progressive web app for management console
* Fixed an issue where the -Minimal parameter couldn't be specified for environments in the Admin Console (#2908)
* Fixed an issue with the git commit file selector (#2877)
* Fixed an issue with published folders that started with a slash in the path (#2655)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.4-11-24-2023)
4.2.4 - 11/24/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-18)
Apps
* Fixed an issue where Get-UDPage could return pages from the wrong app.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-28)
Automation
* Fixed an issue with the PowerShell serializer when saving schedules with splatting enabled (#2866)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#pages)
Pages
* Fixed an issue with submitting forms on Pages
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-24)
Platform
* Fixed an issue with Windows authentication in IIS when attempting to access the admin console.
* Fixed an issue where creating a new module in the admin console would return the error "Value Cannot Be Null (Parameter ‘s’)"
* Fixed an issue where using the certificate thumb print for a certificate with a subject that didn't start with "CN=" would fail to load the certificate.
* Fixed an issue where New-PSULoggingTarget could not be called remotely.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.3-11-21-2023)
4.2.3 - 11/21/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-29)
Automation
* Fixed an issue where Get-PSUJob would not return scheduled jobs (#2867)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-19)
Apps
* Fixed an issue where nested files changes would not cause an autodeploy (#2863)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-25)
Platform
* Fixed an issue where Windows Auth logins would not work with the admin console
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#desktop)
Desktop
* Fixed an issue where Desktop mode would not start properly.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#known-issues)
Known Issues
* There is a known issue with Windows Auth and IIS that will be resolved in 4.2.4.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.2-11-20-2023)
4.2.2 - 11/20/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-20)
Apps
* Increased max websocket size to fix an issue with Get-UDElement failing on large objects like tables
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-26)
Platform
* Fixed an issue where SAML2 logins would not work with the admin console (#2853)
* Added Kestrel:CookiePrefix setting to allow for multiple instances of PSU to run on the same server without sharing cookies (#2846)
* Fixed an issue where the git commit page would reload every second
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.1-11-16-2023)
4.2.1 - 11/16/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#critical)
Critical
* Security Vulnerability Remote code execution in PowerShell Universal APIs (CVE-TBD) - [More Information](https://blog.ironmansoftware.com/powershell-universal-apis-cve/)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-21)
Apps
* Disabled service worker registration for apps to prevent caching of the index.html file (#2855)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.2.0-11-14-2023)
4.2.0 - 11/14/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-18)
APIs
* Added -Local to Get-PSUEventHubConnection (#2715)
* Added support for calling Send-PSUEvent remotely (#2719)
* Improved API performance
* Added C# API plugin
* Added Set-PSUEndpoint
* Fixed an issue where renaming endpoint paths would not have any effect (#2737)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-22)
Apps
* Added -OnClick to New-UDCard (#2697)
* Removed the Mandatory flag for -Text on New-UDMenuItem (#2685)
* Fix style issue with -Multiple and -Icon on New-UDAutocomplete (#2632)
* Added -Variant to New-UDIconButton (#2363)
* Fixed styling issues with New-UDToggleButton (#2532)
* Get-UDPage -Name now works with Page names and file names (#2543)
* Added -CountDescription and -RowsPerPage to New-UDTableTextOption (#2219)
* Fixed name issues with New-UDSelectGroup (#2701)
* Improved performance of Get-UDElement (#2733)
* Apply -Dense to all sub-list items (#2749)
* Fixed an issue where New-UDDatePicker would return a string rather than a DateTime object (#2716)
* Make New-UDTransferList search case-insensitive (#2729)
* Added -FullHeight to Show-UDModal (#2722)
* Fixed an issue with Out-UDDataGridData where it would not filter properly
* Added -Dense, -LeftTitle, -LeftSubTitle, -RightTitle, -RightSubTitle to New-UDTransferList (#2714)
* Improved App Designer properties layout (#2793)
* Automatic navigation now uses -Title as the link for the navigation link (#2758)
* Improved the performance of New-UDDataGrid checkbox selection
* Added -Wait to Sync-UDElement
* Added -Sx to New-UDSelect
* Fix issue with single char issue on New-UDTextbox (#2800)
* Fix variant when using -Mask on New-UDTextbox (#2807)
* Added app page properties (#2757/#2567)
* Added -Icon to New-UDButtonGroupItem (#2789)
* Added -Color, -Disabled, -FullWidth, -Orientation, -Size, -Sx, and -Variant to New-UDButtonGroup (#2789)
* Added live docs for New-UDButtonGroup (#2789)
* Fixed an issue with New-UDDataGridColumn default values (#2828)
* Fixed an issue where using the logout button would not forward back to the app after logging in again (#2642)
* Added -OnRowStyle and -HeaderStyle to New-UDTable (#156, #758)
* Fixed an issue where Sync-UDElement could throw an exception
* Added -IdentityColumn, -RowHeight, -HideExport and -DisableRowSelectionOnClick to New-UDDataGrid
* Fixed card margin issue (#2801)
* Fixed issue with -ShowLoading with dark themes (#2691)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-30)
Automation
* Added a filter for job status (#2694)
* Added support for minimal job environments
* Added support for hiding scheduled jobs (#2710)
* Fixed an issue with Invoke-PSUScript and SecureString parameters
* Wait-PSUJob now supports -JobId
* Wait-PSUJob now returns pipeline output and terminating errors
* Invoke-PSUScript now supports -WaitTimeout
* Added -Schedule to Get-PSUJob
* Fixed an issue starting terminals in the Agent environment
* Added -Parameters to New-PSUSchedule and updated the serializer to use this format by default
* Fixed an issue where Get-PSUSchedule -Integrated would not return the NextExecutionTime
* Added -Parameters to Invoke-PSUScript
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-27)
Platform
* Added New-PSUHealthCheck and New-PSUHealthCheckResult (#2522)
* Added Conflict Module Health check (#2700)
* Adjusted the authentication re-check on the login page to reduce 401s (#2688)
* Dashboard and API endpoint files are now deleted when the resource is removed. (#2676)
* Added the ability to configure disabled drives for the Drive Space health check (#2476)
* Fixed an issue with overlapping tooltips on the computer delete button (#2707)
* Added reserve proxy plugin (YARP)
* Added OpenTelemetry plugin
* Added reload configuration file dropdown
* Added a minimap toggle to the editor
* Fixed an issue with loading Az.Accounts in PSU
* Updated Swashbuckle NuGet package (##2682)
* Included PSResourceGet GA module and remove pre-release PSGet (#2740)
* PowerShell Universal can now be installed as a Progressive Web App
* Added static PowerShell 7 environment to prevent issues when upgrading the underlying PowerShell version (#2765)
* Fixed an issue with array variables (#2693)
* Fixed an issue where the agent environment wouldn't work on Linux
* Added support for Computer Groups and accompanying cmdlets
* Added -FileEncoding to Set-PSUSetting
* Added Basic authentication
* Added Get-PSUGitSetting, Set-PSUGitSetting and Remove-PSUGitSetting
* Added Merge-PSUGitEdit, Start-PSUGitEdit and Stop-PSUGitEdit
* Added Sync-PSUGit
* Added -Commits, -UncommittedChanges, -EditInProgress to Get-PSUGitStatus
* Fixed an issue with -DefaultRoute on New-PSURole not working with forms authentication
* Modified variable properties (#2778)
* Added Clear-PSUCache
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#deprecated)
Deprecated
* Queues configured in appsettings.json - Replaced with computer groups
* Browser based debugging tools - Replaced with VS Code extension
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.10-11-16-2023)
4.1.10 - 11/16/2023
-------------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#critical-1)
Critical
* Security Vulnerability Remote code execution in PowerShell Universal APIs (CVE-TBD)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.8-10-30-2023)
4.1.8 - 10/30/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-23)
Apps
* Fixed an issue where clicking off the Read-Host dialog would not be treated as a cancel
* Fixed an issue where clicking cancel in PromptForChoice would result in an exception (#2806)
* Fix issue with single char issue on New-UDTextbox (#2800)
* Added $ENV:PSU\_APP\_PAGE\_MAX to allow for customizing the max number of page (tab) states are stored in memory per session, per dashboard.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-31)
Automation
* Fixed an issue where Invoke-PSUScript could throw an exception when -Wait is specified in a non-integrated environment while using SQL persistence
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-28)
Platform
* Added -File to Sync-PSUConfiguration
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.7-10-23-2023)
4.1.7 - 10/23/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-24)
Apps
* Fixed an issue where Read-Host Cancel would return an error when clicking the cancel button (#2769)
* Fixed an issue where dashboards would fail to start or stop with a 500 error
* Fixed an issue with variable scoping in rendered table rows (#2776)
* Fixed an issue where New-UDAutocomplete -Value wouldn't work when -Multiple was specified (#2698)
* Fixed an issue where certain formats of $EventData would return a DateTime rather than the expected string
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-32)
Automation
* Fixed an issue where credential variables with roles could throw an exception when starting a job (#2762)
* Fixed an issue where Invoke-PSUScript -Wait would throw an error (#2777)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-29)
Platform
* Fixed an issue where the secret provider did not honor environment variables (#2753)
* Fixed an issue where logging for roles was not displaying properly (#2766)
* SystemLogLevel now defaults to Information
* Added error handling around PSScriptAnalyzer formatting
* Enabled gRPC logging
* Fixed a file locking issue with configuration files
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.6-10-16-2023)
4.1.6 - 10/16/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-19)
APIs
* Fixed an issue where the $Data variable was not populated.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-25)
Apps
* Fixed an issue where Windows authentication would display as anonymous in User Sessions for apps.
* Fixed an issue where Sync-UDElement + New-UDElement cause event handlers to fail. (#2747)
* Fixed an issue where New-UDDatePicker would return the current day rather than $null when no date was selected. (#2734)
* Fixed an issue where New-UDDatePicker would return a string rather than a DateTime object (#2716)
* Fixed vertical alignment of New-UDAlert -Dense (#2724)
* Fixed an issue where Read-Host would return the previous value if Cancel was clicked the second time
* Fixed an issue where Ok and Cancel would both return an empty string from Read-Host. Now cancel returns $null and Ok returns an empty string.
* Make New-UDTransferList search case-insensitive (#2729)
* $Query is now case-insensitive (#2752)
* Fixed an issue where -Variant fullWidth didn't work on New-UDTabs
* Add a delete pages button and tab to the admin console (#2755)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-33)
Automation
* Fixed an issue where Get-PSUJob -Id-RunId would behave differently depending on where you were running it (#2750)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-30)
Platform
* Adjusted the admin console build to avoid inline JavaScript
* Removed Policy Defined from the App Token Role selector since it is not a valid value for tokens (#2739)
* Fixed an issue where updating git settings would clear out the username and password (#2742)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.5-10-9-2023)
4.1.5 - 10/9/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-20)
APIs
* Improved API performance
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-26)
Apps
* Push -Dense down to children on New-UDList (#2677)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-31)
Platform
* Fixed a concurrency issue during authentication when using SQL persistence that could result in SQL exceptions
* Fixed an issue where SQLite persistence would create an errant file and folder in the repository directory
* Fixed an issue where SQLite persistence did not properly support environment variables.
* Remote access is now supported for developer licenses.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.4-10-2-2023)
4.1.4 - 10/2/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-32)
Platform
* Rolling back a change made to support Az.Accounts in the integrated environment as it was causing problems with OIDC and JWT authentication (#2718)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.3-10-2-2023)
4.1.3 - 10/2/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-34)
Automation
* Fixed an issue where viewing script properties with tags assigned would show a JavaScript error.
* Fixed an issue where the rerun job button wasn't present for jobs with a warning status (#2708)
* Fixed an issue where scripts edited in the admin console wouldn't reload parameters
* Fixed an issue where retrying jobs wouldn't work when using SQL persistence (#2706)
* Fixed an issue where parameter sets would not be available in the create schedule dialog (#2712)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-27)
Apps
* Fixed an issue where the View Code button would not work in the App Designer.
* Fixed an issue where extra lines were added to event handlers in the App Designer.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-33)
Platform
* Fixed an issue where the ModuleRefreshInterval setting would not work after a restart of the service.
* Fixed an issue where Az.Accounts could not be loaded into the integrated environment (#2681)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.2-9-25-2023)
4.1.2 - 9/25/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-28)
Apps
* Fixed an issue where -OnLoading of New-UDPage would not have an affect
* Fixed an issue where New-UDElement would leak event handlers (#2692)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-35)
Automation
* Fixed an issue where saving scripts would be slow if there were many scripts defined
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-34)
Platform
* Fixed the default connection string in the MSI to work with SQLite.
* Fixed an issue with viewing log entries in the admin console when using SQLite.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.1-9-18-2023)
4.1.1 - 9/18/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-29)
Apps
* Fixed an issue where the admin link would not work properly in a nested IIS site (#2672)
* Fixed an issue where Get-UDElement would display errors when a property did not exist instead of returning $null
* Fixed an issue where the date picker would not be visible in dark themes (#2669)
* Fixed an issue where PromptForChoice wouldn't behavior properly when run twice on the same page
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-21)
APIs
* Fixed aan issue where Send-PSUEvent hub did not work out of the integrated environment (#2674)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-35)
Platform
* Fixed an issue where certain roles would forward to a missing page rather than the admin console
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.1.0-9-12-2023)
4.1.0 - 9/12/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-22)
APIs
* Added Get-PSUEventHubConnection
* Added -ConnectionId to Send-PSUEvent
* Send-PSUEvent can now return data when using -ConnectionId
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-30)
Apps
* Adding BackgroundImage and BackgroundRepeat to New-UDPage (#2325)
* Adding Disabled to New-UDSelectOption (#2491)
* Adding md to Size to New-UDIcon (#2528)
* Added -Label to New-UDProgress (#2553)
* Added -OpenInNewWindow to New-UDListItem (#2540)
* Added -Minimum and -Maximum to New-UDTextbox (#2455)
* Fixing issues with Show-UDToast -MessageSize (#1000)
* Fixing issues with Show-UDToast -Icon (#1913)
* Added additional configuration options to apps in the admin console
* Added Show-UDSnackbar\\Hide-UDSnackbar (#2561)
* Fixing issue with New-UDDataGrid pagination (#2546)
* Fixed an issue where row selection in New-UDDataGrid wasn't available in Get-UDElement (#2573)
* Added -OnSelectionChanged to New-UDDataGrid
* Fixed an issue where schema forms -OnSubmit would not run
* Added -DefaultSortColumn and -DefaultSortDirection to New-UDDataGrid (#2011)
* Fix issue with min\\max on New-UDDatePicker (#2580)
* Fixed an issue with New-UDSwitch -LabelPlacement should be start not left (#2601)
* Added Restart and Admin Console links to dashboards of admins (#2362)
* Added Get-UDTheme -Current (#2508)
* Fix New-UDAutocomplete to look at options for defaults (#2583)
* Added -ArgumentList to Sync-UDElement (#1815)
* Clear autocomplete with Set-UDElement (#2631)
* Fixed an issue where row selection wouldn't always work when filtering with New-UDTable (#2630)
* Added -Disabled to New-UDAutocomplete (#2639)
* Fixed an issue where links in New-UDMarkdown didn't follow the theme (#2296)
* Added $TimeZone variable to apps (#2646)
* Added missing New-UDAutoCompleteOption to live docs (#2640)
* Power Managing a dashboard will now do so on all nodes when using SQL Server (#1360)
* Fixed an issue where the nivo chart docs were not present on the live docs (#2640)
* Fixed an issue with -CirclePacking and -TreeMap in New-UDNivoChart
* Fixed an issue with -Heatmap in New-UDNivoChart
* Added New-UDTheme (#2653)
* Fixed an issue where several components (tables, pickers, charts) would not update when using within a UDDynamic (#2661)
* Improved the behavior of New-UDButtonGroup (#2651)
* Fixing issue with New-UDAvatar -Variant not supporting default round (#2633)
* Fixed an issue where New-UDUpload did not work in a nested IIS site (#2657)
* Fixed an issue where autocomplete would fail to render if it was pass a single value that wasn't an array (#2668)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-36)
Automation
* Added Error status for jobs that succeed but have errors
* Added a Create Scheduled button to the Scripts \\ Schedules tab. (#2541)
* Added support for cmdlets in -Command in New-PSUScript (#2605)
* Fixed an issue with editing schedules in the admin console (#2659)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-36)
Platform
* Add configurable git sync timeout (#2466)
* Added git to the linux docker container (#2472)
* Updated the integrated and agent environments to 7.3.6 (#2494)
* Administrator role now defaults to $false (#2492)
* Added a Run Module Discovery button to the module page (#2486)
* Added $RefreshToken to access the OIDC refresh token
* Added support for SQLite
* Updated to Microsoft.Data.SqlClient version 5.1.1
* Added loaded Assemblies to the process view
* Added additional branding settings
* Added Remove-PSUCache
* Added ModuleDiscoveryFrequency to Set-PSUSettings (#2595)
* Added Get-PSUPublishedFolder (#2622)
* Added SystemLogLevel to appsettings.json
* Fixed an issue where the default theme setting would not take effect (#2292)
* The secret variable credential dialog now suggests including the domain in the user name (#2625)
* Fixed an issue where Grant-PSUAppToken would generate tokens with invalid roles besides the first role specified.
* Fixed an issue where modules in the Modules directory were imported into the PSU server during startup
* Fixed an issue with editing modules when a Universal extension module was installed
* Fixed an issue where readonly resources could show up in configuration files
* Added support for PSScriptAnalyzer settings files (#2658)
* Fixed an issue where the module REST API did not work with app tokens.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.12-8-31-2023)
4.0.12 - 8/31/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-37)
Automation
* Fixed an issue where scripts provided by modules would not be visible in folder view
* Fixed an issue where job output could be malformed when storing in SQL causing an error in the admin console (#2644)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.11-8-28-2023)
4.0.11 - 8/28/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-23)
APIs
* Endpoints will now attempt to read form data even if the HTTP client doesn't specify a Content-Type header (#2612)
* Fixed an issue where authenticated event hub clients would not receive events.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-31)
Apps
* Fixed an issue where the app designer would add 2 IDs when the ID of a component was changed (#2589)
* Fixed an issue where the default choice for PromptForChoice would throw an exception (#2607)
* Fixed an issue where Get-UDPage would throw an exception if the page was not found causing the entire app to fail to load (#2610)
* Fixed an issue where UDTreeView selected items were not visible in the default dark theme (#2613)
* Fixed an issue where expired tokens would cause -GrantAppToken to fail to generate a new token
* Fixed an issue where recursive object paths could cause an app crash (#2627)
* Fixed an issue where -OnLoadOptions and -Multiple wouldn't show selections in New-UDAutocomplete (#2604)
* Added -Options to New-UDTableColumn (#1097)
* Fix New-UDAutocomplete to look at options for defaults (#2583)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#pages-1)
Pages
* Fixed an issue where unauthenticated pages would clear out the form data after 3 seconds (#2611)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-37)
Platform
* Fixed an issue where no error was shown when there was a failure to save a translation file (#2618)
* Fixed an issue where database git sync could run into an OutOfMemory exception (#2620)
* Fixed an issue where an exception was thrown while attempting to groom an expired apptoken that was used by a job (#2621)
* Added universal-modules docker image tag (#2624)
* Added Download System Logs button
* Implemented a database recovery feature if the LiteDB database is corrupted
* Resources are now marked readonly in the admin console (#2587)
* Fixed an issue where variables with a role wouldn't show up for admins unless it had the Administrator role
* Fixed an issue with the log viewer not retaining filters when sorting or paging.
* Fixed an issue with the documentation links in the admin console
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.10-8-14-2023)
4.0.10 - 8/14/2023
-----------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-24)
APIs
* Fixed an issue where specifying an invalid environment could cause multiple API to fail to load. Now falls back to integrated and shows a warning (#2591)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-32)
Apps
* Fix issue with min\\max on New-UDDatePicker (#2580)
* Fixed an issue where the MUI X license key was expired
* Fixed an issue with New-UDSwitch -LabelPlacement should be start not left (#2601)
* Breaking: Query string values are now passed in via a $Query dictionary rather than as variables to avoid potential injection issues
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-38)
Automation
* Added -PreformattedJobOutput to Set-PSUSettings to improve performance of large job output
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#pages-2)
Pages
* Fixed an issue where default values for form textboxes didn't work (#2592)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-38)
Platform
* Fixed an issue where deleted computers could be displayed in the Run As dropdown (#2593)
* Fixed an issue where 1 day rate limits would actually define a 24 day rate limit (#2594)
* Fixed an issue where canceling a git edit with a missing repo directory would fail (#2599)
* Fixed an issue where TCP and UDP logging targets would not configure properly through the admin console (#2600)
* Fixed an issue where app tokens set to never expire would not authenticate properly (#2598)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.9-7-30-2023)
4.0.9 - 7/30/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-25)
APIs
* Fixed an issue where the event hub edit modal would be empty
* Fixed an issue with connecting to event hubs that had authentication but did not specify roles
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-33)
Apps
* Fixed an issue adding images to the app designer
* Fixing issue with New-UDDataGrid pagination (#2546)
* Fixed an issue where row selection in New-UDDataGrid wasn't available in Get-UDElement (#2573)
* Added -OnSelectionChanged to New-UDDataGrid
* Fixed an issue where schema forms -OnSubmit would not run
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-39)
Automation
* Job output is now set at verbose for the log level to avoid duplicating the output in the database by default to avoid performance issues. Job output is still logged to the job output tables.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-39)
Platform
* Fixed an issue where the access control and app token dialog would not allow edits (#2576)
* Fixed an issue where the home page of the admin console could show a JavaScript error if the health checks failed to return a value (#2575)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.8-7-23-2023)
4.0.8 - 7/23/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-40)
Automation
* Fixed an issue where rerun job would not populate string array parameters correctly. (#2434)
* Fixed an issue where rerun job would not select the correct parameter set
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-34)
Apps
* Fixed an issue where New-UDTickPicker didn't display the picker component (#2551)
* Fixed an issue where New-UDToolTip didn't have a -Type parameter
* Fixed an issue where New-UDAutoComplete would display the value rather than the name of New-UDAutoComplete option when using -OnLoadOptions
* Fixed an issue where the export and delete logging buttons would not work for nested IIS sites (#2554)
* Fixed an issue where -Scrollable on didn't work on New-UDTabs (#2557)
* Fixed an issue where -Size for New-UDButton didn't display properly on the live docs (#2462)
* Fixed an issue where Get-UDElement would return an invalid value from New-UDAutoComplete
* Fixing issues with Show-UDToast -MessageSize (#1000)
* Fixing issues with Show-UDToast -Icon (#1913)
* Fixed a JavaScript error in the App Designer
* Fixed an issue where boolean parameters would not be serialized properly by the app designer (#2562)
* Fixed an issue where templates wouldn't work on Linux due to case sensitivity
* Fixed visual issues with textbox and autocomplete (#2419)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-40)
Platform
* Published folders now set the Cache-Control and Last-Modified headers
* Fixed an issue with creating and edit roles in the admin console (#2563)
* Fixed a concurrency issue with $Cache scope (#2564)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.7-7-17-2023)
4.0.7 - 7/17/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-41)
Automation
* Fixed an issue where the Run Script button could throw a JavaScript error in the admin console
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-41)
Platform
* Fixed an issue where the role selector would not populate in some circumstances in the admin console (#2545)
* Fixed an issue where environments would disappear if clicking cancel in manual git sync when no environments.ps1 file was defined.
* Fixed an issue where read only items (PSUHeader) would be recreated when adding new items to the same config file (#2454)
* Fixed an issue where read only items would have edit and delete buttons in the admin console
* Updated to Microsoft.Identity.Client 4.54.1 to support Pnp.PowerShell 2.2.0
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.6-7-11-2023)
4.0.6 - 7/11/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-42)
Platform
* Fixed an issue where X-Forwarded headers were not processed correctly by the Kestrel server when a remote reverse proxy was used.
* Added -LogGroomDays to Set-PSUSetting
* Fixed an issue where log messages would not be groomed properly
* Fixed an issue where the LiteDB database could become corrupt after some time when running in Azure using Azure File Shares.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-35)
Apps
* Fixed an issue where -Height on New-UDCodeEditor wouldn't have an affect (#2525)
* Adding md to Size to New-UDIcon (#2528)
* Fixed an issue with -Options in New-UDChartJS wouldn't apply properly
* Fixed an issue where saving an app page would return a 500 error (#2531)
* Fixed an issue that was causing the App Live Docs to display an error toast on some pages.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.5-7-6-2023)
4.0.5 - 7/6/2023
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-42)
Automation
* Fixed an issue with One Time schedules and boolean parameters
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-43)
Platform
* Fixed an issue with PSModulePath in external PowerShell hosts.
* Fixed an issue where Format On Save would throw an exception when removing the last item in a collection
* Fixed an issue starting external PowerShell processes when running as Local System and no alternate credentials are specified.
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.4-7-4-2023)
4.0.4 - 7/4/2023
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-36)
Apps
* Fixed an issue where Get-UDPage wouldn't work on Linux
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-43)
Automation
* Fixed an issue where running scripts as alternate users could result in an error about Out-PSUPipeline not being found.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-44)
Platform
* Fixed an issue where the logging system would fail to initialize if the SystemLogPath value was not set.
* Fixed an issue where running processes as alternate users would require the SeTcbPrivilege in some environments (#2521)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.3-7-2-2023)
4.0.3 - 7/2/2023
-------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-37)
Apps
* Fixed an issue where New-UDChartJS would not fill a line chart when a dataset was used by default
* Fixed an issue where the page editor would jump to the top on save (#2502)
* Fixed an issue where custom FavIcon would not load from URLs
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-44)
Automation
* Fixed an issue where Invoke-PSUScript did not work with SecureStrings.
* Fixed an issue where the System Default time zone would cause One-Time schedules to display the wrong time in the admin console (#2495)
* Fixed an issue where unauthenticated event hubs would not connect properly
* Fixed an issue where terminals could not be started when One-Way git sync was enabled (#2504)
* Fixed an issue where schedules could not be deleted
* Fixed an issue where One-Time schedules created with New-PSUSchedule would have parameters double serialized (#2500)
* Fixed an issue where the Job Diagnostics button wouldn't redirect to the correct page in a nested site (#2506)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-45)
Platform
* Fixed an issue where navigating to the PowerShell Universal Modules list would throw a JavaScript error on the modules page.
* Cookies are now prefixed with the base URL to allow for different sessions to the same host running multiple PSU instances
* Fixed an issue with creating logging targets in the admin console
* Fixed an issue where loading multiple apps from a module would fail and only load the first app (#2511)
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.2-6-25-2023)
4.0.2 - 6/25/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apis-26)
APIs
* Fixed concurrency issues when adding or removing APIs
* Fixed an issue where API docs would not work if authentication was enabled but no roles were defined.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-45)
Automation
* Fixed an issue where Job Handshake Timeout was not being set properly (#2476)
* Fixed an issue with editing scripts with tags (#2489)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-38)
Apps
* Button shouldn't default text to button (#2468)
* Fixed an issue where the code editor would switch to light theme when updated (#2477)
* Fixed an issue where the code editor wouldn't resize when the window resized (#2478)
* Fixed an issue where autocomplete would break once a value was selected and navigated away when using name\\value in New-UDAutoCompleteOption
* Fixed an issue where the default ChartJS line chart wasn't filled or have any tension applied to the line
* Fixed an issue where New-UDLink -Children would not render properly (#2490)
* Removed default card title and text
* Designer: Fixed an issue where the code view wouldn't display anything
* Designer: Fixed an issue where editing an icon would throw a JavaScript error
* Designer: Fixed an issue where the component resize handles were not visible in dark mode
* Designer: Added fields for component positioning.
* Designer: General fixes and improvements to the property and layout editor
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#pages-3)
Pages
* Fixed an issue where pages would not display correctly.
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-46)
Platform
* Fixed an issue where external app token validation did not work.
* Fixed an issue where Set-PSUVariable would not update secret values (#2475)
* Rolled back a change that set the PSModulePath on startup that was causing unexpected behavior
* Fixed an issue where git mode would always be Manual if configured from appsettings.json
* Fixed an issue where the heartbeat job would retry indefinitely in the event of a failure and fill up the hangfire job queue
* Fixed an issue where the roles drop down was empty (#2483)
* Fixed an issue where searching for modules would throw an exception in the admin console
* Fixed an issue where the module action buttons were obscured by the module name
* Added support for specifying a license via environment variable
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.1-6-14-2023)
4.0.1 - 6/14/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-39)
Apps
* Fixed an issue where ChartJS would not display data properly (#2463)
* Fix small size for switch (#2354)
* Fixed an issue where apps with -Component parameters would not load properly (#2458)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-46)
Automation
* Fixed an issue with viewing scripts in folders (#2418)
* Fixed an issue with folders when a module was installed via the admin console
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-47)
Platform
* Fixed an issue where log entry time stamps were not displayed correctly (#2460)
* Fixed an issue where Demo mode wouldn't display the default dashboard correctly (#2461)
* SameSite=None cookies are now optional
* Fixed an issue where accessing PSU remotely would not work with some browsers
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#id-4.0.0-6-13-2023)
4.0.0 - 6/13/2023
---------------------------------------------------------------------------------------------------------------
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#api-3)
API
* API endpoint documentation now only shows endpoints the user has access to (#363)
* Added Event Hubs
###
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#apps-40)
Apps
* Replaced react-tooltip with MUI tooltip
* Added -Sx, -Arrow, -FollowCursor, -EnterDelay, -LeaveDelay to New-UDTooltip
* Removed -Type and -Effect from New-UDTooltip
* Added -Truncate to New-UDTypography
* Added New-UDBreadcrumbs (#2150)
* Added support for validation, help text and display messages to New-UDForm -Script (#2043)
* Added -ShowBackButton to New-UDForm -Script (#2044)
* Added -ShowSearch to New-UDTransferList (#2340)
* Fixed an issue where $EventData -OnEdit in New-UDDataGrid would be a string (#2071, #2070, #1978)
* Removed -PopOut from New-UDExpansionPanelGroup (#2373)
* Fixed -Type Accordion on New-UDExpansionPanelGroup (#2373)
* Removed New-UDCodeEditor -Autoresize and set the default to autoresize (#2146)
* Added -Dense to New-UDAlert (#2214)
* Added New-UDButtonGroup and New-UDButtonGroupItem (#2180)
* Added -HelperText to New-UDTextbox (#2285)
* Added -OnChange to New-UDTextbox (#2287)
* Added -Content and Content parameter set to New-UDIcon (#640)
* Added New-UDHelmet
* Added GitHub-Flavored Markdown to New-UDMarkdown
* Added App Designer
* Added Test-UDConnected
* Added -NoData to New-UDTableTextOption (#2112)
* Added -JustifyContent to New-UDStack (#2189)
* Added the ability to disable session time out (#296)
* Added -Width and -Height to New-UDTransferList (#1452)
* Added New-UDDataGridColumn (#2258)
* Added Out-UDDataGridData (#2266)
* Added New-UDSpeedDial and New-UDSpeedDialAction (#2157)
* Added -Dense to New-UDList (#2300)
* Added -Dense to New-UDAlert (#2214)
* Added New-UDButtonGroup and New-UDButtonGroupItem (#2180)
* Added -HelperText to New-UDTextbox (#2285)
* Added -OnChange to New-UDTextbox (#2287)
* Apps now start asynchronously on server startup
* Fixed issue with New-UDAppBar -Footer (#2176)
* Remove support for Universal Dashboard Marketplace
* Renamed Dashboards to Apps
* Theme is now persisted per app (#2156)
* Fixed an issue where New-UDListItem -Label couldn't be a number (#2107)
* Added cursor pointer to Nivo charts with onClick handlers
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#automation-47)
Automation
* Breaking: One Time schedules are no longer written to schedules.ps1
* Added support for SecureString parameters (#1467)
* Added support for markdown in script descriptions (#2128)
* Added -Queue to Invoke-PSUScript
* Added support for IValidateSetValuesGenerator (#472)
* Script page now uses tabs for each section (#551)
####
[](https://docs.powershelluniversal.com/v4-beta/changelogs/changelog#platform-48)
Platform
* Added support for nested roles (#2442)
* Added Claim Type and Value autocomplete (#2201)
* Added Roles to secret variables (#2350)
* Added support for setting the Content-Security-Policy header (#2395)
* Added support for wildcard subdomains in CORS (#2408)
* Added --appsettings and --windowTitle to desktop mode
* Added buttons to run, clear and refresh health checks.
* Added -HideRunOn and -HideEnvironment to Set-PSUSetting (#2294)
* Added -Truncate Disables text wrapping and adds ellipsis for overflow (#2332)
* Fixed an issue where docker images would not run properly (#2359)
* Added groom job health check (#1839)
* Added export button for logs (#2318)
* Added Database (LiteDB and SQL), UDP, TCP and HTTP logging targets
* Added log viewer in admin console
* Added PSScriptAnalyzer and forwardWindowsAuthToken health checks
* Added -Reset to Sync-PSUConfiguration
* Added Suspend-PSUFileWatcher and Resume-PSUFileWatcher
* Added -Module, -Command to New-PSUApp
* Added -Module, -Command to New-PSUScript
* Added -Module, -Command to New-PSUEndpoint
* Added support for loading resources from modules.
* Added Health Checks
* Added LastUsed property to AppTokens (#2173)
* Added -LogoutUrl to OIDC (#764)
* Added -Credential to Environments (#1683)
* Added middleware.ps1
* Added logging header (#2286)
* Updated to PowerShell 7.3.1
* Updated to .NET 7.0.102
* Removed PowerShell Protect support.
* Removed templates
[PreviousSQL Data Grid](https://docs.powershelluniversal.com/v4-beta/samples/apps/sql-data-grid)
[NextExtension Changelog](https://docs.powershelluniversal.com/v4-beta/changelogs/extension-changelog)
Last updated 13 days ago
Was this helpful?
---
# Video Library | PowerShell Universal
[](https://docs.powershelluniversal.com/video-library#agents)
Agents
-------------------------------------------------------------------------
* [Sending Events](https://youtu.be/BK7XvIMnVss)
[](https://docs.powershelluniversal.com/video-library#automation)
Automation
---------------------------------------------------------------------------------
* [Script Parameters](https://youtu.be/iIlcc9Jhejs)
* [Inline Debugger](https://youtu.be/gteP8BpZj84)
[](https://docs.powershelluniversal.com/video-library#git)
Git
-------------------------------------------------------------------
* [Development and Production Environments](https://youtu.be/YFD-bIMUf10)
[](https://docs.powershelluniversal.com/video-library#hosting)
Hosting
---------------------------------------------------------------------------
* [Azure](https://youtu.be/tHB8hqvHhlU)
[](https://docs.powershelluniversal.com/video-library#platform)
Platform
-----------------------------------------------------------------------------
* [Module](https://youtu.be/tWHwcDXlKdY)
* [Variables](https://youtu.be/u06v9t7pkfg)
[](https://docs.powershelluniversal.com/video-library#portal)
Portal
-------------------------------------------------------------------------
* [Assigning Scripts to the Portal](https://youtu.be/sna8La-hrDs)
* [Script Forms and Tables](https://youtu.be/JV6GPD3dJZ0)
[PreviousGet Started](https://docs.powershelluniversal.com/get-started)
[NextAdditional Resources](https://docs.powershelluniversal.com/additional-resources)
Last updated 3 months ago
Was this helpful?
---
# Get Started | PowerShell Universal
[](https://docs.powershelluniversal.com/get-started#install-powershell-universal)
Install PowerShell Universal
-------------------------------------------------------------------------------------------------------------------
You'll need to install the PowerShell Universal server. [There are a lot of ways to do so,](https://docs.powershelluniversal.com/getting-started)
but you can use the command line below to get started quickly:
Windows
[](https://docs.powershelluniversal.com/get-started#tab-windows)
Linux
[](https://docs.powershelluniversal.com/get-started#tab-linux)
Mac OS X
[](https://docs.powershelluniversal.com/get-started#tab-mac-os-x)
Raspberry PI OS
[](https://docs.powershelluniversal.com/get-started#tab-raspberry-pi-os)
You can install PowerShell Universal as a service. Ensure that PowerShell is running as administrator, or the service won't install correctly.
Copy
Install-Module Universal
Install-PSUServer
You can install PowerShell Universal using the following shell script:
Copy
Install-Module Universal
Install-PSUServer
You can install PowerShell Universal using the Universal PowerShell module:
Copy
Install-Module Universal
Install-PSUServer -AddToPath
Start-PSUServer -Port 5000
Copy
wget https://imsreleases.blob.core.windows.net/universal/production/2.4.0/Universal.linux-arm.2.4.0.zip
unzip Universal.linux-arm.2.3.2.zip -d ./PSU
chmod +x ./PSU/Universal.Server
./PSU/Universal.Server
[](https://docs.powershelluniversal.com/get-started#open-powershell-universal)
Open PowerShell Universal
-------------------------------------------------------------------------------------------------------------
By default, PowerShell Universal runs on port 5000 of localhost.
###
[](https://docs.powershelluniversal.com/get-started#first-run-wizard)
First Run Wizard
The first run wizard will step you through the basic settings of PowerShell Universal. This includes the default admin username and password, security settings, telemetry settings and license.
####
[](https://docs.powershelluniversal.com/get-started#admin-account)
Admin Account
The admin account is used to login to PowerShell Universal. It will display a warning if the password does not match the complexity requirements. You can always change it later.
####
[](https://docs.powershelluniversal.com/get-started#security-settings)
Security Settings
Select from the drop down of security settings. They tweak certain features of PowerShell Universal in different levels of security. If you plan on cloning from a git repository, skip this step or set it to default.
####
[](https://docs.powershelluniversal.com/get-started#telemetry)
Telemetry
PowerShell Universal can [send anonymous telemetry data](https://docs.powershelluniversal.com/platform/telemetry)
if you opt-in to do so. If you plan to clone from a git repository, skip this setting.
####
[](https://docs.powershelluniversal.com/get-started#license)
License
Add your license file. This is optional and needs to be an account-based license key.
[](https://docs.powershelluniversal.com/get-started#create-an-api)
Create an API
-------------------------------------------------------------------------------------
APIs allow you to call PowerShell scripts over HTTP. To create an API, click API \\ Endpoints and click Create New Endpoint. Specify a URL.
Next, click details on your new API and enter the following command into the editor:
Copy
Get-ComputerInfo
Save the script and then click the Execute button to test it out.
You can also execute the API via `Invoke-RestMethod`.
Copy
PS C:\Users\adamr> Invoke-RestMethod http://localhost:5000/hello-world
WindowsBuildLabEx : 22000.1.amd64fre.co_release.210604-1628
WindowsCurrentVersion : 6.3
WindowsEditionId : Professional
WindowsInstallationType : Client
WindowsInstallDateFromRegistry : 8/6/2021 4:05:12 PM
WindowsProductId : 00330-52452-93139-AAOEM
WindowsProductName : Windows 10 Pro
WindowsRegisteredOrganization :
[](https://docs.powershelluniversal.com/get-started#create-a-script)
Create a Script
-----------------------------------------------------------------------------------------
To create a script, click Automation \\ Scripts and then click Create New Script.
Enter the following script into the editor and save:
Copy
Read-Host "What should I say?"
1..100 | ForEach-Object {
Write-Progress -PercentComplete $_ -Activity "Processing..."
}
Get-Service
Once the script is saved, click Run.
[](https://docs.powershelluniversal.com/get-started#create-an-app)
Create an App
-------------------------------------------------------------------------------------
To create a new PowerShell-based user interface (app), you can click User Interfaces \\ Apps and then Create New App.
After clicking Ok, click the Details button to edit the PowerShell script. Add the following script to the editor:
Copy
New-UDApp -Title "Hello, World!" -Content {
New-UDButton -Text "Click Me" -OnClick {
Show-UDToast -Message 'Success!!'
}
}
Save the app, click the Restart button and then click the View button. Click the Click Me button.
Learn more about the various features of PowerShell Universal:
* [APIs](https://docs.powershelluniversal.com/api/about)
* [Automation](https://docs.powershelluniversal.com/automation/about)
* [Apps](https://docs.powershelluniversal.com/apps/building-dashboards)
[PreviousWhat's New in v5?](https://docs.powershelluniversal.com/whats-new-in-v5)
[NextVideo Library](https://docs.powershelluniversal.com/video-library)
Last updated 6 months ago
Was this helpful?
---
# Additional Resources | PowerShell Universal
[](https://docs.powershelluniversal.com/additional-resources#blog)
[Blog](https://blog.ironmansoftware.com/tags/powershelluniversal/)
-------------------------------------------------------------------------------------------------------------------------------------------
The Ironman Software blog has articles about PowerShell Universal.
[](https://docs.powershelluniversal.com/additional-resources#demo)
[Demo](https://demo.powershelluniversal.com/)
----------------------------------------------------------------------------------------------------------------------
Demo instance of PowerShell Universal.
[](https://docs.powershelluniversal.com/additional-resources#discord)
[Discord](https://discord.gg/Sb5ngcjkj4)
--------------------------------------------------------------------------------------------------------------------
Chat with other PowerShell Universal users.
[](https://docs.powershelluniversal.com/additional-resources#downloads)
[Downloads](https://ironmansoftware.com/downloads)
--------------------------------------------------------------------------------------------------------------------------------
Download the latest version of PowerShell Universal.
[](https://docs.powershelluniversal.com/additional-resources#forums)
[Forums](https://forums.ironmansoftware.com/)
------------------------------------------------------------------------------------------------------------------------
Connect with the PowerShell Universal community.
[](https://docs.powershelluniversal.com/additional-resources#issue-tracker)
[Issue Tracker](https://github.com/ironmansoftware/issues)
--------------------------------------------------------------------------------------------------------------------------------------------
File a bug report or feature request for PowerShell Universal.
[](https://docs.powershelluniversal.com/additional-resources#pricing)
[Pricing](https://ironmansoftware.com/pricing/powershell-universal)
-----------------------------------------------------------------------------------------------------------------------------------------------
Purchase a license for the features of PowerShell Universal.
[](https://docs.powershelluniversal.com/additional-resources#scripts)
[Scripts](https://github.com/ironmansoftware/scripts)
---------------------------------------------------------------------------------------------------------------------------------
Examples and full solutions for PowerShell Universal.
[PreviousVideo Library](https://docs.powershelluniversal.com/video-library)
[NextInstallation](https://docs.powershelluniversal.com/getting-started)
Last updated 3 months ago
Was this helpful?
---
# Installation | PowerShell Universal
[](https://docs.powershelluniversal.com/getting-started#msi-install-windows)
MSI Install (Windows)
-------------------------------------------------------------------------------------------------------
The MSI install creates a PowerShell Universal service. By default, PowerShell Universal listens on port 5000. You can navigate to `http://localhost:5000`
MSI downloads are available on our [download page](https://ironmansoftware.com/downloads)
.
System installs run as a Windows service. User installs run when the user logs in to the machine. The user install runs in the user's context.
###
[](https://docs.powershelluniversal.com/getting-started#msi-parameters)
MSI Parameters
The following table contains the parameters you can specify if running `msiexec` against our MSI install for automation purposes:
Parameter
Description
Default Value
INSTALLFOLDER
The installation folder for PowerShell Universal
%ProgramFiles(x86)%\\Universal
TCPPORT
The TCP port the HTTP server will be listening on.
5000
REPOFOLDER
The repository folder to save the configuration files to.
%ProgramData%\\UniversalAutomation\\Repository
CONNECTIONSTRING
The SQL, SQLite, or PostgreSQL connection string.
Data Source=%ProgramData%\\UniversalAutomation\\database.db
DATABASETYPE
SQL, SQLite, or PostgreSQL
SQLite
STARTSERVICE
Whether to start the service after install (0 or 1)
1
SERVICEACCOUNT
The service account to set for the Windows service. Use the format of domain\\username.
None
SERVICEACCOUNTPASSWORD
The service account password to set for the Windows Service. The password will be masked with \*\*\*'s in the installer log.
None
TELEMETRY
Anonymous telemetry collection
0
ADDPSMODULEPATH
Adds the PowerShell Universal module directory to the PSModulePath environment variable.
1
STARTSERVICE
Whether to start the service after install.
1
INSTALLTYPE
Whether to perform a server or user install.
Server
###
[](https://docs.powershelluniversal.com/getting-started#example)
Example
The example below shows how to run `msiexec.exe` to install PowerShell Universal and provide parameters to the installer:
Copy
Start-Process msiexec.exe -ArgumentList "/I C:\Users\adamr\Downloads\PowerShellUniversal.5.5.2.msi /q /norestart /L*V `"C:\users\adamr\desktop\msi.log.txt`" STARTSERVICE=0 SERVICEACCOUNT=contoso\service_account SERVICEACCOUNTPASSWORD=ThisPasswordWillBeReplacedWithAsterisksInTheMSILogs" -Wait -NoNewWindow
[](https://docs.powershelluniversal.com/getting-started#zip-install)
ZIP Install
-------------------------------------------------------------------------------------
You can also download the ZIP from our [Downloads page](https://ironmansoftware.com/downloads/)
if you would like to xcopy deploy the files on Windows or Linux.
###
[](https://docs.powershelluniversal.com/getting-started#windows)
Windows
You can start Universal by unzipping the contents, unblocking the files and then executing `Universal.Server.exe`.
Copy
Expand-Archive -Path .\Universal.zip -DestinationPath .\Universal
Get-ChildItem .\Universal -Recurse | Unblock-File
Start-Process .\Universal\Universal.Server.exe
###
[](https://docs.powershelluniversal.com/getting-started#linux)
Linux
You can use the following command line on Linux to install and start PowerShell Universal:
Copy
wget https://imsreleases.blob.core.windows.net/universal/production/5.5.2/Universal.linux-x64.5.2.1.zip
sudo apt install unzip
unzip Universal.linux-x64.5.5.2.zip -d PSU
chmod +x ./PSU/Universal.Server
./PSU/Universal.Server
[](https://docs.powershelluniversal.com/getting-started#linux-service)
Linux Service
-----------------------------------------------------------------------------------------
You can use `systemd` to start PowerShell Universal as a service. The below script is an example of downloading a version of PowerShell Universal and installing it as a service:
Copy
# ----
# This script will install PowerShell Universal on Linux as a service
# This has been tested on Ubuntu 20.04 (ARM64) on a Raspberry Pi 4
# ----
# Dependencies:
# wget
# unzip
#
# Make sure they are installed
# ----
# These are used to derive the download URL
PSU_VERSION="5.5.2" # Change this to the current version
PSU_ARCH="arm64" # Change this to your desired architecture
PSU_FILE="Universal.linux-${PSU_ARCH}.${PSU_VERSION}.zip"
PSU_URL="https://imsreleases.blob.core.windows.net/universal/production/${PSU_VERSION}/${PSU_FILE}"
# These are used for installing PowerShell Universal
# If you'd like to use a different path, change this
PSU_PATH="/opt/psuniversal"
PSU_EXEC="${PSU_PATH}/Universal.Server"
# These are for installing it as a service
PSU_SERVICE="psuniversal"
PSU_USER="psuniversal"
# ----
# BEGIN
# ----
echo "Creating $PSU_PATH and granting access to $USER"
sudo mkdir $PSU_PATH
sudo setfacl -m "u:${USER}:rwx" $PSU_PATH
echo "Creating user $PSU_USER and making it the owner of $PSU_PATH"
sudo useradd $PSU_USER -m
sudo chown $PSU_USER -R $PSU_PATH
echo "Downloading PowerShell Universal $PSU_VERSION ($PSU_ARCH)"
wget -q $PSU_URL -O $PSU_FILE
echo "Extracting $PSU_FILE to $PSU_PATH"
unzip -o -qq $PSU_FILE -d $PSU_PATH
echo "Make $PSU_EXEC executable"
sudo chmod +x $PSU_EXEC
echo "Creating service configuration"
cat < ~/$PSU_SERVICE.service
[Unit]
Description=PowerShell Universal
[Service]
ExecStart=$PSU_EXEC
SyslogIdentifier=psuniversal
User=$PSU_USER
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
echo "Creating and starting service"
sudo cp -f ~/$PSU_SERVICE.service /etc/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable $PSU_SERVICE
sudo systemctl start $PSU_SERVICE
sudo systemctl status $PSU_SERVICE --no-pager
# If you don't use UFW, you can comment this out
echo "Allow port 5000/tcp"
sudo ufw allow 5000/tcp
# ----
# END
# ----
[](https://docs.powershelluniversal.com/getting-started#powershell-module)
PowerShell Module
-------------------------------------------------------------------------------------------------
You can use the PowerShell Universal PowerShell module to install the Universal server. To install the module, use `Install-Module`.
Copy
Install-Module Universal
To install the Universal server, you can use `Install-PSUServer`.
Copy
Install-PSUServer -LatestVersion
Running this command on Windows creates and starts a Windows service on your machine. Running this command on Linux creates and starts a systemd service on your machine. Running this command on Mac OS downloads and extracts the PowerShell Universal server.
[](https://docs.powershelluniversal.com/getting-started#docker)
Docker
---------------------------------------------------------------------------
See the [Docker page](https://docs.powershelluniversal.com/getting-started/docker#installation)
.
[](https://docs.powershelluniversal.com/getting-started#iis-install)
IIS Install
-------------------------------------------------------------------------------------
Please visit the [IIS hosting documentation](https://docs.powershelluniversal.com/config/hosting/hosting-iis)
for information on how to configure PowerShell Universal as an IIS website.
[](https://docs.powershelluniversal.com/getting-started#antivirus-configuration)
Antivirus Configuration
-------------------------------------------------------------------------------------------------------------
PowerShell Universal takes full advantage of PowerShell and the PowerShell SDK. It includes PowerShell scripts directly in the product. Consider configuring antivirus to allow execution of PowerShell scripts in PowerShell Universal.
###
[](https://docs.powershelluniversal.com/getting-started#directories)
Directories
The following directories contain examples from a standard Windows system of scripts and executable files that you may need to exclude from antivirus checks. Changing paths within appsettings.json or within the installer requires changing which directories are excluded.
Path
Description
%ProgramData%\\PowerShellUniversal
Contains log files and appsettings.json
%ProgramData%\\UniversalAutomation
Contains PowerShell scripts and artifacts. Contains the single file database when not using SQL integration.
%ProgramFiles(x86)\\Universal
Contains PowerShell Universal application executables, libraries and modules.
###
[](https://docs.powershelluniversal.com/getting-started#executables)
Executables
It may be necessary to exclude certain executables that run PowerShell scripts. The below is a list of executables that run PowerShell from PowerShell Universal.
Name
Description
Universal.Server.exe
The PowerShell Universal core service.
PowerShellUniversal.Host.exe
The PowerShell Universal host environment executable.
pwsh.exe
PowerShell 7.x
PowerShell.exe
PowerShell 5.x
[](https://docs.powershelluniversal.com/getting-started#default-admin-name-and-password)
Default Admin Name and Password
-----------------------------------------------------------------------------------------------------------------------------
You can use the `$ENV:PSUDefaultAdminName` and `$ENV:PSUDefaultAdminPassword` environment variables to change this behavior. These values are only used if no administrator account already exists. This is useful for cloud-based installations.
[](https://docs.powershelluniversal.com/getting-started#agent)
Agent
-------------------------------------------------------------------------
The PowerShell Universal Agent executes Event Hub actions. Install it depending on your environment:
###
[](https://docs.powershelluniversal.com/getting-started#windows-msi)
Windows (MSI)
The PowerShell Universal Agent MSI is on our download page. After installing the MSI, a PowerShell Universal Agent service runs on your machine. [Configure it](https://docs.powershelluniversal.com/api/event-hubs)
to connect to PowerShell Universal.
###
[](https://docs.powershelluniversal.com/getting-started#zip)
ZIP
ZIP files for each platform we support are on our downloads page. Each ZIP contains a `PowerShellUniversal.Agent.exe` or `PowerShellUniversal.Agent` file that can start an agent. Run the process as a service for it to start whenever the machine reboots.
[](https://docs.powershelluniversal.com/getting-started#next-steps)
Next Steps
-----------------------------------------------------------------------------------
At this point, Universal is up and running. Visit `http://localhost:5000` or your default port to navigate to the admin console. Log in with the default admin name and password or create a default admin account.
[PreviousAdditional Resources](https://docs.powershelluniversal.com/additional-resources)
[NextDocker](https://docs.powershelluniversal.com/getting-started/docker)
Last updated 3 months ago
Was this helpful?
---
# Docker | PowerShell Universal
[](https://docs.powershelluniversal.com/getting-started/docker#docker)
Docker
----------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/getting-started/docker#confirming-docker-is-installed-correctly)
Confirming Docker is installed correctly
> **NOTE:** Apple M1 devices: At the time of writing there are some issues on Apple M1 devices and, some ARM64/ARMv8 devices. Please review [this forum thread](https://forums.ironmansoftware.com/t/docker-image-not-working/8781/15)
> before proceeding.
####
[](https://docs.powershelluniversal.com/getting-started/docker#docker-1)
Docker
Run the following command to confirm Docker is installed:
Copy
docker version
Example Output:
Copy
Client: Docker Engine - Community
Version: 23.0.1
API version: 1.42
Go version: go1.19.5
Git commit: a5ee5b1
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 23.0.1
API version: 1.42 (minimum version 1.12)
Go version: go1.19.5
Git commit: bc3805a
Built: Thu Feb 9 19:47:01 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.18
GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
####
[](https://docs.powershelluniversal.com/getting-started/docker#docker-compose)
Docker Compose
Docker Compose v1 uses the command `docker-compose`. As of June 2023, support ends for Docker Compose v1.
Docker Compose v2 uses the command `docker compose`.
If you are using Docker Compose v1 please adjust the commands accordingly. More information on Docker Compose can be found [here](https://docs.docker.com/compose/)
.
Run one of the following commands to confirm that Docker Compose is installed:
Docker Compose v1:
Copy
docker-compose version
Docker Compose v2:
Copy
docker compose version
Example Output:
Copy
Docker Compose version v2.16.0
####
[](https://docs.powershelluniversal.com/getting-started/docker#a-docker-hello-world)
A Docker Hello-World
To ensure that Docker has the ability to pull and run container images run the following command:
Copy
docker run hello-world
Example Output:
Copy
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:ffb13da98453e0f04d33a6eee5bb8e46ee50d08ebe17735fc0779d0349e889e9
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
###
[](https://docs.powershelluniversal.com/getting-started/docker#installation)
Installation
###
[](https://docs.powershelluniversal.com/getting-started/docker#using-the-pre-built-container)
Using the pre-built Container
In order to run PowerShell Universal, use the provided container image. The docker image is available on [Docker Hub](https://hub.docker.com/r/ironmansoftware/universal)
.
The prebuilt version supports both free & paid features of PowerShell Universal.
Start the container by pulling the image and then running a container with the default port bound.
####
[](https://docs.powershelluniversal.com/getting-started/docker#running-a-basic-image)
Running a basic image
Copy
docker pull ironmansoftware/universal
docker run --name 'PSU' -it -p 5000:5000 ironmansoftware/universal
####
[](https://docs.powershelluniversal.com/getting-started/docker#present-an-image-to-a-different-port)
Present an image to a different port
If port 5000 is unavailable on your host, switch to another port.
e.g. Present on port 80
Copy
docker pull ironmansoftware/universal
docker run --name 'PSU' -it -p 80:5000 ironmansoftware/universal
####
[](https://docs.powershelluniversal.com/getting-started/docker#mount-a-volume)
Mount a volume
The `docker run` command allows you to mount a volume for persistent storage. Mount the volume to the /root folder.
**Mount a volume on container in Windows**
The following command mounts the folder `C:\docker\volumes\PSU` to `/root` on your container:
Copy
docker pull ironmansoftware/universal
docker run --name 'PSU' -it -p 5000:5000 -v C:\docker\volumes\PSU:/root ironmansoftware/universal
**Mount a volume on Container on Mac and Linux**
The following command mounts the folder `/docker/volumes/PSU` to `/root` on your container:
Copy
docker pull ironmansoftware/universal
docker run --name 'PSU' -it -p 5000:5000 -v /docker/volumes/PSU:/root ironmansoftware/universal
####
[](https://docs.powershelluniversal.com/getting-started/docker#stopping-a-container)
Stopping a Container
The following command removes a stopped container named `PSU`:
Copy
docker stop PSU
####
[](https://docs.powershelluniversal.com/getting-started/docker#removing-a-container)
Removing a Container
The following command stops a container named `PSU`:
Copy
docker rm PSU
The `--force` flag can remove a running container:
Copy
docker rm --force PSU
###
[](https://docs.powershelluniversal.com/getting-started/docker#docker-compose-1)
Docker Compose
Docker Compose allows you to use a yaml text file to standardize your build and script the deployment (or build) or multiple containers.
The default name for any compose file is `docker-compose.yml`. It is recommended you use this as your compose filename.
####
[](https://docs.powershelluniversal.com/getting-started/docker#creating-a-compose-script-for-windows)
Creating a Compose Script for Windows
The following compose file runs a Powershell Universal container in Windows:
Copy
version: "5.2.1"
services:
PSU:
container_name: PSU
image: ironmansoftware/universal:latest
ports:
- 5000:5000
restart: unless-stopped
environment:
- TZ=Europe/London
volumes:
- C:\docker\volumes\PSU:/root
####
[](https://docs.powershelluniversal.com/getting-started/docker#creating-a-compose-script-for-mac-linux)
Creating a Compose Script for Mac / Linux
The following compose file runs a Powershell Universal container on Mac and Linux:
Copy
version: "5.2.1"
services:
PSU:
container_name: PSU
image: ironmansoftware/universal:latest
ports:
- 5000:5000
restart: unless-stopped
environment:
- TZ=Europe/London
volumes:
- /docker/volumes/PSU:/root
####
[](https://docs.powershelluniversal.com/getting-started/docker#starting-containers-using-compose-scripts)
Starting Containers using Compose Scripts
Using a Terminal shell or PowerShell for Windows. Use the cd command to change the working directory with your `docker-compose.yml` script.
Run the following command:
Copy
docker compose up -d
Example Output:
Copy
Creating network "PSU_default" with the default driver
Pulling PSU (ironmansoftware/universal:latest)...
latest: Pulling from ironmansoftware/universal
7608715873ec: Pull complete
4e66273c6cfb: Pull complete
2649c52300c2: Pull complete
a20175666bc7: Pull complete
65ce93bc0653: Pull complete
Digest: sha256:d7ff98e6197d21070aac325c2efbefa393a4952d2e8ba6b1327dc97824ec4d55
Status: Downloaded newer image for ironmansoftware/universal:latest
Creating PSU ... done
####
[](https://docs.powershelluniversal.com/getting-started/docker#stopping-containers-using-compose-scripts)
Stopping Containers using Compose Scripts
Using a Terminal shell, or PowerShell for Windows. cd to the directory with your `docker-compose.yml` script.
Run the following command
Copy
docker compose down
Example Output:
Copy
[+] Running 2/2
⠿ Container PSU Removed 0.5s
⠿ Network PSU_default Removed 0.4s
####
[](https://docs.powershelluniversal.com/getting-started/docker#using-environment-variables-and-sql-persistence)
Using Environment Variables and SQL Persistence
You can add Environment variables into your Compose Scripts. Below is an example of:
* Setting a node name
* Adding SQL persistence
* Adding a SQL Connection String
Copy
version: "5.2.1"
services:
PSU:
container_name: PSU
image: ironmansoftware/universal:latest
ports:
- 5000:5000
restart: unless-stopped
environment:
- TZ=Europe/London
- Plugins__0=SQL
- Data__ConnectionString=Data Source=sql1.domain.com;Initial Catalog=PSUTicketBridge;User Id=psu_ticketbridge_dbo;Password=Password123;TrustServerCertificate=True;Trusted_Connection=True;integrated security=false;
- NodeName=mynodename
volumes:
- /docker/volumes/PSU:/root
####
[](https://docs.powershelluniversal.com/getting-started/docker#using-environment-variables-and-postgresql-persistence)
Using Environment Variables and PostgreSQL Persistence
You can add Environment variables into your Compose Scripts. Below is an example of:
* Setting a node name
* Adding PostgreSQL persistence
* Adding a PostgreSQL Connection String
Copy
version: "5.2.1"
services:
PSU:
container_name: PSU
image: ironmansoftware/universal:latest
ports:
- 5000:5000
restart: unless-stopped
environment:
- TZ=Europe/London
- Plugins__0=PostgreSQL
- Data__ConnectionString=Host=PGhostname; Database=PGdatabase; User Id=PGusername; Password=PGpassword!;Port=5432
- NodeName=mynodename
volumes:
- /docker/volumes/PSU:/root
###
[](https://docs.powershelluniversal.com/getting-started/docker#building-a-custom-container)
Building a Custom Container
If you wish to build more features, modify, or hardcode Environment Variables into your container, then create a `Dockerfile`
> _**NOTE:**_ Dockerfiles' are case-sensitive and must start with a capital 'D'.
To create a Docker image that can persist the Universal data, create a dockerfile like the one below.
This Dockerfile exposes port 5000, creates a /data volume, sets configuration environment variables to store the Universal repository and database in the volume and then sets the Universal.Server as the entry point to the container.
####
[](https://docs.powershelluniversal.com/getting-started/docker#writing-a-dockerfile-script-for-linux)
Writing a Dockerfile script for Linux
Copy
FROM ironmansoftware/universal:latest
LABEL description="Universal - The ultimate platform for building web-based IT Tools"
EXPOSE 5000
VOLUME ["/home/data"]
ENV Data__RepositoryPath /home/data/Repository
ENV Data__ConnectionString Data Source=/home/data/database.db
ENV UniversalDashboard__AssetsFolder /home/data/UniversalDashboard
ENV Logging__Path /home/data/logs/log.txt
ENTRYPOINT ["./Universal/Universal.Server"]
####
[](https://docs.powershelluniversal.com/getting-started/docker#building-a-container)
Building a container
From the path that hosts your Dockerfile, run the following command:
Copy
docker build . --tag=universal-persistent
####
[](https://docs.powershelluniversal.com/getting-started/docker#windows)
Windows
Copy
FROM ironmansoftware/universal:5.0.0-windowsservercore-1809
LABEL description="Universal - The ultimate platform for building web-based IT Tools"
EXPOSE 5000
VOLUME ["C:/data"]
ENV Data__RepositoryPath C:/data/Repository
ENV Data__ConnectionString Data Source=C:/data/database.db
ENV UniversalDashboard__AssetsFolder C:/data/UniversalDashboard
ENV Logging__Path C:/data/logs/log.txt
ENTRYPOINT ["C:/ProgramData/Universal/Universal.Server.exe"]
Run a build with the build command:
Copy
docker build . --tag=universal-persistent
Start the docker container with the run command and make sure to specify the volume to mount:
Copy
docker run -it --name powershelluniversal --mount source=psudata,target=/home/data --rm -d -p 5000:5000/tcp universal-persistent:latest
####
[](https://docs.powershelluniversal.com/getting-started/docker#sql)
SQL
To use SQL persistence, define the plugin and connection string as follows:
Copy
ENV Data__ConnectionString=Data Source=ServerName; Initial Catalog=DatabaseName; Integrated Security=SSPI;
ENV Plugins:0=SQL
####
[](https://docs.powershelluniversal.com/getting-started/docker#postgresql)
PostgreSQL
To use PostgreSQL persistence, define the plugin and connection string as follows:
Copy
ENV Data__ConnectionString=Host=PGhostname; Database=PGdatabase; User Id=PGusername; Password=PGpassword!;Port=5432
ENV Plugins:0=PostgreSQL
###
[](https://docs.powershelluniversal.com/getting-started/docker#time-zones)
Time Zones
To properly support time zones on Linux when scheduling jobs, include the `tzdata` package in your dockerfile along with an environment variable that specifies the server time zone.
Copy
ENV TZ Europe/Amsterdam
RUN apt-get install -y tzdata
[](https://docs.powershelluniversal.com/getting-started/docker#tags)
Tags
------------------------------------------------------------------------------
We publish the following tags to Docker Hub:
* latest - Current version using Ubuntu LTS
* 5.x-preview-modules - Nightly build of version 5 using Ubuntu LTS and select AZ modules
* 5.x-preview-- - Nightly build of version 5 with the specified OS and PS version
* 4.x-preview-- - Nightly build of version 4 with the specified OS and PS version
* 5.x-- - Production version 5 with the specified OS and PS version
* 5.x-modules - Current production version on Ubuntu LTS with select AZ modules installed
* 4.x-- - Current production version 4 with the specified OS and PS versions
###
[](https://docs.powershelluniversal.com/getting-started/docker#included-modules)
Included Modules
The module container images include the following modules:
* Az.Accounts
* Az.Compute
* Az.KeyVault
* Az.Resources
* Invoke-SqlCmd2
[](https://docs.powershelluniversal.com/getting-started/docker#summary)
Summary
------------------------------------------------------------------------------------
This basic "How to Get Started" enables you to start running or building PSU Containers. This references section links all sources for commands:
[](https://docs.powershelluniversal.com/getting-started/docker#references)
References
------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/getting-started/docker#running-containers)
Running Containers
https://docs.docker.com/engine/reference/commandline/run/
https://docs.docker.com/engine/reference/commandline/stop/
https://docs.docker.com/engine/reference/commandline/rm/
https://docs.docker.com/compose/
###
[](https://docs.powershelluniversal.com/getting-started/docker#building-containers)
Building Containers
https://docs.docker.com/engine/reference/commandline/build/
[PreviousInstallation](https://docs.powershelluniversal.com/getting-started)
[NextUpgrade](https://docs.powershelluniversal.com/getting-started/upgrading)
Last updated 6 months ago
Was this helpful?
---
# Uninstall | PowerShell Universal
[](https://docs.powershelluniversal.com/getting-started/uninstall#application-files)
Application Files
-----------------------------------------------------------------------------------------------------------
Depending on how you installed PowerShell Universal, you will need to uninstall the application files.
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#zip-installation)
ZIP Installation
If you installed using a provided ZIP file, you can simply stop the PowerShell Universal process or service and delete the folder you extracted to.
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#msi-installation)
MSI Installation
If you installed with the Windows MSI, uninstall the application from Add\\Remove Programs.
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#module-installation)
Module Installation
The Universal module installs the application files to the following locations by default.
####
[](https://docs.powershelluniversal.com/getting-started/uninstall#windows)
Windows
* `%ProgramData%\PowerShellUniversal`
####
[](https://docs.powershelluniversal.com/getting-started/uninstall#linux-and-mac-os)
Linux and Mac OS
* `%HOME%/.PowerShellUniversal`
[](https://docs.powershelluniversal.com/getting-started/uninstall#configuration-files)
Configuration Files
---------------------------------------------------------------------------------------------------------------
Configuration files are stored in the repository folder. Once you have removed the application files, you can delete the configuration files. They are stored in the following locations by default:
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#windows-1)
Windows
* `%ProgramData%\PowerShellUniversal`
* `%ProgramData%\UniversalAutomation`
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#linux)
Linux
* `%HOME%/.PowerShellUniversal/`
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#mac-os)
Mac OS
* `%HOME%/.PowerShellUniversal/`
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#desktop)
Desktop
* `%AppData%\PowerShellUniversal`
[](https://docs.powershelluniversal.com/getting-started/uninstall#database)
Database
-----------------------------------------------------------------------------------------
Removing the database depends on the database type used.
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#sqlite)
SQLite
SQLite databases are stored in a single file on the file system.
####
[](https://docs.powershelluniversal.com/getting-started/uninstall#windows-2)
Windows
* `%ProgramData%\PowerShellUniversal\database.db`
####
[](https://docs.powershelluniversal.com/getting-started/uninstall#linux-and-mac-os-1)
Linux and Mac OS
* `%HOME%/.PowerShellUniversal/database.db`
###
[](https://docs.powershelluniversal.com/getting-started/uninstall#postgresql-and-sql)
PostgreSQL and SQL
PostgreSQL and SQL databases are stored on your SQL server and will require you to manually remove the database.
[](https://docs.powershelluniversal.com/getting-started/uninstall#iis)
IIS
-------------------------------------------------------------------------------
You need to remove the IIS App Pool and Website when removing PowerShell Universal. Note that App Pools can be shared amongst websites and caution should be taken when doing so.
[PreviousUpgrade](https://docs.powershelluniversal.com/getting-started/upgrading)
[NextDowngrade](https://docs.powershelluniversal.com/getting-started/downgrade)
Last updated 11 months ago
Was this helpful?
---
# Upgrade | PowerShell Universal
[](https://docs.powershelluniversal.com/getting-started/upgrading#overview)
Overview
-----------------------------------------------------------------------------------------
This document will cover the upgrade process for production PowerShell Universal instances. We will cover the following topics.
1. Data Backup
2. Upgrade Process
3. Upgrade Validation
The Universal application binaries can generally be upgraded without having to change the configuration or database manually, but we do recommend backups of production data.
[](https://docs.powershelluniversal.com/getting-started/upgrading#recommendations)
Recommendations
-------------------------------------------------------------------------------------------------------
For production environments, we recommend deploying PowerShell Universal to a staging or development environment prior to major upgrades. This allows for testing before end users are affected. You can use [Development Licenses](https://docs.powershelluniversal.com/licensing#developer-licenses)
to test changes in PowerShell Universal instances without purchasing another license.
[](https://docs.powershelluniversal.com/getting-started/upgrading#id-1.-data-backup)
1\. Data Backup
---------------------------------------------------------------------------------------------------------
PowerShell Universal uses a script-based configuration system alongside a database used for retention of entities such as app tokens, job history and identities. If possible, you will want to backup these items before running an upgrade for easy rollback in case an issue is encountered during validation.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#database)
Database
Backing up the database ensures that all apptokens, job history, identities and database secrets are retained in the case of an upgrade failure. SQL databases also may adjust the schema of the database and may require a rollback of not only the data, but also the schema of the tables in the database.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#sqlite)
SQLite
By default, PowerShell Universal uses a single file database called SQLite. Unless configured otherwise, the database is stored in `%ProgramData%\UniversalAutomation`. You should have a `database.db` and possibility a `database-log.db`. Both of these files should be backed up. The service must be stopped in order to back up the files.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#sql)
SQL
When using SQL for persistence, backup the entire database (including schema). There isn't necessarily a need to stop the PowerShell Universal service when backing up the database, but it may continue to write to the database (for example when running scheduled jobs) after the backup has been completed.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#configuration-scripts)
Configuration Scripts
Scripts make up the main configuration data to backup when upgrading a production PowerShell Universal instance. For production, we recommend using a version control system. You can also take advantage of the built-in git integration. If you are using a two-way sync for PowerShell Universal git integration, consider tagging your git branch prior to the upgrade to allow for easy rollback to unexpected changes within the git repository.
[](https://docs.powershelluniversal.com/getting-started/upgrading#id-2.-upgrade-progress)
2\. Upgrade Progress
-------------------------------------------------------------------------------------------------------------------
Below are sections for each type of system upgrade and the steps that you should take based on how you originally installed PSU.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#msi)
MSI
When installing via the MSI, you will want to follow the same backup procedures above.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#appsettings.json)
appsettings.json
You will want to back up the `appsettings.json` file stored in `%ProgramData%\PowerShellUniversal`. This file contains information such as port, data storage location and other server settings. Typically, the MSI will not make changes to this file once created. It will use the settings found for the upgraded version. That said, if necessary, the MSI will make changes to the appsettings file. These changes are considered breaking and will be listed in the changelog for the release.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#service-account)
Service Account
When running an MSI upgrade, the PSU service is not uninstalled, and thus, the service account will still be set once the service starts up.
If you perform an uninstall and then an install using the MSI, then the service account will be removed.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#upgrade-process)
Upgrade Process
Once all the configuration files and the database are backed up, you can run the new MSI installer.
For major upgrades (e.g. v4.3.4 to v5.0.4 etc), you will need to uninstall the previous version prior to running the new version.
The installer may prompt for a restart of the machine if files are locked. The PSU MSI will uninstall all the files in the installation directory and install entirely new files.
Once the MSI has completed, you can navigate to your PowerShell Universal admin console to perform installation validation.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#iis)
IIS
Below you will find information about upgrading an IIS install.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#web.config)
web.config
In addition to the files listed to backup above, you will also want to consider backing up your `web.config` file. If you have made no changes to this file, you do not need to back it up.
The `web.config` file that is included in the application installation directory will be overwritten during upgrades. If you have moved your web.config file to an alternate location, it will not be overwritten. When creating an IIS website, you can simply include the `web.config` file in the web app's directory and have the [binaries stored in a different location](https://docs.powershelluniversal.com/config/hosting/hosting-iis)
.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#upgrade-process-1)
Upgrade Process
When upgrading with IIS, you will need to first stop your application pool to ensure that the binaries used by IIS are no longer in use and then replace the binaries with the new ones. To ensure that the upgrade works as expected, it's recommended to delete all the application files and then unzip the new ones into the same directory to avoid assembly conflicts.
As with any installation from a ZIP file, make sure that you run `Get-ChildItem -Recurse | Unblock-File` from an elevated command prompt across the PowerShell Universal files to ensure they can be executed properly.
Once you have copied the new files and unblocked them, start the app pool, navigate to the PowerShell Universal Admin Console and perform installation validation.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#universal-module)
Universal Module
The Universal module can be used to upgrade installations of PowerShell Universal previously installed by the module.
Do not use the Universal module to upgrade instances installed via MSI.
Follow the backup procedures above and then perform the upgrade.
First, upgrade the local PowerShell Universal module and verify the expected version is installed.
Copy
Update-Module Universal
Import-Module Universal -PassThru
Next, run `Update-PSUServer` to download and unzip the new PSU instance.
Copy
Update-PSUServer
After the upgrade is complete, navigate to the PowerShell Universal Admin Console and begin upgrade validation.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#zip)
ZIP
Perform the necessary backup procedures and download the latest ZIP of PowerShell Universal.
Stop the PowerShell Universal service. Delete the existing PowerShell Universal application files. Extract the ZIP files to the same directory. Finally, run `Unblock-File` against the directory to ensure that PSU can execute properly. Always run this command as administrator.
Copy
Get-ChildItem -Recurse | Unblock-File
After the upgrade is complete, navigate to the PowerShell Universal Admin Console and begin upgrade validation.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#database-1)
Database
By default, the PSU service will migrate to the latest database version during the startup process.
The database can also be upgraded before upgrading the application. This is recommended for larger installations that may require some time for the schema update to take place. In some environments, allowing the service to upgrade the database can result in a timeout, like with Service Control Manager in Windows.
If you are using SQL, you can find SQL files generated and placed in the SQL folder within the PSU installation media. Run these scripts against your database before upgrading.
All types of databases support the `psu` command line tool for upgrades.
Copy
psu db schema latest --connection-string "Data Source=C:\ProgramData\UniversalAutomation\database.db"
[](https://docs.powershelluniversal.com/getting-started/upgrading#id-3.-upgrade-validation)
3\. Upgrade Validation
-----------------------------------------------------------------------------------------------------------------------
After running an upgrade, you should perform basic validation against your PSU server to ensure that it is fully functional.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#notifications)
Notifications
Verify that there are no errors within the notification drop down. They may be a sign of issues during the upgrade.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#modules)
Modules
Upgrades to PowerShell Universal may change assembly versions of DLLs shipped with the platform. This can cause other modules to fail to load. While this may not be obvious at first, you may consider taking an inventory of modules used in your platform to ensure that the versions are consistent before and after the upgrade to limit changes.
If you have installed a version of the `Universal` module outside of PowerShell Universal (for example, with `Install-Module`), you must make sure to update the module or it can conflict with the new one installed with PowerShell Universal.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#apps)
Apps
The most common upgrade issues come due to changes in the Universal App framework. Apps can be complex and bug fixes or features can sometimes cause for certain user's app while fixing issues pertaining to another user's app. Please read the changelog before upgrading to understand the impact of changes made to the app framework and consider testing the app with development data before upgrading in production.
[](https://docs.powershelluniversal.com/getting-started/upgrading#nightly-builds)
Nightly Builds
-----------------------------------------------------------------------------------------------------
When using nightly builds, you cannot upgrade from one nightly version to another. You can upgrade from a generally available version to a nightly version. In order to test a new nightly build, you will need to uninstall the current nightly build, rollback the database schema and then install the new version. You can roll back the database schema with `psu.exe` .
Copy
.\psu.exe db schema --schema-version 5.4.0
[](https://docs.powershelluniversal.com/getting-started/upgrading#common-upgrade-issues)
Common Upgrade Issues
-------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#iis-app-pool-does-not-start-after-upgrade)
IIS App Pool Does Not Start After Upgrade
The most common upgrade issue is that `Unblock-File` is not called properly on the extracted files when performing an upgrade of a IIS ZIP install. Also make sure to run the `Unblock-File` command recursively and from within an administrative session.
Another command issue is extracting the files over the top of the existing files. This can cause assembly conflicts and puts the application in an unknown state. Follow the IIS upgrade documentation and delete the files before extracting them.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#command-not-found-errors)
Command Not Found Errors
When new functionality is added to PowerShell Universal it is typically done using new cmdlets. If older versions of the PowerShell Universal module are installed on the system, it can cause conflicts with the one shipped within the installation media. Ensure that you have removed older versions of the `Universal` module if you encounter these errors.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#table-column-not-found-error-when-using-sql-persistence)
Table\\Column Not Found Error when using SQL Persistence
This can happen if SQL schema upgrades are not being run during upgrades. If you set the `RunMigrations` setting to `false` in `appsettings.json`, you must run the migrations manually or the PowerShell Universal service will not function properly.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#breaking-app-component-change)
Breaking App Component Change
These changes can be visual or functional. Please ensure that you review the changelog for items that may be related to the change you are seeing. Consider posting the forums or opening a GitHub issue to see if the issue is as designed and if there is a viable workaround.
We make the best possible effort to support everyone's' apps without breaking changes. That said, every configuration is pretty unique so we are more than happy to address issues you may encounter. Please, just let us know.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#license-issues-after-upgrade)
License Issues after Upgrade
The licensing model of PowerShell Universal provides licensed users the ability to upgrade to whatever is the newest version as long as they have an active perpetual or subscription license. If you attempt to upgrade a server that is no longer within the license window, the server will not function as expected. You will need to downgrade back to the previous version to restore functionality.
Additionally, you may encounter issues due to the PSU service restart. When the service starts, it verifies license subscription status. If it fails to do so, it may not be licensed properly and cause other issues. The root cause is typically networking issues while attempting to access the IronmanSoftware.com website for activation. Offline license keys do not contact the IMS website for activation and will not encounter this issue.
[](https://docs.powershelluniversal.com/getting-started/upgrading#id-5.0-breaking-changes)
5.0 Breaking Changes
--------------------------------------------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#removal-of-pages)
Removal of Pages
The drag and drop page designer has been removed in favor of [Portal Pages](https://docs.powershelluniversal.com/portal/portal-pages)
and [Widgets](https://docs.powershelluniversal.com/portal/portal-widgets)
.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#removal-of-app-pages-designer)
Removal of App Pages Designer
The drag and drop page designer for apps has been removed. Apps created with the designer will still function.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#removal-of-access-controls)
Removal of Access Controls
Access Controls have been removed in favor of [Permissions](https://docs.powershelluniversal.com/security/enterprise-security/permissions)
. You can also use the [Portal](https://github.com/ironmansoftware/universal-docs/blob/v5/getting-started/broken-reference/README.md)
to assign resources, like scripts, to users without the need for complicated permissions.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#cmdlet-communication-channel-and-authorization-changes)
Cmdlet Communication Channel and Authorization Changes
Prior to v5, cmdlets would send data over HTTP or by using an internal gRPC channel. Now, all cmdlets use an externally facing gRPC Channel that is protected by authentication and authorization. It no longer uses standard REST API HTTP calls.
This can be a problem for PowerShell Universal instances behind [reverse proxies](https://docs.powershelluniversal.com/config/hosting/reverse-proxy)
and requires that the proper header values are sent.
Please review the [Module](https://docs.powershelluniversal.com/config/module)
documentation for more information.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#common-cmdlet-errors-you-may-encounter-during-upgrade)
Common cmdlet errors you may encounter during upgrade
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#http-status-code-403)
HTTP Status Code 403
The cmdlet you are calling does not have access to the PowerShell Universal APIs. You will need to specify an -AppToken parameter on the cmdlets in order to use them.
You can also enable the [permissive API security model](https://docs.powershelluniversal.com/config/module#authorization-security-model)
to allow internally called cmdlets from PowerShell Universal without the need for authorization.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#uri-not-defined)
URI Not Defined
The cmdlets are unable to determine how to call the PowerShell Universal APIs. You will need to either specify a -ComputerName parameter or setup the API URL in appsettings.json.
Copy
{
"API" : {
"URL": "http://localhost:5000"
}
}
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#ssl-certificate-error)
SSL Certificate Error
If you are using a self-signed certificate, you will need to specify the `-TrustCertificate` parameter of the cmdlets.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#powershell-7-environment-no-longer-uses-pwsh.exe)
PowerShell 7 Environment No longer Uses Pwsh.exe
The default PowerShell 7 environment uses a .NET version of Universal.Agent.exe executable running PowerShell 7.5. This allows for the greatest compatibility with PowerShell Universal libraries and other modules.
It's still possible to use the pwsh.exe process in custom environment configurations.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#iis-hosting-package)
IIS Hosting Package
If you are hosting in IIS, ensure that you install the [.NET 9.0 hosting bundle](https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-aspnetcore-9.0.4-windows-hosting-bundle-installer)
.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#integrated-environment-powershell-version)
Integrated Environment PowerShell Version
The integrated environment now uses PowerShell 7.5.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#sqlite-by-default)
SQLite by Default
SQLite is the default persistence method. You will need to perform a manual conversion from LiteDB before installing version 5.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#litedb-support-removed)
LiteDB Support Removed
LiteDB has been removed as a supported database engine. Included with the PowerShell Universal installation files, you will find `psu.exe`. It can be used to convert a LiteDB database into a SQLite database. Use the following command line.
Copy
.\psu.exe db convert --Path "$ENV:ProgramData\UniversalAutomation\database.db"
The tool will create a `database.bak` file before performing the conversion. Progress will be reported in the console.
####
[](https://docs.powershelluniversal.com/getting-started/upgrading#converting-a-database-for-a-msi-upgrade)
Converting a Database for a MSI Upgrade
In order for the PowerShell Universal installer to run successfully, you will need to update the database before running the MSI installer. Below are the steps to take to do so.
1. Download the ZIP package for Windows and extract to a local directory.
2. Stop the PowerShell Universal service
3. Run the psudb.exe command from the ZIP directory, as stated above, to convert the database file in %ProgramData%\\UniversalAutomation
4. Update the %ProgramData%\\PowerShellUniversal\\appsettings.json file to use the SQLite plugin rather than the LiteDB plugin
5. Run the PowerShell Universal v5 installer to upgrade the application files.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#desktop-mode-removed)
Desktop Mode Removed
Desktop mode has been removed. Resources such as hot keys, file associations and shortcuts are no longer supported. The MSI now supports User scope installs that will run as the current user and start upon login.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#install-psuserver-on-windows-installs-from-the-msi)
Install-PSUServer on Windows Installs from the MSI
In previous versions of PowerShell Universal, this command would install to a directory and create the service manually. This command now installs from MSI. If you previously installed with this module, you would need to remove the existing install with a previous version of the module and then install with the new version of the module.
Copy
Install-Module Universal -RequiredVersion 4.4.0
Remove-PSUServer
Open a new command prompt and run the following.
Copy
Uninstall-Module Universal
Install-Module Universal
Install-PSUServer
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#git-database-storage-removed)
Git Database Storage Removed
PowerShell Universal no longer supports storing the git repository directly in the database. We recommend using a remote git provider like GitHub, GitLab, or Gitea. PowerShell Universal v5 does support local git repositories without the need to sync to a remote. This allows for storing file history directly on the PowerShell Universal server.
###
[](https://docs.powershelluniversal.com/getting-started/upgrading#removed-heatmap-and-marker-cluster-from-new-udmap)
Removed Heatmap and Marker Cluster from New-UDMap
Maps no longer support heatmaps or marker clusters.
[PreviousDocker](https://docs.powershelluniversal.com/getting-started/docker)
[NextUninstall](https://docs.powershelluniversal.com/getting-started/uninstall)
Last updated 3 months ago
Was this helpful?
---
# Downgrade | PowerShell Universal
In some scenarios it may be required to roll back the version of PowerShell Universal. This could be due to a feature change or bug that affects the system in a way too impactful to continue with the version. We [always recommend](https://docs.powershelluniversal.com/getting-started/upgrading)
validating a version in a development or quality assurance environment before upgrading in production to avoid having to perform a downgrade.
Downgrading can be complicated and error prone. We recommend restoring from a backup or snapshot instead of downgrading.
[](https://docs.powershelluniversal.com/getting-started/downgrade#configuration-files)
Configuration Files
---------------------------------------------------------------------------------------------------------------
Downgrading the configuration files will require removing or altering the `.universal` repository files to remove or rename new parameters. New cmdlets will be ignored by PowerShell Universal. If a cmdlet was renamed, it may have to be updated as well. You will need to refer to the [changelog](https://docs.powershelluniversal.com/changelogs/changelog)
to see which cmdlets have changed in each version.
Major versions may include breaking changes. Minor versions may have additional cmdlets or parameters but will not have any breaking changes.
You can find information about each configuration file in the [Repository page](https://docs.powershelluniversal.com/config/repository)
.
It is much easier to restore from a backup of the configuration files before the upgrade rather than manually updating files.
[](https://docs.powershelluniversal.com/getting-started/downgrade#database)
Database
-----------------------------------------------------------------------------------------
Restoring the database to a previous version requires downgrading the schema. This can be accomplished with [PSU CLI](https://docs.powershelluniversal.com/config/psucli)
. Using the `schema` command, you will be able to select the down-level version.
Downgrading the database schema can be a destructive operation. You may remove tables and columns that contain data. Always backup a database before performing these operations.
Below is an example of downgrading the schema of a SQLite database to version 5.3.0. You will need to stop the PowerShell Universal services before doing so.
Copy
.\psu.exe schema --target-version '5.3.0' --connection-string "Data Source=C:\ProgramData\UniversalAutomation\database.db" --database-type "SQLite"
You can downgrade a nightly build version of the database to a stable version of the database to allow for an upgrade to the stable build of the target version. You will lose any data found in new columns or tables.
[](https://docs.powershelluniversal.com/getting-started/downgrade#application-files)
Application Files
-----------------------------------------------------------------------------------------------------------
Downgrading the application files is typically a simple process and depends on how you installed the product. You will need to perform the configuration file and database downgrades before performing the application downgrade.
###
[](https://docs.powershelluniversal.com/getting-started/downgrade#msi)
MSI
To downgrade an MSI installation, you will need to first uninstall the current version. PowerShell Universal will not allow you to run a downgrade. After the uninstall is complete, perform an installation of the target version.
If you have configured a service account, you will need to set the service account again after install. This will require the service account credentials.
###
[](https://docs.powershelluniversal.com/getting-started/downgrade#zip)
ZIP
To downgrade a ZIP installation, simply delete the PowerShell Universal application files. Once the directory is clear unzip the target version's ZIP into the installation directory. Ensure that you run `Get-ChildItem -Recurse | Unblock-File` after doing so.
###
[](https://docs.powershelluniversal.com/getting-started/downgrade#iis)
IIS
Similar to the ZIP installation, remove the old version's files and unzip and unblock the target version's files. Ensure that the web site and App Pool are stopped before attempting so.
[PreviousUninstall](https://docs.powershelluniversal.com/getting-started/uninstall)
[NextMigrate and Restore](https://docs.powershelluniversal.com/getting-started/migration)
Last updated 3 months ago
Was this helpful?
---
# Migrate and Restore | PowerShell Universal
It is often desirable to migrate a PowerShell Universal server configuration from one machine to another. This can be due to change of infrastructure or restoring from backup. This can be for operating system upgrades or general data center maintenance.
This document explains the steps necessary to migrate PowerShell Universal configuration to another machine.
We recommend stopping the PowerShell Universal service before performing the migration or restore.
Copy
Stop-Service 'PowerShellUniversal'
Depending on the type of migration or restoration, you may not need to perform all of these actions.
[](https://docs.powershelluniversal.com/getting-started/migration#configuration-data)
Configuration Data
-------------------------------------------------------------------------------------------------------------
The configuration data files are stored in `%ProgramData%\UniversalAutomation\Repository` by default. These will consist of features such as APIs, Scripts and Apps. The entire directory is necessary for the configuration of the target system to function.
You can either copy the folder manually or via PowerShell. Ensure that you include all subdirectories.
Copy
Copy-Item $ENV:ProgramData\UniversalAutomation\Repository \\newServer\C$\ProgramData\UniversalAutomation\Repository -Recurse
[](https://docs.powershelluniversal.com/getting-started/migration#database)
Database
-----------------------------------------------------------------------------------------
The database migration will depend on the type of database used.
###
[](https://docs.powershelluniversal.com/getting-started/migration#sqlite)
SQLite
You will need to copy the SQLite database file to the configured, or default, database location. On a default installation, this will be `%ProgramData%\UniversalAutomation\database.db`. The target machine account or service account will need read and write access to this database file.
Copy
Copy-Item $ENV:ProgramData\UniversalAutomation\database.db \\newServer\C$\ProgramData\UniversalAutomation\database.db
If you are restoring from backup, you may need to [Downgrade](https://docs.powershelluniversal.com/getting-started/downgrade)
the schema if you upgraded the version.
###
[](https://docs.powershelluniversal.com/getting-started/migration#sql-and-postgresql)
SQL and PostgreSQL
Because these databases are stored outside of the PowerShell Universal server, you do not need to perform a migration of the database itself. You will need to ensure that the target server has network access to the SQL host.
If you are restoring from backup, you may need to [Downgrade](https://docs.powershelluniversal.com/getting-started/downgrade)
the schema if you upgraded the version.
[](https://docs.powershelluniversal.com/getting-started/migration#application-settings)
Application Settings
-----------------------------------------------------------------------------------------------------------------
The PowerShell Universal `appsettings.json` file is necessary for providing the appropriate server settings to the platform. By default, this is stored in `%ProgramData%\PowerShellUniversal\appsettings.json`. You will need to copy this to the new server in the same location.
This file contains configuration settings such as HTTP certificate, authentication, git sync settings, API configuration options and more.
Copy
Copy-Item $ENV:ProgramData\PowerShellUniversal\appsettings.json \\newServer\C$\ProgramData\PowerShellUniversal\appsettings.json
appsettings.json files do not change between upgrades and you likely not need to perform this action during a restore.
[](https://docs.powershelluniversal.com/getting-started/migration#secret-vaults)
Secret Vaults
---------------------------------------------------------------------------------------------------
PowerShell Universal includes 3 built-in secret vaults that may need to be migrated. The database vault is included with the database migration and does not require extra steps. If you are performing a restore, it's unlikely you will need to perform these restore operations unless the secret vaults have become corrupted.
###
[](https://docs.powershelluniversal.com/getting-started/migration#psusecretstore)
PSUSecretStore
The `PSUSecretStore` vault uses the Microsoft's [SecretStore module](https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/get-started/using-secretstore?view=ps-modules)
. This module stores secrets, on disk, using symmetric encryption. A default encryption key is included with PowerShell Universal installations. If the key was updated, the new key will be in the appsettings.json file you migrated in the previous step. You will also need to move the physical secret store to the new server's file system.
The SecretStore module uses a user-specific storage location to ensure that ACLs are enforced on the files themselves. You will need to ensure that you copy the vault's contents to the account of the user that will be running PowerShell Universal on the new system.
Copy
Copy-Item $Env:LOCALAPPDATA\Microsoft\PowerShell\secretmanagement\localstore \\newServer\C$\Users\myServiceAccount\AppData\Local\Microsoft\PowerShell\secretmanagement\localstore
###
[](https://docs.powershelluniversal.com/getting-started/migration#builtinlocalvault)
BuiltInLocalVault
The `BuiltInLocalVault` is only available on Windows and uses Credential Manager to store secrets. You will need to recreate these secrets in the Credential Manager store on the new system.
Within Credential Manager, you will find PowerShell secrets stored with a `ps:` prefix.

While it's not possible to extract credentials directly from the Credential Manager UI, you can use the Secret Management modules directly. To retrieve secrets, you can do the following.
Copy
Install-Module Micorosoft.PowerShell.SecretManagement
Install-Module SecretManagement.JustinGrote.CredMan
Register-SecretVault -Name 'BuiltInLocalVault' -ModuleName SecretManagement.JustinGrote.CredMan
Get-SecretInfo -Vault BuiltInLocalVault
$Secret = Get-Secret -Name 'TestApiKey' -Vault 'BuiltInLocalVault' -AsPlainText
On the new server, you can do the reverse and call `Set-Secret`. Note that these commands need to run as the service account running PowerShell Universal in order to store them properly in the Credential Manager account for the user.
[](https://docs.powershelluniversal.com/getting-started/migration#authentication)
Authentication
-----------------------------------------------------------------------------------------------------
Certain authentication types will require configuration outside of PowerShell Universal. Unless you are moving the machine running PowerShell Universal or changing the accessible URLs, you will not need to perform these actions.
###
[](https://docs.powershelluniversal.com/getting-started/migration#openid-connect)
OpenID Connect
Ensure that the proper sign-on URLs are configured in your Identity provider (e.g. Azure AD or Okta) if the host name of the server is changing. Without properly configured sign-on URLs, users will not be able to sign on the new system.
###
[](https://docs.powershelluniversal.com/getting-started/migration#windows)
Windows
[Windows authentication](https://docs.powershelluniversal.com/security/enterprise-security/windows-sso)
requires the setup of an SPN for the service account running the PowerShell Universal service. Ensure this SPN is in place before attempting to use Windows authentication with the new system.
[](https://docs.powershelluniversal.com/getting-started/migration#other-resources-and-considerations)
Other Resources and Considerations
---------------------------------------------------------------------------------------------------------------------------------------------
There may be other resources that PowerShell Universal uses on the system that should be taken into account when migrating or restoring servers. Typically, you will not need to worry about these resources during a restore as they should remain the same if the machine has not changed.
* PowerShell Modules
* Environment Variables
* Local Account Privileges
* File System Permissions
* Proxy Configuration
* Certificates
* Git SSH keys or credentials
* DNS Settings
[](https://docs.powershelluniversal.com/getting-started/migration#application-files)
Application Files
-----------------------------------------------------------------------------------------------------------
Once all the following steps have been taken, you can now install PowerShell Universal on the new server. If you are downgrading during a restore, please follow the [Downgrade](https://docs.powershelluniversal.com/getting-started/downgrade)
documentation.
###
[](https://docs.powershelluniversal.com/getting-started/migration#msi-kestrel)
MSI \\ Kestrel
The MSI package for PowerShell Universal installs the platform as a Windows service that hosts its own web server called Kestrel. To install the service, [download the MSI](https://powershelluniversal.com/downloads)
and run it. We recommend using the exact same version as the source server.
During the MSI install, leave all settings as default. We recommend leaving the service account blank and unchecking the box that states to start the PowerShell Universal service after the installation is complete.
After the installation completes, the service will be created but not running. Open Service Control Manager (`services.msc`) and set the service account for the PowerShell Universal service. Start the service.
[](https://docs.powershelluniversal.com/getting-started/migration#debugging-issues)
Debugging Issues
---------------------------------------------------------------------------------------------------------
When migrating a PowerShell Universal service, you may run into issues the arise from configuration differences between the two systems. The following are places to look for more information.
###
[](https://docs.powershelluniversal.com/getting-started/migration#event-viewer)
Event Viewer
if the service starts and stops, there may be an issue with the database access. We recommend looking in the Application log within Event Viewer. PowerShell Universal will report two application Errors that will include .NET in the name. The second of the two errors will provide a human readable exception with more details.
###
[](https://docs.powershelluniversal.com/getting-started/migration#system-logs)
System Logs
PowerShell Universal will write system logs to the %ProgramData%\\PowerShellUniversal directory. Search for strings starting with `[ERR]` to gather more information about issues with the installation.
###
[](https://docs.powershelluniversal.com/getting-started/migration#notifications)
Notifications
After migrating the service, check for any error notifications that may indicate misconfiguration of the system.
[PreviousDowngrade](https://docs.powershelluniversal.com/getting-started/downgrade)
[NextLicensing](https://docs.powershelluniversal.com/licensing)
Last updated 5 months ago
Was this helpful?
---
# Licensing | PowerShell Universal
PowerShell Universal is licensed per server. We provide licenses for individuals and organizations.
You can purchase a license on [our website](https://ironmansoftware.com/pricing/powershell-universal)
.
[](https://docs.powershelluniversal.com/licensing#whats-a-server)
What's a server?
---------------------------------------------------------------------------------------
A server is a single running instance of PowerShell Universal.
###
[](https://docs.powershelluniversal.com/licensing#what-if-i-have-multiple-containers)
What if I have multiple containers?
The license applies to each container instance and not the container host. For example, if you have 10 container instances running, you will need 10 licenses.
###
[](https://docs.powershelluniversal.com/licensing#what-if-i-have-multiple-sites-on-a-single-iis-server)
What if I have multiple sites on a single IIS server?
Each website running PowerShell Universal will need a license and not a single license for the entire IIS server.
[](https://docs.powershelluniversal.com/licensing#install-a-license)
Install a License
-------------------------------------------------------------------------------------------
To install a license, click Settings \\ License. Click the Add License button to upload your license file. You can also install licenses using the `Set-PSULicense` cmdlet. Offline licenses do not require an internet connection but will need to be reinstalled when the subscription expires, in you wish to update the version of PowerShell Universal. Online licenses require an internet connection and access to `https://ironmansoftware.com` in order to verify subscription status.
You can use the `PSULICENSE` environment variable to set a license. The value of this environment variable needs to be the contents of the license file.
Proxy configuration can be done by clicking Settings \\ General and configuring the proxy URI and, optionally, credentials. You can also configure proxy settings with the `Set-PSUSetting` cmdlet.
###
[](https://docs.powershelluniversal.com/licensing#account-based-licensing)
Account-Based Licensing
When using account-based licensing, you will enter your account's license key. Whenever you activate a PowerShell Universal server, it will assign a license to computer. This license key does not change so there is no need to install a new license when renewing. You can view the assigned computers and account license key in your Ironman Software account.
The PowerShell Universal server needs to have access to ironmansoftware.com.

###
[](https://docs.powershelluniversal.com/licensing#offline-licenses)
Offline Licenses
Offline license files are required for environments that do not have internet access. You will need to install a new license file when you plan to upgrade to a version past the expiration date of the license.
###
[](https://docs.powershelluniversal.com/licensing#online-licenses)
Online Licenses
Online licenses work the same as offline but check the subscription status on ironmansoftware.com. The license is tied to a specific subscription and may require a change after renewal. We recommend account-based licensing over online licenses.
[](https://docs.powershelluniversal.com/licensing#developer-licenses)
Developer Licenses
---------------------------------------------------------------------------------------------
When a server license is purchased, you will be able to generate developer licenses for users building solutions for your team. Their intent is to be used by individual developers in their local environments. Do not use developer licenses when hosting a server for remote access for testing or production. Instances of PowerShell Universal running with a Developer License will display a water mark in the admin console and any apps stating they are intended only for development purposes.
You can generate a developer license on the Settings \\ License page by clicking the Generate Developer License button.

Generate Developer License
[](https://docs.powershelluniversal.com/licensing#licensed-features)
Licensed Features
-------------------------------------------------------------------------------------------
The following features of PowerShell Universal require a license.
* Debugging Tools
* Enterprise Authentication
* OpenID Connect
* SAML2
* WS-Federation
* Windows Authentication
* Custom Authentication Scripts
* Client Certificate
* App Tokens
* Enterprise Authorization
* Permissions
* Custom Authorization Scripts
* Platform
* Git Support
* Module Management
* Non-Database Credential Vaults
* SQL Support
* PostgreSQL Support
* Published Folders
* Cache Management
* Computer Groups
* Translations
* Settings
* Branding
* Tags
* APIs
* Event Hubs
* OpenAPI Documentation
* Automation
* Triggers
* Terminals
* Tests
* Apps
* App Page Editor
* App Function Editor
[PreviousMigrate and Restore](https://docs.powershelluniversal.com/getting-started/migration)
[NextSystem Requirements](https://docs.powershelluniversal.com/system-requirements)
Last updated 8 days ago
Was this helpful?
---
# System Requirements | PowerShell Universal
[](https://docs.powershelluniversal.com/system-requirements#hardware)
Hardware
-----------------------------------------------------------------------------------
Hardware recommendations are based on use and depend on how many scripts are running on the PowerShell Universal server and how many users are accessing the machine. Unix based machines typically require less hardware requirements than Windows based machines. The below recommendations are based on low use of the system.
###
[](https://docs.powershelluniversal.com/system-requirements#minimum)
Minimum
This is the base line for a Universal server with very minimal server load. It should be used for trial or development purposes only.
* 2 CPU
* 4 GB
* 250 GB
* SQLite Database
###
[](https://docs.powershelluniversal.com/system-requirements#recommended)
Recommended
This is the base line for a Universal server running several jobs an hour, hosting APIs with fewer than 100 requests per hour and a single App. It will support up to 10 concurrent users.
* 4 CPU
* 16 GB
* 500 GB
* MS SQL\\PostgreSQL Database
###
[](https://docs.powershelluniversal.com/system-requirements#performance)
Performance
This is the base line for a Universal server running dozens of jobs an hour, hosting APIs with greater than 100 requests per hour and up to 5 Apps. It will support up to 50 concurrent users.
* 16 CPU
* 32 GB
* 1 TB
* MS SQL\\PostgreSQL Database
###
[](https://docs.powershelluniversal.com/system-requirements#distributed)
Distributed
A distributed system employs multiple instances of PowerShell Universal connected to the same database. It requires either Git or managed deployments to share configuration data. We recommend this for widely used production instances. It provides the best performance, stability and redundancy.
This configuration can support hundreds of jobs per hour, thousands of API requests and many apps. The number of concurrent users will depend on the number of PSU servers in the cluster.
* 32 CPU
* 64 GB
* 1 TB
* MS SQL\\PostgreSQL Database
[](https://docs.powershelluniversal.com/system-requirements#software)
Software
-----------------------------------------------------------------------------------
###
[](https://docs.powershelluniversal.com/system-requirements#windows)
Windows
* Optional\*: [Windows PowerShell v5.1](https://www.microsoft.com/en-us/download/details.aspx?id=54616)
or later
* Optional\*: PowerShell v7.2 or later
* .NET Framework v4.8.0 or later (only for Windows PowerShell)
###
[](https://docs.powershelluniversal.com/system-requirements#linux)
Linux
* Optional\*: PowerShell v7.2 or later
* Validated Distributions: Ubuntu 18.04 and 20.04
###
[](https://docs.powershelluniversal.com/system-requirements#mac-os)
Mac OS
* Optional\*: PowerShell v7.2 or later
\*PowerShell Universal packages a version of the PowerShell SDK. If you do not have a version of PowerShell installed, the integrated versions of PowerShell will be used.
[](https://docs.powershelluniversal.com/system-requirements#network)
Network
---------------------------------------------------------------------------------
PowerShell Universal communicates on the port configured during installation and\\or configuration.
###
[](https://docs.powershelluniversal.com/system-requirements#web-server-front-end)
Web Server Front End
* Default Port: 5000
* Typical Configured Ports: 443, 80
###
[](https://docs.powershelluniversal.com/system-requirements#tcp-backend)
TCP Backend
* Dynamically assigned local port on loopback
###
[](https://docs.powershelluniversal.com/system-requirements#database)
Database
* MS SQL: 1433
* PostgreSQL: 5432
###
[](https://docs.powershelluniversal.com/system-requirements#agent)
Agent
* Web Server Front End Port, default 5000
###
[](https://docs.powershelluniversal.com/system-requirements#git)
Git
* Standard HTTP Ports, typically 443
###
[](https://docs.powershelluniversal.com/system-requirements#online-licensing)
Online Licensing
Online licensing requires access to www.ironmansoftware.com on port 443. Offline licenses do not require internet access.
###
[](https://docs.powershelluniversal.com/system-requirements#proxy)
Proxy
PowerShell Universal provides proxy configuration settings in the Settings \\ General page. These are used for communication with remote git, database or internet services.
[PreviousLicensing](https://docs.powershelluniversal.com/licensing)
[NextSupported Browsers](https://docs.powershelluniversal.com/supported-browsers)
Last updated 1 month ago
Was this helpful?
---
# Supported Browsers | PowerShell Universal
Universal uses a variety of modern web frameworks and can have issues with older browsers such as Internet Explorer.
Recent versions of the following web browsers are supported: [Chrome](https://www.google.com/chrome/)
, [Firefox](http://www.mozilla.org/firefox/)
, [Safari](http://www.apple.com/safari/)
, and [Microsoft Edge](https://www.microsoft.com/en-us/windows/microsoft-edge)
.
When considering a browser, you will need to understand that certain features are required. They include:
* [WebSocket](https://caniuse.com/?search=websocket)
* [CSS Flexbox](https://caniuse.com/?search=flexbox)
* [Fetch](https://caniuse.com/?search=fetch)
[PreviousSystem Requirements](https://docs.powershelluniversal.com/system-requirements)
[NextRelease Support Policy](https://docs.powershelluniversal.com/release-support-policy)
Last updated 11 months ago
Was this helpful?
---
# Release Support Policy | PowerShell Universal
PowerShell Universal recently migrated from a static, two-year support policy for releases to a standard and long-term support policy based on the underlying frameworks that the platform is built upon.
[](https://docs.powershelluniversal.com/release-support-policy#support-policy)
Support Policy
--------------------------------------------------------------------------------------------------
Starting with version 6, PowerShell Universal will provide long term support options pinned to the underlying support policy of the .NET SDK. Microsoft provides support for .NET versions for 18 months on standard support releases and 36 months on long-term support releases. PowerShell Universal runs on a similar support policy.
Version 5 is the last version on the historical, arbitrary support policy per major version. It will be supported until August 2026. Please see the below table for upcoming release support. Support is the same for each release type but varies based on the life time.
Version
Release Date
End of Support
Support Type
v4
6/23
6/26
Legacy
v5
8/24
8/26
Legacy
v6
3/26
3/29
Long Term
v7
3/27
9/28
Standard
v8
3/28
3/31
Long Term
v9
3/29
9/32
Standard
[PreviousSupported Browsers](https://docs.powershelluniversal.com/supported-browsers)
[NextAbout](https://docs.powershelluniversal.com/api/about)
Last updated 4 days ago
Was this helpful?
---
# About | PowerShell Universal
Universal provides the ability to define REST API endpoints using PowerShell. When the endpoints are executed by a compatible HTTP client, the PowerShell script will execute and return the result to the end user.
This feature is for developing custom APIs run by Universal. It is not required for managing Universal. Universal provides a set of management APIs that are included with the platform.
[](https://docs.powershelluniversal.com/api/about#execution-environment)
Execution Environment
---------------------------------------------------------------------------------------------------
The REST API execution environment runs in your default PowerShell version. Unlike Automation jobs, which can also be run via the Universal management API, APIs that you define are run in a single PowerShell process. Because the PowerShell process is not started and stopped for each call to the endpoint, the API is much faster.
You can define the [environment](https://docs.powershelluniversal.com/config/environments)
that runs the PowerShell Universal API process by specifying the `-ApiEnvironment` on `Set-PSUSetting`. Changing this setting will cause the API process to restart.
Copy
Set-PSUSetting -ApiEnvironment '7.1'
###
[](https://docs.powershelluniversal.com/api/about#per-endpoint-environment)
Per Endpoint Environment
You can also define the environment used by specifying the Environment on the endpoint itself.
Copy
New-PSUEndpoint -Url /environment -Environment Integrated -Endpoint {
$PSUEnvironment
}
###
[](https://docs.powershelluniversal.com/api/about#performance)
Performance
Performance is relative to the hardware and network conditions that you are running Universal on. That said, in ideal conditions you can expect the Universal APIs to service about 500 requests per second. This is with an entirely empty endpoint so any script that you add to that endpoint will reduce the throughput. The reduction of throughput will depend on the cmdlets and script executed within the API endpoint. There is no hard limit.
See [https://blog.ironmansoftware.com/webapp-benchmark-siege/](https://blog.ironmansoftware.com/webapp-benchmark-siege/)
for detailed information about benchmark tests on Universal APIs.
###
[](https://docs.powershelluniversal.com/api/about#variables)
Variables
Variables are listed on the [variables page](https://docs.powershelluniversal.com/platform/variables#api)
.
[](https://docs.powershelluniversal.com/api/about#api)
API
---------------------------------------------------------------
* [New-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUEndpoint.txt)
* [Get-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Get-PSUEndpoint.txt)
* [Remove-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Universal/Remove-PSUEndpoint.md)
* [Set-UASetting](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Universal/Set-UASetting.md)
[PreviousRelease Support Policy](https://docs.powershelluniversal.com/release-support-policy)
[NextEndpoints](https://docs.powershelluniversal.com/api/endpoints)
Last updated 4 days ago
Was this helpful?
---
# OpenAPI | PowerShell Universal
[](https://docs.powershelluniversal.com/api/openapi#about)
About
---------------------------------------------------------------------
API documentation can be produced for your endpoints by creating a new OpenAPI definition and assigning endpoints to it. OpenAPI is a standard format and can be consumed by tools, such as the [OpenAPI Generator](https://openapi-generator.tech/)
or [Swagger Codegen](https://swagger.io/tools/swagger-codegen/)
, to create clients. The Swagger dashboard is also integrated into PowerShell Universal to provide interactive documentation.
[](https://docs.powershelluniversal.com/api/openapi#management-api-documentation)
Management API Documentation
-------------------------------------------------------------------------------------------------------------------
You can view the Managment API documentation by visiting the built in Swagger dashboard.
Copy
http://localhost:5000/swagger/index.html
[](https://docs.powershelluniversal.com/api/openapi#create-an-openapi-document)
Create an OpenAPI Document
---------------------------------------------------------------------------------------------------------------
To create an OpenAPI definition, click APIs \\ Documentation and then Create new Endpoint Documentation. You can set the name, URL, description and authentication details for the documentation.

Endpoint Documentation Dialog
Once created, you can assign endpoints to the documentation by editing the endpoint.

Edit Endpoint
The documentation for your endpoint will appear within the Swagger dashboard. Select the definition with the Select a definition dropdown.

All your custom endpoints will be listed.

Swagger Documentation for APIs
[](https://docs.powershelluniversal.com/api/openapi#help-text)
Help Text
-----------------------------------------------------------------------------
You can specify help text for your APIs using comment-based help. Including a synopsis, description and parameter descriptions will result in each of those pieces being documented in the OpenAPI documentation and Swagger age.
For example, with a simple `/get/:id` endpoint, we could have comment-based help such as this.
Copy
<#
.SYNOPSIS
This is an endpoint
.DESCRIPTION
This is a description
.PARAMETER ID
This is an ID.
#>
param($ID)
$Id
The resulting Swagger page will show each of these descriptions.
[](https://docs.powershelluniversal.com/api/openapi#input-and-output-types)
Input and Output Types
-------------------------------------------------------------------------------------------------------
Types can be defined within an endpoint documentation ScriptBlock. Click the Edit Details button on the API documentation record.

Endpoint Documentation Editor
APIs can also be documented using input and output types by creating a PowerShell class and referencing it within your comment-based help. PowerShell Universal takes advantage of the `.INPUTS` and `.OUTPUTS` sections to specify accepted formats and define status code return values.
Within the `.INPUTS` and `.OUTPUTS` , you will define a YAML block to provide this information. To create types, use the Endpoint Documentation editor. This file is loaded when reading OpenAPI documents. This information is stored in `endpointsDocumentation.ps1`.
Copy
[Documentation()]
class MyReturnType {
[string]$Value
}
###
[](https://docs.powershelluniversal.com/api/openapi#inputs)
Inputs
Input types are defined in the `.INPUTS` section. This section is a YAML block that defines if the input is required, provides a description and specifies the content type. This is a content type followed by the PowerShell class you defined in the endpoint documentation.
Copy
<#
.INPUTS
Required: false
Description: This is an input value.
Content:
application/json: MyReturnType
#>
param()
###
[](https://docs.powershelluniversal.com/api/openapi#outputs)
Outputs
Output types are similar to input but are specified on return codes as well as their content type and PowerShell class. The below example returns an ADAccountType class when a HTTP OK (200) is returned from the API. A 400 (Bad Request) does not return data but does provide a description that will be displayed in the API documentation.
Copy
<#
.OUTPUTS
200:
Description: This is an output value.
Content:
application/json: ADAccountType
400:
Description: Invalid input
#>
param()
[PreviousEndpoints](https://docs.powershelluniversal.com/api/endpoints)
[NextEvent Hubs](https://docs.powershelluniversal.com/api/event-hubs)
Last updated 6 months ago
Was this helpful?
---
# Event Hubs | PowerShell Universal
Event Hubs require a [license](https://docs.powershelluniversal.com/licensing)
.
Event Hubs provide the ability to connect client to the PowerShell Universal server. Once connected, the PowerShell Universal server can send messages to the connected clients and they will run a local PowerShell script block.
[](https://docs.powershelluniversal.com/api/event-hubs#creating-an-event-hub)
Creating an Event Hub
--------------------------------------------------------------------------------------------------------
To create an event hub, click APIs \\ Event Hub and click Create New Event Hub. Event Hubs are named and can choose to enforce authentication and authorization.
[](https://docs.powershelluniversal.com/api/event-hubs#agent)
Agent
------------------------------------------------------------------------
You will need to install and configure the [PowerShell Universal Agent](https://docs.powershelluniversal.com/config/agent)
to use Event Hubs.
[](https://docs.powershelluniversal.com/api/event-hubs#send-events)
Send Events
------------------------------------------------------------------------------------
From within the PowerShell Universal server, you can send events from a hub to connected clients using the `Send-PSUEvent` cmdlet.
Copy
Send-PSUEvent -Hub 'MyHub' -Data "Hello!"
The `-Data` parameter accepts an object and will be serialized using CLIXML and send to the client. The data will be deserialized before passing to the script block.
You can also run commands. This does not require defining a script on the event hub client. You can also use the `Invoke-PSUCommand` alias to mimic native PowerShell behavior.
Copy
Invoke-PSUCommand -Hub "MyHub" -Command "Start-Process" -Parameters @{
FilePath = "Notepad"
}
[](https://docs.powershelluniversal.com/api/event-hubs#receive-data-from-clients)
Receive Data from Clients
----------------------------------------------------------------------------------------------------------------
This feature is only available when sending data to an individual client, rather than all clients connected to a hub.
Copy
$Connection = Get-PSUEventHubConnection | Where-Object UserName -eq 'Admin'
$Result = Send-PSUEvent -Hub 'Hub' -Data 'Say Hello!' -Connectionid $Connection.ConnectionId
Show-UDToast $Result
[](https://docs.powershelluniversal.com/api/event-hubs#example-running-scripts-on-remote-machines)
Example: Running Scripts on Remote Machines
---------------------------------------------------------------------------------------------------------------------------------------------------
This example provides a way to run scripts on remote machines without having to install another instance of PowerShell Universal.
This example allows for sending scripts to remote machines and executing them with a generic event hub script.
First, create an event hub in PowerShell Universal. This example does not use authentication.
Next, install the PowerShell Universal Agent on the remote machine. Create a configuration file in `%ProgramData%\PowerShellUniversal\agent.json`.
Copy
{
"Connections": [\
{\
"Url": "http://localhost:5000",\
"Hub": "eventHub",\
"ScriptPath": "script.ps1"\
}\
]
}
Next, create a helper script.ps1 to receive the event hub data and process requests from PSU to invoke scripts. It creates a new temporary PS1 file and uses the `$EventData` passed down from the event hub message with the contents and parameters for the script.
Copy
$TempFile = (New-TemporaryFile).FullName + ".ps1"
$EventData.Contents | Out-File -FilePath $TempFile
$Parameters = $EventData.Parameters
& $TempFile @Parameters
In PowerShell Universal, add a script that you want to run on the remote machine. In this example, it simply starts a process.
Copy
param($Name)
Start-Process $Name
Finally, add another script that sends the event down to the client. This could be from an API or an App as well. Because the script on the agent is generic, it will just run whatever is passed to it.
Copy
param($TargetComputer, $ProcessName)
Send-PSUEvent -Computer $TargetComputer -Data @{
Contents = Get-Content StartAProcess.ps1 -Raw
Parameters = @{
Name = $ProcessName
}
}
From here you could event use the script to schedule jobs to run on the remote machines using the agent.
[PreviousOpenAPI](https://docs.powershelluniversal.com/api/openapi)
[NextSecurity](https://docs.powershelluniversal.com/api/security)
Last updated 3 months ago
Was this helpful?
---
# Endpoints | PowerShell Universal
Endpoints are defined by their URI and HTTP method. Calls made to the Universal server that match your defined API endpoint and method execute the API endpoint script.
Copy
New-PSUEndpoint -Url '/endpoint' -Method 'GET' -Endpoint {
"Hello, world!"
}
To invoke the above method, you can use `Invoke-RestMethod`.
Copy
Invoke-RestMethod http://localhost:5000/endpoint
When defining endpoints in the management API, you can skip the `New-PSUEndpoint` call, as the admin console defines it.

API Properties
The only contents that you need to provide in the editor are the script you wish to call.

API Content
Avoid using endpoint URLs that match internal PowerShell Universal Management API URLs, as this causes unexpected behavior. You can reference the [OpenAPI documentation](https://docs.powershelluniversal.com/api/openapi#management-api-documentation)
for the [Management API](https://docs.powershelluniversal.com/config/management-api)
to verify that none of the URLs match.
[](https://docs.powershelluniversal.com/api/endpoints#http-methods)
HTTP Methods
-------------------------------------------------------------------------------------
Endpoints can have one or more HTTP methods defined. To determine which method is used by an endpoint, use the built-in `$Method` variable.
Copy
New-PSUEndpoint -Url '/user' -Method @('GET', 'POST') -Endpoint {
if ($Method -eq 'GET')
{
Get-User
}
else {
New-User
}
}
[](https://docs.powershelluniversal.com/api/endpoints#variable-url)
Variable URL
-------------------------------------------------------------------------------------
URLs can contain variable segments. You can denote a variable segment using a colon (`:`). For example, the following URL would provide a variable for the ID of the user. The `$Id` variable will be defined within the endpoint when it is executed. Variables must be unique in the same endpoint URL.
Copy
New-PSUEndpoint -Url '/user/:id' -Method 'GET' -Endpoint {
Get-User -Id $Id
}
To call this API and specify the ID, do the following:
Copy
Invoke-RestMethod http://localhost:5000/user/123
[](https://docs.powershelluniversal.com/api/endpoints#query-string-parameters)
Query String Parameters
-----------------------------------------------------------------------------------------------------------
Query string parameters are automatically passed into endpoints as variables that you can then access. For example, if you have an endpoint that expects an `$Id` variable, you can provide it in the query string.
Copy
New-PSUEndpoint -Url '/user' -Method 'GET' -Endpoint {
Get-User -Id $Id
}
The resulting `Invoke-RestMethod` call must then include the query string parameter.
Copy
Invoke-RestMethod http://localhost:5000/user?Id=123
When using multiple query string parameters, ensure that your URL is surrounded by quotes so PowerShell translates it properly. Including an ampersand (&) without quotes will cause issues in both Windows PowerShell and PowerShell 7.
Copy
Invoke-RestMethod "http://localhost:5000/user?Id=123&name=tim"
###
[](https://docs.powershelluniversal.com/api/endpoints#security-considerations)
Security Considerations
When accepting input via Query String parameters you may be vulnerable to [CWE-914: Improper Control of Dynamically-Identified Variables](https://cwe.mitre.org/data/definitions/914.html)
. Consider using a `param` block to ensure that only valid parameters are provided to the endpoint.
Below is an example of CWE-914. Include a `$IsChallengePassed` query string parameter to bypass the challenge.
Copy
New-PSUEndpoint -Url "/api/v1.0/CWE914Test" -Description "Vulnerable to CWE-914" -Endpoint {
if($ChallengeInputData -eq "AcceptableInput") {
$IsChallengePassed = $true
}
if($IsChallengePassed) {
"Challenge passed. Here is Sensitive Information"
} else {
"Challenge not passed"
}
}
In order to avoid this particular issue, you can use a `param` block.
Copy
New-PSUEndpoint -Url "/api/v1.0/CWE914Test" -Description "Not Vulnerable to CWE-914" -Endpoint {
Param(
$ChallengeInputData
)
if($ChallengeInputData -eq "AcceptableInput") {
$IsChallengePassed = $true
}
if($IsChallengePassed) {
"Challenge passed. Here is Sensitive Information"
} else {
"Challenge not passed"
}
}
[](https://docs.powershelluniversal.com/api/endpoints#headers)
Headers
---------------------------------------------------------------------------
Request headers are available in APIs using the `$Headers` variable. The variable is a hashtable. To access a header, use the following syntax:
Copy
$Headers['Content-Type']
[](https://docs.powershelluniversal.com/api/endpoints#cookies)
Cookies
---------------------------------------------------------------------------
Request cookies are available in APIs using the `$Cookies` variable. The variable is a hashtable. To access a cookie, use the following syntax:
Copy
$Cookies['Request-Cookie']
Send back request cookies with the `New-PSUApiResponse` cmdlet. Use the `-Cookies` parameter with a supplied hashtable.
Copy
New-PSUApiResponse -StatusCode 200 -Cookies @{
ResponseCookie = '123'
}
[](https://docs.powershelluniversal.com/api/endpoints#body)
Body
---------------------------------------------------------------------
To access a request body, you will simply access the `$Body` variable. Universal `$Body` variable will be a string. If you expect JSON, you should use `ConvertFrom-Json`.
Copy
New-PSUEndpoint -Url '/user' -Method Post -Endpoint {
$User = ConvertFrom-Json $Body
New-User $User
}
To call the above endpoint, specify the body of `Invoke-RestMethod`.
Copy
Invoke-RestMethod http://localhost:5000/user -Method Post -Body "{'username': 'adam'}"
[](https://docs.powershelluniversal.com/api/endpoints#live-log)
Live Log
-----------------------------------------------------------------------------
You can view the live log information for any endpoint by clicking the log tab. Live logs include URL, HTTP method, source IP address, PowerShell streams, status code, return Content Type, and HTTP content length.
You can write to the live log from within your endpoints with cmdlets like `Write-Host`.

Endpoint Live Log
[](https://docs.powershelluniversal.com/api/endpoints#testing)
Testing
---------------------------------------------------------------------------
You can use the Test tab in the Endpoint editor to test your APIs. Using this Test tool, you can adjust headers, the query string, and body. You can also adjust the Authentication and Authorization for the test.

Endpoint Test Tab
When using the test tab, any changes to the values of the test will result in an updated Code block that you can then use within PowerShell. Click the Code tab to view the test code.
Copy
Invoke-RestMethod -Uri 'http://localhost:5000/test-api?Page=1' -Headers @{'X-Custom-Header' = 'Value';} -Method 'POST'
Additionally, tests performed within the tester will be stored for 30 days to allow for retesting without having to reconfigure all the properties. Clicking the Apply button will setup the Test tool with the same properties.

Test History
[](https://docs.powershelluniversal.com/api/endpoints#form-data)
Form Data
-------------------------------------------------------------------------------
You can pass data to an endpoint as form data. Form data will pass into your endpoint as parameters.
Copy
New-PSUEndpoint -Url '/user' -Method Post -Endpoint {
param([Parameter(Mandatory)]$userName, $FirstName, $LastName)
New-User $UserName -FirstName $FirstName -LastName $LastName
}
You can then use a hashtable with Invoke-RestMethod to pass form data.
Copy
Invoke-RestMethod http://localhost:5000/user -Method Post -Body @{
UserName = "adriscoll"
FirstName = "Adam"
LastName = "Driscoll"
}
[](https://docs.powershelluniversal.com/api/endpoints#json-data)
JSON Data
-------------------------------------------------------------------------------
You can pass JSON data to an endpoint and it will automatically bind to a param block.
Copy
New-PSUEndpoint -Url '/user' -Method Post -Endpoint {
param([Parameter(Mandatory)]$userName, $FirstName, $LastName)
New-User $UserName -FirstName $FirstName -LastName $LastName
}
You can then send JSON data to the endpoint.
Copy
Invoke-RestMethod http://localhost:5000/user -Method Post -Body (@{
UserName = "adriscoll"
FirstName = "Adam"
LastName = "Driscoll"
} | ConvertTo-Json) -ContentType 'application/json'
[](https://docs.powershelluniversal.com/api/endpoints#param-block)
Param Block
-----------------------------------------------------------------------------------
You can use a `param` block within your script to enforce mandatory parameters and provide default values for optional parameters such as query string parameters. Variables such as `$Body`, `$Headers` and `$User` are provided automatically.
In the below example, the `$Name` parameter is mandatory and the `$Role` parameter has a default value of Default.
Copy
New-PSUEndpoint -Url '/user/:name' -Endpoint {
param([Parameter(Mandatory)$Name, $Role = "Default")\
}\
\
When using the `param` block with route parameters like the above example, you must include the route variable in your parameter. If it is not specified, you will not have access to that value.\
\
For example, the following `$Name` variable is always `$null`. The endpoint always returns false.\
\
Copy\
\
New-PSUEndpoint -Url '/user/:name' -Endpoint {\
param($Role = "Default")\
\
$Name -eq 'Adam'\
}\
\
If you use the `CmdletBinding` or `Parameter` attribute within your param block, the endpoint will strictly enforce which parameters are allowed into the endpoint.\
\
For example, the following enforces that the name parameter is specified.\
\
Copy\
\
New-PSUEndpoint -Url '/user' -Endpoint {\
param([Parameter(Mandatory)$Name)\
}\
\
That said, you cannot specify additional parameters to the endpoint. Doing the following will cause an error.\
\
Copy\
\
Invoke-RestMethod http://localhost:5000/user -Method Post -Body (@{ \
Name = "adriscoll"\
DisplayName = 'Adam'\
} | ConvertTo-Json) -ContentType 'application/json'\
\
If you change your endpoint to avoid using the `Parameter` attribute, you can pass in any number of params and they will be bound as variables and not parameters to the endpoint.\
\
Copy\
\
New-PSUEndpoint -Url '/user' -Endpoint {\
param($Name)\
}\
\
[](https://docs.powershelluniversal.com/api/endpoints#returning-data)\
\
Returning Data\
\
\
-----------------------------------------------------------------------------------------\
\
Data returned from endpoints is assumed to be JSON data. If you return an object from the endpoint script block, it is automatically serialized to JSON. If you want to return another type of data, you can return a string formatted however you chose.\
\
[](https://docs.powershelluniversal.com/api/endpoints#processing-files)\
\
Processing Files\
\
\
---------------------------------------------------------------------------------------------\
\
### \
\
[](https://docs.powershelluniversal.com/api/endpoints#uploading-files)\
\
Uploading Files\
\
You can process uploaded files by using the `$Data` parameter to access the byte array of data uploaded to the endpoint.\
\
Copy\
\
New-PSUEndpoint -Url '/file' -Method Post -Endpoint {\
$Data\
}\
\
PS C:\Users\adamr> iwr http://localhost:5000/file -method post -InFile '.\Desktop\add-dashboard.png'\
\
StatusCode : 200\
StatusDescription : OK\
Content : [137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,2,17,0,0,1,92,8,2,0,0,0,249,210,123,106,0,0,0,1,\
115,82,71,66,0,174,206,28,233,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,9,112,72,89,115,0,\
0,…\
\
`The multipart/form-data`content type is not supported for uploading files to APIs.\
\
You can also save the file into a directory.\
\
Copy\
\
New-PSUEndpoint -Url '/file' -Method Post -Endpoint {\
[IO.File]::WriteAllBytes("tempfile.dat", $Data)\
}\
\
### \
\
[](https://docs.powershelluniversal.com/api/endpoints#downloading-files)\
\
Downloading Files\
\
You can send files down using the `New-PSUApiResponse` cmdlet.\
\
Copy\
\
New-PSUEndpoint -Url '/image' -Endpoint {\
$ImageData = [IO.File]::ReadAllBytes("image.jpeg")\
New-PSUApiResponse -ContentType 'image/jpg' -Data $ImageData\
}\
\
[](https://docs.powershelluniversal.com/api/endpoints#returning-custom-responses)\
\
Returning Custom Responses\
\
\
-----------------------------------------------------------------------------------------------------------------\
\
You can return custom responses from endpoints by using the `New-PSUApiResponse` cmdlet in your endpoint. This cmdlet allows you to set the status code, content type and even specify the byte\[\] data for the content to be returned.\
\
Copy\
\
New-PSUEndpoint -Url '/file' -Method Get -Endpoint {\
New-PSUApiResponse -StatusCode 410\
}\
\
You can also return custom body data with the `-Body` parameter of `New-PSUApiResponse`.\
\
Copy\
\
New-PSUEndpoint -Url '/file' -Method Get -Endpoint {\
New-PSUApiResponse -Body "Not what you're looking for." -StatusCode 404\
}\
\
Invoking the REST method returns the custom error code.\
\
Copy\
\
PS C:\Users\adamr\Desktop> invoke-restmethod http://localhost:8080/file\
\
Invoke-RestMethod: Not what you're looking for.\
\
You can control the content type of the returned data with the `-ContentType` parameter.\
\
Copy\
\
New-PSUEndpoint -Url '/file' -Method Get -Endpoint {\
New-PSUApiResponse -Body "12" -ContentType 'text/xml'\
}\
\
You can control the response headers with a hashtable of values that you pass to the `-Headers`parameter.\
\
Copy\
\
New-PSUApiResponse -StatusCode 200 -Headers @{\
"Referrer-Policy" = "no-referrer"\
}\
\
[](https://docs.powershelluniversal.com/api/endpoints#persistent-runspaces)\
\
Persistent Runspaces\
\
\
-----------------------------------------------------------------------------------------------------\
\
Persistent runspaces allow you to maintain runspace state between API calls. This is important for users that perform some sort of initialization within their endpoints that they do not want to execute on subsequent API calls.\
\
By default, runspaces are reset after each execution. This removes variables, modules and functions defined during the execution of the API.\
\
To enable persistent runspaces, you will need to configure an [environment](https://docs.powershelluniversal.com/config/environments)\
for your API. Set the `-PersistentRunspace` parameter to enable this feature. This is configured in the `environments.ps1` script.\
\
Copy\
\
New-PSUEnvironment -Name 'Env' -Path 'powershell.exe' -PersistentRunspace\
\
You can then assign the API environment in the `settings.ps1` script.\
\
Copy\
\
Set-PSUSetting -ApiEnvironment 'Env'\
\
[](https://docs.powershelluniversal.com/api/endpoints#timeout)\
\
Timeout\
\
\
---------------------------------------------------------------------------\
\
By default, endpoints will not time out. To set a timeout for your endpoints, you can use the `New-PSUEndpoint` `-Timeout` parameter. The timeout is set in the number of seconds.\
\
[](https://docs.powershelluniversal.com/api/endpoints#external-endpoint-content)\
\
External Endpoint Content\
\
\
---------------------------------------------------------------------------------------------------------------\
\
You can define the path to an external endpoint content file with the `-Path` parameter of `New-PSUEndpoint`. The path is relative to the `.universal` directory in Repository.\
\
The content of the `endpoints.ps1` file is then this:\
\
Copy\
\
New-PSUEndpoint -Url "/path" -Path "endpoint-path.ps1"\
\
[](https://docs.powershelluniversal.com/api/endpoints#c-apis)\
\
C# APIs\
\
\
--------------------------------------------------------------------------\
\
C# APIs are enabled as a [plugin](https://docs.powershelluniversal.com/platform/plugins#c-api-environment)\
.\
\
There is no UI for creating a C# API, so you need to do so using configuration files. First, create a `.cs` file that runs your API.\
\
You will have access to a `request` parameter that includes all the data about the API request.\
\
Copy\
\
public class ApiRequest\
{\
public long Id;\
public ICollection Variables;\
public IEnumerable Files { get; set; };\
public string Url;\
public ICollection Headers;\
public byte[] Data;\
public int ErrorAction;\
public ICollection Parameters;\
public string Method;\
public ICollection Cookies;\
public string ClaimsPrincipal;\
public string ContentType;\
}\
\
You will also have access to a `ServiceProvider` property that allows you to access services within PowerShell Universal. These are not currently well-documented, but below is an example of restarting a dashboard.\
\
Copy\
\
var dm = ServiceProvider.GetService(typeof(IDashboardManager));\
var dashboard = dm.GetDashboard(1);\
dm.Restart(dashboard);\
\
Some other useful services include:\
\
* IDatabase\
\
* IApiService\
\
* IConfigurationService\
\
* IJobService\
\
\
You can choose to return an `ApiResponse` from your endpoint.\
\
Copy\
\
return new ApiResponse {\
StatusCode = 404\
};\
\
Once you have defined your C# endpoint file, you can add it by editing `endpoints.ps1`.\
\
Copy\
\
New-PSUEndpoint -Url /csharp -Path endpoint.cs -Environment 'C#'\
\
The PowerShell Universal service automatically compiles and runs C# endpoints.\
\
[](https://docs.powershelluniversal.com/api/endpoints#api)\
\
API\
\
\
-------------------------------------------------------------------\
\
* [New-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUEndpoint.txt)\
\
* [Get-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Get-PSUEndpoint.txt)\
\
* [Remove-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Remove-PSUEndpoint.txt)\
\
* [New-PSUApiResponse](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUApiResponse.txt)\
\
* [Set-PSUSetting](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Set-PSUSetting.txt)\
\
\
[PreviousAbout](https://docs.powershelluniversal.com/api/about)\
[NextOpenAPI](https://docs.powershelluniversal.com/api/openapi)\
\
Last updated 3 months ago\
\
Was this helpful?
---
# Error Handling | PowerShell Universal
By default, endpoints will return a 200 OK message even if there are errors. If an error occurs, you will get a blank response from the endpoint. This document demonstrates different ways to handle errors within APIs.
[](https://docs.powershelluniversal.com/api/error-handling#automatically-returning-errors)
Automatically Returning Errors
------------------------------------------------------------------------------------------------------------------------------
To automatically return errors from APIs, you can change the default behavior by setting the `-ErrorAction` parameter of `New-PSUEndpoint` to `Stop`. Any errors will cause an 500 Internal Server Error to be returned with a list of the errors and stack trace.
Terminating errors will always return a 500 Internal Server Error.
Copy
New-PSUEndpoint -Url "/error" -Endpoint {
throw "Uh oh!"
} -ErrorAction stop
New-PSUEndpoint -Url /error2 -Endpoint {
Write-Error "Whoa!"
} -ErrorAction Stop
You will notice different behavior in Windows PowerShell and PowerShell 7 when calling REST APIs that return errors. In Windows PowerShell, you will receive a generic error that doesn't return the error message.
Copy
PS C:\Users\adamr> invoke-restmethod http://localhost:5000/error2
invoke-restmethod : The remote server returned an error: (500) Internal Server Error.
At line:1 char:1
+ invoke-restmethod http://localhost:5000/error2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], Web
Exception
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
In PowerShell 7, when an error is returned, you will see the error message returned.
Copy
PS C:\Users\adamr\Desktop> invoke-restmethod http://localhost:5000/error
Invoke-RestMethod: Uh oh!
at , : line 2
at , : line 1
PS C:\Users\adamr\Desktop> invoke-restmethod http://localhost:5000/error2
Invoke-RestMethod: Whoa
at , : line 2
at , : line 1
You can retrieve the error message in Windows PowerShell, by using the following syntax.
Copy
PS C:\Users\adamr> try { invoke-restmethod http://localhost:5000/error2 } catch { [System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()).ReadToEnd()}
Whoa!
at , : line 2
at , : line 1
[](https://docs.powershelluniversal.com/api/error-handling#manually-returning-errors)
Manually Returning Errors
--------------------------------------------------------------------------------------------------------------------
To manually return errors, you need to use the `New-PSUApiResponse` cmdlet. This cmdlet allows you to define the status code and body for the response.
In this example, we are returning a 404 error code from the endpoint.
Copy
New-PSUEndpoint -Url /broken -Endpoint {
New-PSUApiResponse -StatusCode 404 -Body 'Failed!'
}
Similar to the automatic error codes, error codes returned manually will as display better in PowerShell 7. Here's an example of calling the endpoint.
Copy
PS C:\Users\adamr\Desktop> invoke-restmethod http://localhost:5000/broken
Invoke-RestMethod: Failed!
If called from Windows PowerShell, you will receive an error similar to the one returned automatically.
Copy
PS C:\Users\adamr> invoke-restmethod http://localhost:5000/broken
invoke-restmethod : The remote server returned an error: (404) Not Found.
At line:1 char:1
+ invoke-restmethod http://localhost:5000/broken
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], Web
Exception
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
You can choose to return error codes if certain conditions are met by using your PowerShell script within the endpoint.
Copy
New-PSUEndpoint -Url /user/:name -Endpoint {
if ($Name -eq 'User')
{
@{ UserName = "Adam" }
}
else
{
New-PSUApiResponse -StatusCode 404 -Body 'Unknown user!'
}
}
[](https://docs.powershelluniversal.com/api/error-handling#api)
API
------------------------------------------------------------------------
* [New-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUEndpoint.txt)
* [Get-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Get-PSUEndpoint.txt)
* [Remove-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Remove-PSUEndpoint.txt)
* [New-PSUApiResponse](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUApiResponse.txt)
* [Set-PSUSetting](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Set-PSUSetting.txt)
[PreviousSecurity](https://docs.powershelluniversal.com/api/security)
[NextRate Limiting](https://docs.powershelluniversal.com/api/rate-limiting)
Last updated 9 months ago
Was this helpful?
---
# Security | PowerShell Universal
Once enabled, you will be able to enforce authentication and authorization on your endpoints.
[](https://docs.powershelluniversal.com/api/security#defining-secure-endpoints)
Defining Secure Endpoints
--------------------------------------------------------------------------------------------------------------
You can define secure endpoints in the UI by enabling authentication. You will endpoint authentication and authorization under the Security tab of an endpoint's properties.
You can also define secure endpoints using the `.universal/endpoints.ps1` file or the Management API using `New-PSUEndpoint`.
Copy
New-PSUEndpoint -Url '/endpoint' -Method 'GET' -Endpoint {
"Hello, world!"
} -Authentication
When authentication is enabled, it will enforce the use of one of the configured authentication methods. APIs support the following methods.
* JWT App Tokens
* Windows Authentication
* Cookie Authentication
* Basic Authentication
[](https://docs.powershelluniversal.com/api/security#accessing-secure-endpoints)
Accessing Secure Endpoints
----------------------------------------------------------------------------------------------------------------
Once you have defined a secure endpoint, you will need to provide authentication and authorization to access the endpoint.
###
[](https://docs.powershelluniversal.com/api/security#authenticating-with-tokens)
Authenticating with tokens
Note that if you are hosting in IIS and do not have Anonymous Authentication enabled, you will not be able to pass app tokens to the PowerShell Universal server.
To authenticate with tokens, first, you need generate a new app token for use. You can use the `Grant-PSUAppToken` cmdlet to do so remotely or you can create an app token in the UI using the Settings Security AppTokens tab.
Hover over your user name in the top right of the admin console, click Tokens and click Create Application Token.
Once you have created your app token, you can now use it to authenticate against the secure endpoint. To do so, pass the Authorization header along with the request.
Copy
Invoke-RestMethod http://localhost:5000/auth -Headers @{ Authorization = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoIjoiMWUyY2IzNzAtMmMyNS00ZDU5LTk4YzgtMzc5MTFjMDAyZmI5Iiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYmYiOjE2MDU2NjEyNTUsImV4cCI6MTYzNzM2NzI1OCwiaXNzIjoiSXJvbm1hblNvZnR3YXJlIiwiYXVkIjoiUG" }
####
[](https://docs.powershelluniversal.com/api/security#custom-authorization-header)
Custom Authorization Header
PowerShell Universal provides a custom authorization header to support scenarios with reverse proxies that may require their own Authorization header. If the `X-PSU-Authorization` header is specified, PSU will ignore the `Authorization` header and use this header instead.
Copy
Invoke-RestMethod http://localhost:5000/auth -Headers @{
Authorization = "Bearer msft_xyz_123"
'X-PSU-Authorization' = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQWRtaW4iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9oYXNoIjoiMWUyY2IzNzAtMmMyNS00ZDU5LTk4YzgtMzc5MTFjMDAyZmI5Iiwic3ViIjoiUG93ZXJTaGVsbFVuaXZlcnNhbCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6IkFkbWluaXN0cmF0b3IiLCJuYmYiOjE2MDU2NjEyNTUsImV4cCI6MTYzNzM2NzI1OCwiaXNzIjoiSXJvbm1hblNvZnR3YXJlIiwiYXVkIjoiUG'
}
###
[](https://docs.powershelluniversal.com/api/security#authenticating-with-windows-authentication)
Authenticating with Windows Authentication
To authenticate with [Windows Authentication](https://docs.powershelluniversal.com/security/security#windows-authentication-in-iis)
, you can use the `-UseDefaultCredentials` parameter of `Invoke-RestMethod` and `Invoke-WebRequest` . This will perform negotiate authentication whether you are running inside IIS or a service.
Copy
Invoke-RestMethod http://localhost:5000/auth -UseDefaultCredentials
###
[](https://docs.powershelluniversal.com/api/security#authenticating-with-cookies)
Authenticating with Cookies
To authenticate with cookies, you will first need to call the login API to receive a valid cookie from the system. You can use `Invoke-WebRequest` to do so. Pass the user name and password as the body. Specify the `-SessionVariable` parameter to establish a session.
Copy
Invoke-WebRequest http://localhost:5000/api/v1/signin -Body (@{
UserName = "Admin"
Password = "Any"
} | ConvertTo-Json) -ContentType 'application/json' -SessionVariable mySession -Method POST
Once you have successfully authenticated, you can use your `$mySession` variable to call secure endpoints.
Copy
Invoke-WebRequest http://localhost:5000/auth -WebSession $mySession
[](https://docs.powershelluniversal.com/api/security#enforcing-roles)
Enforcing Roles
------------------------------------------------------------------------------------------
In addition to creating endpoints that require authentication, you can also enforce roles by define a role in the `New-PSUEndpoint` cmdlet or by selecting one in the UI. If a role is selected, it's possess the role.
Windows and Cookie authentication will assign roles based on the Identity of the user and the role policies as they are applied.
JWT app tokens will use the role that was defined when they were generated.
[](https://docs.powershelluniversal.com/api/security#api)
API
------------------------------------------------------------------
* [New-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUEndpoint.txt)
* [Get-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Get-PSUEndpoint.txt)
* [Remove-PSUEndpoint](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Remove-PSUEndpoint.txt)
* [New-PSUApiResponse](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSUApiResponse.txt)
* [Set-PSUSetting](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Set-PSUSetting.txt)
[PreviousEvent Hubs](https://docs.powershelluniversal.com/api/event-hubs)
[NextError Handling](https://docs.powershelluniversal.com/api/error-handling)
Last updated 2 months ago
Was this helpful?
---
# Rate Limiting | PowerShell Universal
Rate limiting requires a [license](https://ironmansoftware.com/pricing/powershell-universal)
.
PowerShell Universal lets you rate limit requests made to the web server. You can configure rate limiting per endpoint and per period. By default, the client IP address rate limits clients.
Configuration data for rate limits are stored in the `ratelimits.ps1` file.
[](https://docs.powershelluniversal.com/api/rate-limiting#configuring-rate-limiting)
Configuring Rate Limiting
-------------------------------------------------------------------------------------------------------------------
To configure rate limiting, visit the APIs / Rate Limiting page. Click the Add button and define a new rate limit rule.
Rate limiting affects all URLs for the server. If you enforce rate limiting that isn't correctly configured, you can negatively affect the management API.
###
[](https://docs.powershelluniversal.com/api/rate-limiting#method)
Method
The method is the HTTP method to for this rule. If you use `*` , this rule affects all HTTP methods. You can also select a single method by picking it from the drop down.
###
[](https://docs.powershelluniversal.com/api/rate-limiting#endpoint)
Endpoint
The endpoint is the URL that you are rate limiting. You can rate limit all URLs by using a `*`. You can define specific URLs by defining the relative path: `/api/user`.
###
[](https://docs.powershelluniversal.com/api/rate-limiting#limit)
Limit
This is the number of requests in the time frame before rate limiting kicks in.
###
[](https://docs.powershelluniversal.com/api/rate-limiting#period)
Period
This is the period over which the rate limit is counted. For example, if you select a period of 10 minutes and a limit of 100, then up to 100 requests can be made to the method and endpoint you have selected.
[](https://docs.powershelluniversal.com/api/rate-limiting#allow-lists)
Allow Lists
---------------------------------------------------------------------------------------
To disable rate limiting for particular IP Addresses, clients, and endpoints, add them to the rate limiting allow lists. Find these by clicking the settings button.
The below example prevents the loopback adapter from being rate limited.
Copy
Set-PSUSetting -RateLimitIpAddressAllowList @("127.0.0.1")
[](https://docs.powershelluniversal.com/api/rate-limiting#example-limit-custom-api)
Example: Limit Custom API
------------------------------------------------------------------------------------------------------------------
Limits callers of the `/api/users` endpoint to 100 requests per minute.
Copy
New-PSURateLimit -Endpoint "GET|/api/users" -TimeSpan "00:01:00" -Limit 100
[](https://docs.powershelluniversal.com/api/rate-limiting#example-limit-management-api)
Example: Limit Management API
--------------------------------------------------------------------------------------------------------------------------
Limits callers of the management API to 100 requests per second.
Copy
New-PSURateLimit -Endpoint "*|/api/v1/*" -TimeSpan "00:00:01" -Limit 100
[](https://docs.powershelluniversal.com/api/rate-limiting#api)
API
-----------------------------------------------------------------------
* [New-PSURateLimit](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/New-PSURateLimit.txt)
* [Set-PSUSetting](https://github.com/ironmansoftware/universal-docs/blob/v5/cmdlets/Set-PSUSetting.txt)
[PreviousError Handling](https://docs.powershelluniversal.com/api/error-handling)
[NextAbout Automation](https://docs.powershelluniversal.com/automation/about)
Last updated 4 days ago
Was this helpful?
---
# Email Protection | Cloudflare
Please enable cookies.
Email Protection
================
You are unable to access this email address docs.powershelluniversal.com
------------------------------------------------------------------------
The website from which you got to this page is protected by Cloudflare. Email addresses on that page have been hidden in order to keep them from being accessed by malicious bots. **You must enable Javascript in your browser in order to decode the e-mail address**.
If you have a website and are interested in protecting it in a similar way, you can [sign up for Cloudflare](https://www.cloudflare.com/sign-up?utm_source=email_protection)
.
* [How does Cloudflare protect email addresses on website from spammers?](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/)
* [Can I sign up for Cloudflare?](https://developers.cloudflare.com/fundamentals/setup/account/create-account/)
Cloudflare Ray ID: **96be3a3e4e3fde83** • Your IP: Click to reveal 54.237.218.47 • Performance & security by [Cloudflare](https://www.cloudflare.com/5xx-error-landing)
---