Users

All Posts (25)

avatar

SunnyJ

2026.3.4 - Endpoints Throwing Unexplained Exceptions

avatar
avatar
avatar

PSU: 2026.3.4

OS: Windows Server 2025

Hosting: IIS

I'm not sure what the best way to provide instructions on how to reproduce this; however, I have an API that worked fine in 2026.3.3, but in 2026.3.4, when I run it using the following regex definition, I get the following error:

URL = 'my/api/v1/Virtualization/Cluster/(?<VirtualizationClusterId>[0-9]+)/vLAN'; Method = @('POST'); Environment = 'Dedicated - API - v1'; Description = "APIv1 - Create new vLANs for the specified virtualization Cluster."; Regex = $True; Authentication = $True; Role = @('Administrator','PSUService')

Exception of type 'PowerShellUniversal.ApiResponseException' was thrown.
at ScriptBlock, D:\Powershell Universal\Repository\Scripts\vLANs.ps1: line 24
at ScriptBlock, No file: line 1

If I use the same script, but with the following definition (without regex), it works without error:

URL = 'my/api/v1/Virtualization/Cluster/:VirtualizationClusterId/vLAN'; Method = @('POST'); Environment = 'Dedicated - API - v1'; Description = "APIv1 - Create new vLANs for the specified virtualization Cluster."; Authentication = $True; Role = @('Administrator','PSUService')

For note, line 24 is the first line of the Param block, with the following:

[Parameter(Mandatory=$True,ParameterSetName='Post')]

I've also got another endpoint that worked in 2026.3.3, but after upgrading to 2026.3.4, I now get errors on (regex configured or not). I configured transcription for the whole script, which doesn't catch an error (makes it to the end of the script), but PSU returns the following error: "Object reference not set to an instance of an object"

[11/3/2026 4:59:52 PM] [Error] [Api-/my/api/v1/Computer/Request:POST|PATCH|DELETE] System.NullReferenceException: Object reference not set to an instance of an object.
   at UniversalAutomation.Host.PowerShellApiService.ExecuteRequest(ApiRequest request) in D:\a\powershell-universal\powershell-universal\src\Host\ApiService.cs:line 295
   at UniversalAutomation.Host.PowerShellApiService.ExecuteRequest(ApiRequest request) in D:\a\powershell-universal\powershell-universal\src\Host\ApiService.cs:line 295

I'm not sure what else I can provide to help further troubleshoot these.

2026.3.4 - Regex POST and PATCH APIs Not Working When App at Root

avatar
avatar
avatar

Hello Patrick,

Thanks for the follow up.

Good call on the non-regex option. I can use that for the time being. I've been trying to do regex for all of them to keep things consistent, but for the time being, I can use that to get around the bug.

I mainly ended up using the regex option as I would only need to configure one endpoint that could then support multiple in-line variables with varying requirements. Example:

URL = 'my/api/v1/NamingDictionary/(?<Dictionary>[A-Za-z0-9]+)/?(?<ID>[0-9]+)?'

This supports all the variations of what this endpoint needs to support.

However, if I configured it using the non-regex way:

URL = '/my/api/v1/NamingDictionary/:Dictionary/:Id'

I couldn't then call the endpoint with/my/api/v1/NamingDictionary/Location, I would need to include a / at the end to get it to work (alternately, I'd need to create a "different" endpoint, one that only had the :Dictionary value)..

As for the roles, I am in a group that is part of the endpoint role groups. I just removed some from the configuration provided as sanitization.

Thanks,

Jacob

2026.3.4 - Regex POST and PATCH APIs Not Working When App at Root

avatar
avatar
avatar

PSU: 2026.3.4

OS: Windows Server 2025

Hosting: IIS

I saw in the patch notes for 2026.3.4 that regex APIs were fixed in instances when you have an app set up at "/", and they partially are (as GETs work); however, it seems POST and PATCH methods do not work.

To reproduce, setup an app at "/" and then setup a RegEX API endpoint that supports POST and PATCH and returns some data. When attempting a POST or PATCH via Invoke-RestMethod externally (from a client system), you will receive a blank response. Logs indicate no endpoint is found/method not supported. Moving the app from "/" to some new home (ie "/Hosting"), the API will start accepting a POST or PATCH and return data.

If you use Invoke-PSUEndpoint, it will work in both situations.

Example configuration:

New-PSUApp -Name "Server Management" -FilePath "Dashboards\Server Management\Dashboard.ps1" -BaseUrl "/" -Environment "Dedicated - App - Server Management" -Authenticated -SessionTimeout 120 -IdleTimeout 60 -AutoDeploy -Description "Server Management Dashboard"

