Portable, Side-by-Side PowerShell Universal Instances

PowerShell PowerShell Universal

July 31, 2024

quote Discuss this Article

This blog post walks through how to setup isolated PowerShell Universal instances on the same machine. This is useful for testing different versions of PowerShell Universal or for running multiple instances on the same machine. If you would like to see a video of this process, you can watch it here.

Introduction

You may want to run multiple instances of PowerShell Universal on the same machine for a variety of reasons. You may want to test different versions of PowerShell Universal, you may want to play with different server configurations or simply isolate different resources to different environments. We use this technique extensively in our testing and development environments.

Installation

The first step is to setup a folder to host your PowerShell Universal app and configuration files. Next, you will need to download the PowerShell Universal ZIP file and place it into an App directory. You can use the following script to retrieve the latest version 4 build and extract to the a local directory. Create an update.ps1 script in your directory and run it.

$Version = (Invoke-WebRequest https://imsreleases.blob.core.windows.net/universal/production/v4-version.txt).Content

Write-Verbose "Downloading $Version..."

$Temp = [System.IO.Path]::GetTempPath()
$Zip = (Join-Path $Temp "Universal.$Version.zip")

if (Test-Path $Zip) {
    Remove-Item $Zip -Force
}

Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$version/Universal.win7-x64.$Version.zip" -OutFile $Zip
$AppPath = Join-Path $PSScriptRoot "App"
if (Test-Path $AppPath) {
    Remove-Item $AppPath -Recurse -Force
}

Expand-Archive -Path $Zip -DestinationPath $AppPath
Get-ChildItem $AppPath -Recurse | Unblock-File

If you want to use version 5, you would change the v4-version.txt portion of the version URL to v5-version.txt. You can also hard code the version if you want to use a specific version. Within the actual blob URL for the ZIP, you may have noticed the win7-x64 portion. This is the platform that the ZIP is built for. You can change this to linux-x64 or osx-x64 if you are running on a different platform. Visit our download page to see how these URLs are formatted if the blob is not available.

Configuration

Next, create a run.ps1 in your directory to setup the configuration settings for your instance. They will use relative paths for the Repository, Database, and log files. Below, we are using environment variables to set the configuration based on the appsettings.json file found in the App folder. Any environment variables will override the settings in the appsettings.json file.

param($Port = 5000)

$ENV:Data__RepositoryPath = "$PSScriptRoot\Repository"
$ENV:Data__ConnectionString = "Data Source=$PSScriptRoot\Database.db"
$ENV:Kestrel__Endpoints__HTTP__Url = "http://localhost:$Port"
$ENV:Plugins__0 = "SQLite"
$ENV:SystemLogPath = "$PSScriptRoot\Logs\SysLog.txt"

& "$PSScriptRoot\App\Universal.Server.exe"

This script will setup the configuration for your instance. You can run this script with a specific port to start your instance. You can duplicate this script to another directory and change the port to run multiple instances. Each instance will have its own configuration and data. You cannot share ports between instances unless you are using IIS.