$Var = @{ URL = 'my/api/v1/Computer/Request'; Method = @('POST','PATCH','DELETE'); Environment = 'Dedicated - API - v1'; Description = "Request API" ;  Regex = $True ; Authentication = $True; Role = @('Administrator', 'Requestors'); Path = "D:\Powershell Universal\Endpoints\myendpoint.ps1" }
New-PSUEndpoint @Var

The above endpoint will not be triggered when called with Invoke-RestMethod. However, if you move the App to "/Hosting", the endpoint will work.

Logs attached. I also noticed in the systemLog that despite specifically using a POST, the initial logs show the request as a GET which is strange.

[2026.3.3] $ClaimsPrincipal is a JSON string

avatar
avatar
avatar

PSU 2026.3.3

IIS Hosted

Endpoint/API

$ClaimsPrincipal looks to be a json string instead of the [ClaimPrincipal] class as indicated in the documentation here: Variables | Devolutions PowerShell Universal | Product guides & reference.

Attempting to filter under the assumption that it's the .Net class fails:

$ClaimsPrincipal.Claims | ?{ $_.Issuer -eq 'https://www.poshtools.com' } | ?{ @('MyApproved','GroupsHere') -contains $_.Value })

Instead, I have to convert it from JSON to then be able to filter:

($ClaimsPrincipal | ConvertFrom-Json).Claims | ?{ $_.Issuer -eq 'https://www.poshtools.com' } | ?{ @('MyApproved','GroupsHere') -contains $_.Value }

Is this intentional or a bug? If it's intentional, the documentation should probably be updated.

Invoke-PSUEndpoint Oddities

avatar
avatar
avatar

I generally thought that using Invoke-PSUEndpoint for things internal to PSU would be the preferred method to keep things internal, would be faster, and also negates needing to gather/parse the hostname for the call (and technically the hostname would point to a LoadBalancer in front of our prod node which would involve additional hops). There's also instances where we need to retain the end user identity (in the case of calling auth/role limited API endpoints), which I believe using Invoke-RestMethod would lose, but if you're saying Invoke-RestMethod is the preferred/recommended best practice approach, I can change things to that (assuming I'd still need to use Invoke-PSUEndpoint to call endpoints that require retaining the identity of the user accessing the app page).

Invoke-PSUEndpoint Oddities

avatar
avatar
avatar

In that case, what's the best way to correct this?

Our general philosophy is most GET APIs are just open/don't require auth as the server is network protected (making it easier for other tools to integrate), but anything more elevated/secure requires auth and uses roles. Should I use -Integrated for these? Do I grant execute permission to everyone, but would that open execute to all APIs (including ones that are limited based on roles)?

Invoke-PSUEndpoint Oddities

avatar
avatar
avatar

PSU: 2026.3.3 (upgraded from 2026.1.2)

OS: Server 2025 IIS Hosted

In 2026.1.2, when I used Invoke-PSUEndpoint -Url '/my/endpoint/here'in an app to an endpoint where authentication was disabled, it worked as the endpoint did not require auth. Now in 2026.3.3, those calls are failing with "Permission denied. The role specified does not have access to this resource."

I can get around this, seemingly, by specifying -Integrated but NOT -UseDefaultCredentials despite the fact that the endpoint does not require authentication (-UseDefaultCredentials throws the same error as not having the arg).

Is this an expected change?

Is PSU being abandoned ?

avatar
avatar
avatar
avatar
avatar

It feels like it's still active, but that QA/the overall quality of the product had dropped. I've been running 2026.1.2 for quite a while as I've ran into bug after bug on newer versions that prevents me from updating our production servers and even in dev as say my RegEx endpoints aren't behaving as they had in versions up to 2026.1.2, or bugs with startup, built-in variables randomly missing, permissions not assigning properly, the list goes on... Some of this may be due to more hands working on it and not knowing how parts work, but some of the issues that have appeared should have been caught in early QA (ie the gRPC stuff that troubled 2026.3.x).

[2026.3.1] App Crash

avatar
avatar
avatar

Hello @rubentapia

I tried updating to 2026.3.3 as it mentioned a fix for something that was likely affecting this server:

> Fixed a system hang on startup when an invalid license file was installed.

There is an old license installed from the old way that dev instances were licensed (via generating a dev license from a licensed PSU server). PSU version 2026.3.3 works and I am able to load pages/the admin interface now. You can mark this item as resolved.

[2026.3.1] App Crash

avatar
avatar
avatar

Version: 2026.3.1

OS: 2025 Server Datacenter (latest Windows Updates - including the Out-Of-Band one)

.Net Core: 10.0.12 - Windows Server Hosting

IIS Hosted - App Pool running as a gMSA

Database: SQLite

Whenever I attempt to browse to PSU at all, even the /admin page, I get application crashes logged and the page errors out or the application pool crashes. This is the application crash I'm getting:

Faulting application name: w3wp.exe, version: 10.0.26100.1882, time stamp: 0xc6bd45bd
Faulting module name: e_sqlite3.DLL, version: 3.53.3.0, time stamp: 0x4b3d3b00
Exception code: 0xc00000fd
Fault offset: 0x0000000000115d7c
Faulting process id: 0xB68
Faulting application start time: 0x1DD4B6FADEF5BD3
Faulting application path: c:\windows\system32\inetsrv\w3wp.exe
Faulting module path: D:\Powershell Universal\e_sqlite3.DLL
Report Id: 840d3897-5d38-49f7-9c2b-968392a41442
Faulting package full name: 
Faulting package-relative application ID: 

(sometimes it references ntdll.dll, but that's typically a red herring)

This was happening on 2026.3.0 after upgrading from 2026.1.2, though that was routinely referencing D:\Powershell Universal\coreclr.dll.

What I've tried:

  • Verified the ZIP download hash.

  • Manually verfied files weren't blocked (I run a Get-ChildItem -Recurse | Unblock-File in the upgrade process)

  • Re-extracted and copied over our appsettings.json and web.confg.

  • Reviewed and updated the appsettings.json to contain any new settings that exist in the one from the zip

  • Upped the logging to debug in appsettings.json, I see a lot of lines about loading license information, but nothing that looks useful

The only error (tagged warning but has error in the message) in the systemLog file for PSU is the following:

2026-09-23 11:26:35.921 -04:00 [INF][UniversalAutomation.Services.UniversalConfigurationService] Reading configuration for Variable
2026-09-23 11:26:35.925 -04:00 [INF][ProtoBuf.Grpc.Server.ServicesExtensions.CodeFirstServiceMethodProvider] RPC services being provided by UniversalAutomation.IPublicGitSyncService: 5
2026-09-23 11:26:36.048 -04:00 [INF][Microsoft.AspNetCore.Hosting.Diagnostics] Request starting HTTP/1.1 GET https://<internalURL>/login?returnUrl=%2Fadmin - null null
2026-09-23 11:26:36.109 -04:00 [WRN][Microsoft.AspNetCore.Session.SessionMiddleware] Error unprotecting the session cookie.
System.Security.Cryptography.CryptographicException: The payload was invalid. For more information go to https://aka.ms/aspnet/dataprotectionwarning
   at Microsoft.AspNetCore.DataProtection.Cng.CbcAuthenticatedEncryptor.DecryptImpl(Byte* pbCiphertext, UInt32 cbCiphertext, Byte* pbAdditionalAuthenticatedData, UInt32 cbAdditionalAuthenticatedData)
   at Microsoft.AspNetCore.DataProtection.Cng.Internal.CngAuthenticatedEncryptorBase.Decrypt(ArraySegment`1 ciphertext, ArraySegment`1 additionalAuthenticatedData)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
   at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
   at Microsoft.AspNetCore.Session.CookieProtection.Unprotect(IDataProtector protector, String protectedText, ILogger logger)
2026-09-23 11:26:36.334 -04:00 [INF][Microsoft.AspNetCore.Routing.EndpointMiddleware] Executing endpoint '/Login'
2026-09-23 11:26:36.354 -04:00 [INF][Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker] Route matched with {page = "/Login", action = "", controller = ""}. Executing page /Login
2026-09-23 11:26:36.372 -04:00 [INF][Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker] Executing handler method PowerShellUniversal.Login.OnGet - ModelState is "Valid"
2026-09-23 11:26:38.618 -04:00 [INF][UniversalAutomation.Services.UniversalConfigurationService] Reading configuration for Translation
2026-09-23 11:26:38.623 -04:00 [INF][UniversalAutomation.Services.UniversalConfigurationService] Reading configuration for Settings

Both reverting to the 2026.1.2 folder and reverting the VM restores functionality.

For reference, my upgrade process is as follows:

  1. Create new folder, set ACL security on the folder for the gMSA.

  2. Extract the ZIP.

  3. Unblock recursively

  4. Copy web.conf and appsettings.json from the existing PSU folder to the new folder

  5. iisreset /stop

  6. Rename folders (old one gets datetime stamped, new one gets renamed to the original path)

  7. iisreset (to start IIS)

The database/repository folders are separate and outside the path of the IIS site, and are not touched. Database access looks functional based on the systemLog, as in debug logging, I see it sucesfully executing queries:

2026-09-23 11:52:15.845 -04:00 [DBG] Creating DbConnection.
2026-09-23 11:52:15.846 -04:00 [DBG] Created DbConnection. (0ms).
2026-09-23 11:52:15.846 -04:00 [DBG] Opening connection to database 'main' on server 'D:\PSUDB\database.workflows.db'.
2026-09-23 11:52:15.846 -04:00 [DBG] Opened connection to database 'main' on server 'D:\PSUDB\database.workflows.db'.
2026-09-23 11:52:15.846 -04:00 [DBG] Creating DbCommand for 'ExecuteReader'.
2026-09-23 11:52:15.846 -04:00 [DBG] Created DbCommand for 'ExecuteReader' (0ms).
2026-09-23 11:52:15.846 -04:00 [DBG] Initialized DbCommand for 'ExecuteReader' (0ms).
2026-09-23 11:52:15.846 -04:00 [DBG] Executing DbCommand [Parameters=[@filter_UsableAsActivity='?' (DbType = Boolean)], CommandType='"Text"', CommandTimeout='30']
SELECT "w"."Id", "w"."BinaryData", "w"."CreatedAt", "w"."Data", "w"."DefinitionId", "w"."Description", "w"."IsLatest", "w"."IsPublished", "w"."IsReadonly", "w"."IsSystem", "w"."MaterializerContext", "w"."MaterializerName", "w"."Name", "w"."OriginalSource", "w"."ProviderName", "w"."StringData", "w"."TenantId", "w"."ToolVersion", "w"."UsableAsActivity", "w"."Version"
FROM "WorkflowDefinitions" AS "w"
WHERE "w"."UsableAsActivity" = @filter_UsableAsActivity
ORDER BY "w"."CreatedAt"
2026-09-23 11:52:15.846 -04:00 [INF] Executed DbCommand (0ms) [Parameters=[@filter_UsableAsActivity='?' (DbType = Boolean)], CommandType='"Text"', CommandTimeout='30']
SELECT "w"."Id", "w"."BinaryData", "w"."CreatedAt", "w"."Data", "w"."DefinitionId", "w"."Description", "w"."IsLatest", "w"."IsPublished", "w"."IsReadonly", "w"."IsSystem", "w"."MaterializerContext", "w"."MaterializerName", "w"."Name", "w"."OriginalSource", "w"."ProviderName", "w"."StringData", "w"."TenantId", "w"."ToolVersion", "w"."UsableAsActivity", "w"."Version"
FROM "WorkflowDefinitions" AS "w"
WHERE "w"."UsableAsActivity" = @filter_UsableAsActivity
ORDER BY "w"."CreatedAt"
2026-09-23 11:52:15.846 -04:00 [DBG] Closing data reader to 'main' on server 'D:\PSUDB\database.workflows.db'.
2026-09-23 11:52:15.846 -04:00 [DBG] A data reader for 'main' on server 'D:\PSUDB\database.workflows.db' is being disposed after spending 0ms reading results.
2026-09-23 11:52:15.846 -04:00 [DBG] Closing connection to database 'main' on server 'D:\PSUDB\database.workflows.db'.
2026-09-23 11:52:15.846 -04:00 [DBG] Closed connection to database 'main' on server 'D:\PSUDB\database.workflows.db' (0ms).
2026-09-23 11:52:15.846 -04:00 [DBG] 'ManagementElsaDbContext' disposed.
2026-09-23 11:52:15.846 -04:00 [DBG] Disposing connection to database 'main' on server 'D:\PSUDB\database.workflows.db'.
2026-09-23 11:52:15.846 -04:00 [DBG] Disposed connection to database 'main' on server 'D:\PSUDB\database.workflows.db' (0ms).

I will note that I don't see any logs about it talking to the main DB, just this workflow db.

The final lines in the systemLog are always:

2026-09-23 11:54:28.550 -04:00 [DBG][UniversalAutomation.Common.Interfaces.ILicenseService] Loading license information.
2026-09-23 11:54:29.129 -04:00 [INF][UniversalAutomation.Services.UniversalConfigurationService] Reading configuration for Translation
2026-09-23 11:54:29.135 -04:00 [INF][UniversalAutomation.Services.UniversalConfigurationService] Reading configuration for Settings
2026-09-23 11:54:29.139 -04:00 [DBG][UniversalAutomation.Services.ConfigurationScript] Reading configuration file settings.ps1
2026-09-23 11:54:29.140 -04:00 [DBG][UniversalAutomation.Services.ConfigurationScript] File exists. Deserializing items.
2026-09-23 11:54:32.682 -04:00 [DBG][Universal.Server.Routing.UniversalEndpointDataSource] Endpoints changed. Notifying change token.

Any help on where to start further troubleshooting would be appreciated.

All apps/scripts not working on 2026.3.0

avatar
avatar
avatar
avatar
avatar

Could this cause PSU to not even fully start/load when hosted in IIS? I just updated our dev instance from 2026.1.2 to 2026.3.0 and PSU doesn't even load, instead I get an app crash:

Faulting application name: w3wp.exe, version: 10.0.26100.1882, time stamp: 0xc6bd45bd
Faulting module name: coreclr.dll, version: 10.0.1226.42308, time stamp: 0x6a89b724
Exception code: 0xc0000005
Fault offset: 0x00000000000b2514
Faulting process id: 0x1440
Faulting application start time: 0x1DD49E6BB46ABCB
Faulting application path: c:\windows\system32\inetsrv\w3wp.exe
Faulting module path: D:\Powershell Universal\coreclr.dll
Report Id: 33f29003-7320-45b8-9397-afc8e089117a
Faulting package full name: 
Faulting package-relative application ID:

The system logs that PSU spits out don't provide anything that's helpful and just stop after Reading configuration for Settings so I'm not sure if this is related or not. The only other log I've seen is in C:\ProgramData\PowerShellUniversal\Logs\PowerShellHost folder, all of the logs there have:

2026-09-21 14:14:45.705 -04:00 [ERR] Error checking module path 
System.ArgumentException: The path is not of a legal form.
   at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
   at System.IO.Path.InternalGetDirectoryName(String path)
   at UniversalHost.AgentService.Initialize(IHostLogger logger) in D:\a\powershell-universal\powershell-universal\src\Host\AgentService.cs:line 48

Passing Auth from App to API

avatar
avatar
avatar
avatar

Hello Ruben,

I've tried it with both Strict and Permissive.

My current related settings are:

#Relevant settings in appsettings.json
"Api": {
    "SecurityModel": "Strict",


"Authentication": {
    "Windows": {
      "Enabled": "true"
    }

#Settings in settings.ps1
$Parameters = @{
	LogLevel          = "Error"
	DefaultPage       = "Home"
	EnhancedAppTokenSecurity = $True
	ApiSecurityModel = "Medium"
	NotificationLevel = "Warning"
	DarkTheme         = $True
}
Set-PSUSetting @Parameters
	

We have both Windows authentication and anonymous auth configured in IIS, but this is specifically using Windows Auth.

I did some further testing of what variables are available in the API when accessed by the App using:

Get-ChildItem Variable: | Out-File D:\PSU\ScriptLogs\Temp.txt

There were no variables in that Temp.txt file that listed a username when using Invoke-PSUEndpoint.

Let me know if you need any more information.

Passing Auth from App to API

avatar
avatar
avatar
avatar

PSU: 2026.1.2

I've been looking over Module | Devolutions PowerShell Universal | Product guides & reference and tried using different auth security models and experimenting with different ways to accomplish this, I but have not had any luck.

I have a PSU API that to execute requires auth and with specific roles that can invoke it:

Authentication = $True
Role = @('Administrator','Approvers')

In that API it records the calling user's identity as part of the logging/audit tracking.

However, when I create an App that requires auth and the page has role limits, and then attempt to trigger that API, it doesn't seem to list the user that called it in any of the available variables regardless of how I seem to try to trigger it.

I've tried the following commands in both Strict and Permissive

Invoke-PSUEndpoint -Url "/api/v1/Build/1/Approve" -Method POST
Invoke-PSUEndpoint -Url "/api/v1/Build/1/Approve" -Method POST -Header $Headers
Invoke-RestMethod -Uri "$($PSUURL)/api/v1/Build/1/Approve" -Method POST

(the last one doesn't work, gives access denied error)

In all these the $Identity variable is empty, and I need that value (or some other variable that has the username that calls the API). I could add support to supply that in the post, but that opens it up to abuse and falsification, so I'd rather not do that.

Is there a proper way to accomplish this?

Additionally, what's the difference between defining the auth security model in appsettings.jsonvs .universal\settings.ps1 ApiSecurityModel? Or is it two different places to define the same thing?

UDTable On Row Click

avatar
avatar
avatar
avatar
avatar

Thanks for the follow up Ruben. I have submitted a feature request on that forum: OnRowClick for Tables - Devolutions Forum

OnRowClick for Tables

avatar
avatar
avatar
avatar

This is a request for a new Table feature to support a row click function that allows calling an endpoint (running commands) and is spawned from this item on the support form: UDTable On Row Click - Devolutions Forum

Essentially, it would be nice to support clicking anywhere in a table row to then perform some function, whether it be navigate to a new page based off data in the row, popping up a modal, or other options. This would help generate more interactive/dynamic pages and make things cleaner than the current options (configuring a clickable button per row).

The example I provided is as follows, which would pop up a modal displaying additional details on the row clicked:

 New-UDTable -LoadData {
  $Data } -Columns @(
    New-UDTableColumn -IncludeInExport -Id Id -Property Id -Title "Id" -Width 50
    New-UDTableColumn -IncludeInExport -Id ServerName -Property ServerName -Title "Server Name" -Width 150  
    New-UDTableColumn -IncludeInExport -Id CPUS -Property CPUS -Title "CPUs" 
    New-UDTableColumn -IncludeInExport -Id Memory_GB -Property Memory_GB -Title "Memory (GB)" 
    New-UDTableColumn -IncludeInExport -Id OperatingSystem -Property OperatingSystem -Title "Operating System" -Width 100
) -OnRowClick {
 Show-UDModal -FullWidth -Content {
    New-UDCard -Content {
        New-UDGridLayout -Content {
            $VMData = Invoke-PSUEndpoint -Integrated -Url "/api/v1/VM/$($EventData.Id)" | ConvertFrom-Json
            New-UDTextbox -Id 'Id' -Label 'Id' -Value $EventData.Id -Disabled
            New-UDTextbox -Id 'ComputerName' -Label 'ComputerName' -Value $EventData.ServerName -Disabled
            New-UDTextbox -Id 'Department' -Label 'Department' -Value $VMData.Department -Disabled
            New-UDTextbox -Id 'Owner' -Label 'Owner' -Value $VMData.Owner -Disabled
            New-UDTextbox -Id 'State' -Label 'State' -Value $VMData.State -Disabled
        }
      }
    }
  }

UDTable On Row Click

avatar
avatar
avatar
avatar
avatar

PSU 2026.1.2

I'm looking for a way to pop up additional information when clicking on a row (not selecting a row) in a UDTable. I know there's the expand row option, which opens an expand box below the row and there's the option of adding a custom button, but I was hoping there was a way to support clicking on the row and it could then support a code block (in my case, likely open a modal with the extended details of the row item).

For instance, the table would have like

 New-UDTable -LoadData {
  $Data } -Columns @(
    New-UDTableColumn -IncludeInExport -Id Id -Property Id -Title "Id" -Width 50
    New-UDTableColumn -IncludeInExport -Id ServerName -Property ServerName -Title "Server Name" -Width 150  
    New-UDTableColumn -IncludeInExport -Id CPUS -Property CPUS -Title "CPUs" 
    New-UDTableColumn -IncludeInExport -Id Memory_GB -Property Memory_GB -Title "Memory (GB)" 
    New-UDTableColumn -IncludeInExport -Id OperatingSystem -Property OperatingSystem -Title "Operating System" -Width 100
) -OnRowClick {
 Show-UDModal -Persistent -FullWidth -Content {
    New-UDCard -Content {
        New-UDGridLayout -Content {
            $VMData = Invoke-PSUEndpoint -Integrated -Url "/api/v1/VM/$($EventData.Id)" | ConvertFrom-Json
            New-UDTextbox -Id 'Id' -Label 'Id' -Value $EventData.Id -Disabled
            New-UDTextbox -Id 'ComputerName' -Label 'ComputerName' -Value $EventData.ServerName -Disabled
            New-UDTextbox -Id 'Department' -Label 'Department' -Value $VMData.Department -Disabled
            New-UDTextbox -Id 'Owner' -Label 'Owner' -Value $VMData.Owner -Disabled
            New-UDTextbox -Id 'State' -Label 'State' -Value $VMData.State -Disabled
        }
      }
    }
  }

And then when clicked on, it would display a bunch of additional information, like power state, health of tracked services, drives, other internal server tracking values that bloat the original table well beyond the width of the screen.

I know this could probably be done in an expand, but it requires you click on the dropdown button rather than just the row itself (and frankly looks ugly compared to a popup modal / so I'd just do a details button at that point), so I was hoping someone might have an idea or way to accomplish what I'm looking for as an on row click (anywhere in the row preferably).

Environment start scripts

avatar
avatar
avatar
avatar
avatar

Hello,

I've updated from 2026.1.2 to 2026.2.5 and it seems like this issue still exists.

New-PSUEnvironment -Name "Dedicated - App - Server Management" -Modules @('CustomModule1','CustomModule2','CustomModule3') -Variables @('*') -PersistentRunspace -StartupScript @('Dashboards\Server Management\Includes\Base.ps1') -Description "PS Environment for the Server Management environment." -Type "WindowsPowerShell" 

New-PSUApp -Name "Server Management" -FilePath "Dashboards\Server Management\Dashboard.ps1" -BaseUrl "/" -Environment "Dedicated - App - Server Management" -Authenticated -SessionTimeout 120 -IdleTimeout 60 -AutoDeploy -Description "Hosting Services and Automation Dashboard"

Upon loading a page from this App, it complains about missing functions that are loaded either directly as part of Base.ps1 or as other dot sourced files, example:

. '.\Includes\Base.ps1'
. '.\Includes\Dashboards\Debugging.ps1'

These dot sourced imports work fine in 2026.1.2 and I don't see any notes about there being significant changes to how these should work, so I'd assume they should still work?

I'll note that it seems that it doesn't even run the first few lines of `Dashboards\Server Management\Includes\Base.ps1` as that should start a transcription, which I'm not seeing done either.

Multiple Endpoints Using the Same File

avatar
avatar
avatar
avatar

So the goal is to leave the read access open to anyone so we don’t have to generate keys/they don’t have to use auths to pull data that is not considered private/secure. We call it dictionary data.

Now, obviously we want to restrict who can write/modify these. This is why I was trying to configure two different endpoints, but it seems PSU throws an error when trying to use the same file for multiple endpoints.

Multiple Endpoints Using the Same File

avatar
avatar
avatar
avatar

Is that possible if there aren’t any credentials/auths supplied in the request though? If there’s nothing to even attempt to auth with, doesn’t the API/Endpoint reject it as unauthenticated?

Multiple Endpoints Using the Same File

avatar
avatar
avatar
avatar

Interestingly, if you don’t set Authentication = True for the endpoint, both the identity and claimsprincipal do not populate even if you supply a cred (ie -UseDefaultCredentials), so I’m unable to manually handle validating authentication.

Yes, the end goal is to basically do the following:

@{ Path = 'C:\Repo\api\v1\NamingDictionary.ps1'; URL = 'api/v1/NamingDictionary/(?<Dictionary>[A-Za-z0-9]+)/?(?<ID>[0-9]+)?'; Method = @('GET'); Environment = 'Dedicated - API - v1'; Description = "Returns naming dictionary information based on requested dictionary and optionally ID." ;  Regex = $True }

@{ Path = 'C:\Repo\api\v1\NamingDictionary.ps1'; URL = 'api/v1/NamingDictionary/(?<Dictionary>[A-Za-z0-9]+)'; Method = @('POST'); Environment = 'Dedicated - API - v1'; Description = "Allows an administrator to configure a new dictionary code." ;  Regex = $True; Authentication = $True; Role = @('Administrator') }

This will result in 2 endpoints, but since they use the same code file, it throws an error when running the New-PSUEndpoint with the 2nd hashtable.

Multiple Endpoints Using the Same File

avatar
avatar
avatar
avatar
Product: PowerShell Universal
Version: 2026.1.2

Hello,

I’m trying to create multiple endpoints off the same script but it’s giving the following error:

Endpoint already exists at path

While the error is pretty self-explanatory, is there a reason why different endpoints can’t use the same code source?

What I’m trying to accomplish is support GET requests without authentication but require auth/roles for POST or PATCH, where the code handles all three of the options rather than splitting it across multiple files and having repeat code. Is there a good way to accomplish without using multiple files?

PowerShell Universal - 2026.1.6

avatar
avatar
avatar
avatar
avatar

I am still receiving the following after updating to 2026.1.6:

The 'ConvertTo-SecureString' command was found in the module 'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module Microsoft.PowerShell.Security'.

I’m also still having issues with regex-based APIs as reported in

Regex-style API endpoint route does not match requests, while equivalent documented :variable routes work · Issue #5606 · ironmansoftware/powershell-universal

Endpoints Not Reflecting GIT Updates

avatar
avatar
Product: PowerShell Universal
Version: 5.6.8

It seems that when PSU is configured for GIT syncs, updates for API endpoints are not reflected when GIT runs a sync.

For instance, if I update the actual endpoint code in .endpoints, that is not reflected.

New-PSUEndpoint -Url "/api/Build/:Id" -Method @('GET') -Authentication -Role @('BuildAdmin','Administrator') -Path "D:\PSU\Repository\endpoints\api_Build.ps1" -Environment "Windows PowerShell 5.1" 

Updated to include PATCH

New-PSUEndpoint -Url "/api/Build/:Id" -Method @('GET','PATCH') -Authentication -Role @('BuildAdmin','Administrator') -Path "D:\PSU\Repository\endpoints\api_Build.ps1" -Environment "Windows PowerShell 5.1" 

But the interface still shows it not having that method. It also reflects the old code if you look at the code for the endpoint, but the files in the repository show the updated code. Doing things against the endpoint also show the old behavior.

The only solution I have found is restarting the service.

Is it expected that you have to restart the service/run an iisreset to update endpoints (either the configuration of the endpoint or the backing code)?

Note, that I’m able to reproduce this on 2 PSU instances (running on different servers), though, they are using the same GIT source, just different branches.

Environment Startup Scripts Not Always Ran?

avatar
avatar
Product: PowerShell Universal
Version: 5.6.7

I’m working with an App page that uses a custom module that calls a remote API but requires auth. I have this module set as a module that is imported in the Environment that the App runs and I have a Startup Script that sets the credential for the module (module name/functions have been generalized).

Relevant config lines:

New-PSUApp -Name "Server Management" -FilePath "Dashboards\Server Management\Dashboard.ps1" -BaseUrl "/" -Environment "Dedicated - App - Server Management" -Authenticated -SessionTimeout 120 -IdleTimeout 60 -AutoDeploy -Description "Server Automation Dashboard"

New-PSUEnvironment -Name "Dedicated - App - Server Management" -Modules @('MyModule1','MyModule2') -Variables @('*') -PersistentRunspace -StartupScript @('Dashboards\Server Management\Includes\Base.ps1') -Description "PS Environment for the Server Management environment." -Type "WindowsPowerShell" 

#Snip from Dashboards\Server Management\Includes\Base.ps1
Set-MyModule1Credential -Environment $Global:ExecutionEnvironment.MyModule1 -Credential $Secret:CredModule1

This sets the credential within the module and is stored in a script variable inside the module so functions in that module can run without having to specify the credential every time (this module is used in manual work as well as this automation).

However, and it’s seemingly entirely random, it seems that sometimes on pages within the App that call this API, the thread/environment/PowerShell session that runs the API call has not ran the StartupScript and it prompts in the interface for a credential.

I have tried debugging this myself, to the extent of starting transcription in the Startup Script to capture verbose output:

if (!(Test-Path -Path "D:\PSU\ScriptLogs\ServerManagement\$([DateTime]::Now.ToString('yyyyMMdd'))")) { New-Item -ItemType Directory -Path "D:\PSU\ScriptLogs\ServerManagement\$([DateTime]::Now.ToString('yyyyMMdd'))" }
    Start-Transcript -Path "D:\PSU\ScriptLogs\ServerManagement\$([DateTime]::Now.ToString('yyyyMMdd'))\$([DateTime]::Now.ToString('yyyyMMddhhmmss-fff')).Transcript.log"

Despite throwing verbose logging all over the module and the App code where it calls this module, the transcript logs never show the verbose output that is logged before the module would manually ask for credentials (specifically because they’re not pre-set). With this in mind, are there situations where the Startup Script isn’t called?

The example code where I’m using a Module function where it works and sometimes it prompts for auth (note it’s even as random as, I could type 3 letters, and it works, and type the 4th letter and it prompts for auth - but most common is refresh the page and it will work or won’t work):

    New-UDAutocomplete -Id 'RequestUser' -Label 'Request User' -Value $CurrentValue -OnLoadOptions {
        try {
            if ($Body.Length -ge 3 -and $Body -match '^[A-Za-z0-9 ]*$') {
                "MyModule1 Loaded: $(Get-Module MyModule1 | Out-String)" | Write-Verbose -Verbose
                "EnvironmentMyModule1: $($Global:ExecutionEnvironment.MyModule1)" | Write-Verbose -Verbose
                "Request User search string: $($Body)" | Write-Verbose -Verbose
                (Get-MyModule1User -Environment $Global:ExecutionEnvironment.MyModule1 -DisplayName $Body).Value.DisplayName | ConvertTo-Json
            }
        } catch {}
    }

Any guidance or help figuring this out or if I’m misunderstanding something in how this works would be appreciated.

App Dashboard SubFolders

avatar
avatar
avatar
avatar
Product: PowerShell Universal
Version: 5.6.6

I’ve been trying to figure out how to use subfolders for page organization and still having them get parsed/show up as pages.

For example, I have a page “Function1 Page.ps1”

New-UDPage -Url '/Function1/Page1' -Name 'Function1 Page' -Title 'Test page' -Content {
"Test page"
}

If I have this in the root of the pages folder, it loads it, it shows up in the pages tab, and I can browse to it. However, if I move it to a sub directory (such as Function1) to match the url, the page is no longer loaded.

I have tried a few different ways to get this to work without success, such as

New-UDApp -Title 'PowerShell Universal' -Pages @(
    Get-UDPage -Name 'Function1 Page'
    Get-UDPage -Name 'Function1/Function1 Page'
    Get-UDPage -Name 'Function1\Function1 Page'
)

But nothing seems to work. Is there documentation on how this can be done or would anyone be able to provide guidance on doing this?

Thanks!

1 - 25 of 25 items