Users

All Posts (24)

avatar

wwong1

PowerShell Universal 2026.3 - Official gMSA Support and Recommended Installation Configuration

avatar
avatar
avatar

Hello @wwong1

Thank you for your patience.

We have raised the remaining gMSA architecture questions internally so we can provide guidance that accurately reflects the intended behavior and recommended configuration for PSU 2026.3.

At this point, we will wait for that internal clarification before providing a definitive recommendation regarding the PSU service identity, RunAs gMSA usage, and the appropriate Secret Management configuration.

I will update this thread as soon as we have the confirmed guidance.

Best regards,

Ruben Tapia

@rubentapia

We look forward to Devolution's response. We will explore migration to the new platform using a traditional service account model while the team gathers some clarity.

PowerShell Universal 2026.3 - Official gMSA Support and Recommended Installation Configuration

avatar
avatar
avatar

We are an existing PowerShell Universal Enterprise customer from Ironman Software and are currently planning/upgrading our deployment to PowerShell Universal 2026.3.

We would like clarification on Devolutions' current support stance and recommended configuration for using a Group Managed Service Account (gMSA) with PSU.

Specifically, can you confirm the supported and recommended configurations for the following?

  1. Running the PowerShell Universal Windows service itself under a gMSA

    • Is this officially supported in PSU 2026.3?

    • Are there any known limitations compared with running the service as LocalSystem?

    • Are there specific Windows rights, filesystem ACLs, registry permissions, or other configuration requirements that should be applied?

  2. Using gMSAs for RunAs / automation execution

    • Is the recommended model to run PSU itself as LocalSystem and use separate gMSAs for scripts, endpoints, or jobs that need domain access?

    • Can RunAs gMSAs be used when the PSU service itself is running under another gMSA or traditional domain service account?

    • Are there any restrictions on this configuration in 2026.3?

  3. Secret Management

    • Are there known limitations with PowerShell SecretManagement / SecretStore when the PSU service runs under a gMSA?

    • Does the built-in PSU secret functionality fully support a gMSA service identity, including after automatic gMSA password rotation?

    • Are there any vault types or configurations that you recommend or specifically discourage when PSU runs under a gMSA?

  4. Known-good / recommended installation pattern

    1. If available, could you provide the currently recommended enterprise deployment pattern for PSU 2026.3 where domain resources such as Active Directory, SQL Server, file shares, etc. need to be accessed?

For example, is the preferred architecture:

LocalSystem -> PSU -> RunAs gMSA(s) for privileged/domain actions

or

PSU gMSA -> domain resources directly

or another configuration?

I have reviewed the documentation and searched the Ironman Software forums. There are several older discussions where users report successfully using gMSAs, including password-less RunAs credentials, but there also appear to be issues or caveats around the PSU service identity, RunAs behavior, and Secret Management.

Before we standardize our 2026.3 installation, we would like to understand the officially supported and tested configuration from Devolutions, rather than relying on older community posts.

Thanks.

How do I securely run automation scripts that needs write rights in AD/Entra with a gMSA running the service?

avatar
avatar
avatar
avatar
avatar

Given:

  • gMSAs define who/what can get the always rotating creds (computer or

  • PSU runs as gMSA service account (ie - gMsaPsu)

Setup:

Let’s say you run a script in PSU. It executes in context of gMsaPsu. This can retrieve gMsaPsuAdAction, you can use gMSACredentialModule to handle the call.

$cred = Get-GMSACredential -GMSAName 'gMsaPsuAdAction' -Domain $env:userdnsdomain
Invoke-GMSACommand -Credential $cred -ScriptBlock {
  Add-AdGroupMemmber -Id $group -Members $member
}

Pretty much other methods of unattended action rely on a chain of trust and secrets cryptographically. The nice part here is all the secrets in this chain from machine account, psu service account, ad action is now rotated by AD automatically now.

Apptoken bloat - How to clean up?

avatar
avatar
avatar
avatar
avatar

We ran into the bug. We’re on SQL server. I revoked the token in the table, deleted the entries and also reset the id count so we’re back at the expected “normal” id range.

Windows Service: Recommended hardware

avatar
avatar
avatar
avatar
avatar

First off… we needed to set “Module Discovery Frequency” to once per day on our system. It was a feature that I asked for.

Without reference to what the actual jobs and code does… it’s a guess on what’s taking all the time. How long does it take to run? Can it go faster? which part of the code is slow?

From experience and looking at the screenshot… Import-Module can eat up lots of CPU and slow down the system a lot.

You also might not need to use Import-Module in a script. You can let powershell do the command inferencing. That can work with VMWare and Exchange modules which are slow to load.

You can architecturally move parts of the scripts into a long lived PSU environments and then internally call via API.

One of two server is missing default logging targets

avatar
avatar
avatar
avatar
avatar

I agree with this post about the documentation being lacking in this area. Some documentation about what the default or recommended minimum logging.ps1 file can be really helpful. Also, more logging examples for the cmdlets. Event logging is pretty important as it is generally one of the first steps taken in system auditability and a core component in the security of the system.

Can't get UDTable to Update

avatar
avatar
avatar
avatar
avatar

Here was my test code.

It seems to only work with Columns listed out and -LoadingComponent { New-UDProgress }

Seems like we have enough to make a repro.

Example:

New-UDDashboard -Title "Demo Test" -Content {

$Columns = @(
    New-UDTableColumn -Property Name -Title "Name" -ShowFilter
    New-UDTableColumn -Property Value -Title "Value" -ShowFilter
)

$ColumnsNofilter = @(
    New-UDTableColumn -Property Name -Title "Name"
    New-UDTableColumn -Property Value -Title "Value"
)

$Data = 1..10 | ForEach-Object {
  @{
      Name = "Record-$_"
      Value = $_ 
  }
}

New-UDButton -Text 'Get Filtered Data' -OnClick {
    $Element = Get-UDElement -Id 'filteredTable'
    Show-UDModal -Content {
        New-UDElement -Tag 'pre' -Content {
           $Element | ConvertTo-Json
        }
    }
}

New-UDTable -Id 'filteredTable' -Columns $Columns -LoadData {
    foreach($Filter in $EventData.Filters)
    {
        $Data = $Data | Where-Object -Property $Filter.Id -Match -Value $Filter.Value
    }

    $TotalCount = $Data.Count 

    if (-not [string]::IsNullOrEmpty($EventData.OrderBy))
    {
        $Descending = $EventData.OrderDirection -ne 'asc'
        $Data = $Data | Sort-Object -Property $EventData.orderBy -Descending:$Descending
    }
    
    $Data = $Data | Select-Object -First $EventData.PageSize -Skip ($EventData.Page * $EventData.PageSize)

    $Data | Out-UDTableData -Page $EventData.Page -TotalCount $TotalCount -Properties $EventData.Properties 
} -ShowFilter -ShowSort -ShowPagination -ShowSelection -DisableMultiSelect -Dense -OnRowSelection {
        Sync-UDElement 'dyNext'
        # Sync-UDElement 'selectedTable'
    }

New-UDDynamic -Id 'dyNext' -Content {
    $element = (Get-UDElement -id 'filteredTable').SelectedRows
    if (-not $element) {
        return
    }
    New-UDTable -Id "selectedTable" -Data $element -Columns $ColumnsNoFilter -Dense -RemoveCard

} -LoadingComponent {
    #Seems to be required to make selectedTable work
    New-UDProgress
}

}

Actual:

Removing -Columns $ColumnsNofilter and -LoadingComponent { New-UDProgress }

Selecting from filteredTable does not update the selectedTable.

New-UDDynamic -Id 'dyNext' -Content {
    $element = (Get-UDElement -id 'filteredTable').SelectedRows
    if (-not $element) {
        return
    }
    New-UDTable -Id "selectedTable" -Data $element -Dense -RemoveCard

}

Expected:

This should work.

Workaround:

Example code does work.

Can't get UDTable to Update

avatar
avatar
avatar
avatar
avatar

Adding Columns parameter should fix it.

$ColumnsVpg = @(
    New-UDTableColumn -Property VMName -Title "VM Name"
    New-UDTableColumn -Property PortName -Title "Port Name"
    New-UDTableColumn -Property VirtualSwitch -Title 'Virtual Switch'
)


New-UDTable -Title "Network" -Id 'vpg_table' -Data $PortGroups -RemoveCard -Dense -Columns $ColumnsVpg

PowerShell Universal - 4.2.0

avatar
avatar
avatar
avatar
avatar

Any additional information about Powershell Universal PWA? Can we define a custom/name PWA URL for a UD App/Dashboard?

I find that this feature would be very useful.

Completely clear PSUCache?

avatar
avatar
avatar

It would be nice to have a command like Get-PSUCacheStatistics or a Get-PSUCache -Metadata switch. Let’s us get metadata information to have an idea of what’s in the cache, memory, expiration.

PowerShell Universal - 4.1.6

avatar
avatar
avatar
avatar

I can confirm that I can reproduce this in “Windows Powershell 5.1” psu environment.

Set-UDElement reset by Sync-UDElement

avatar
avatar
avatar
avatar

Can you clarify how we can add a -Wait parameter? I experience similar problems with components.

PowerShell Universal - 4.1.6

avatar
avatar
avatar
avatar

Is the app not running in the Integrated environment? We get the same grpc problem.

PSU 4.0.12 Universal.Server.exe is crashing every 5 minutes from Groom service

avatar
avatar

The following fix helped. It was due to module discovery happening at roughly the same time which pulled in a module that interfered with SqlClient.

Modules are imported by module discovery · Issue #2664 · ironmansoftware/issues (github.com)

PSU 4.0.12 Universal.Server.exe is crashing every 5 minutes from Groom service

avatar
avatar
Product: PowerShell Universal
Version: 4.0.12

I’m on PSU 4.0.12 and it’s crashing every 5 minutes. This shows up in Application event log.

   at PowerShellUniversal.DatabaseLogging.Truncate(System.DateTime)
   at UniversalAutomation.GroomService.GroomLogMessages()
   at UniversalAutomation.GroomService.Groom()
   at DynamicClass.InvokeStub_GroomService.Groom(System.Object, System.Object, IntPtr*)

Application: Universal.Server.exe
CoreCLR Version: 7.0.222.60605
.NET Version: 7.0.2
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Stack:
   at Microsoft.Data.SqlClient.SNINativeMethodWrapper.SNIReadAsync(Microsoft.Data.SqlClient.SNIHandle, IntPtr ByRef)
   at Microsoft.Data.SqlClient.SNINativeMethodWrapper.SNIReadAsync(Microsoft.Data.SqlClient.SNIHandle, IntPtr ByRef)
   at Microsoft.Data.SqlClient.TdsParserStateObjectNative.ReadAsync(Microsoft.Data.SqlClient.SessionHandle, UInt32 ByRef)
   at Microsoft.Data.SqlClient.TdsParserStateObject.ReadSni(System.Threading.Tasks.TaskCompletionSource`1<System.Object>)
   at Microsoft.Data.SqlClient.SqlCommand.BeginExecuteNonQueryInternalReadStage(System.Threading.Tasks.TaskCompletionSource`1<System.Object>)
   at Microsoft.Data.SqlClient.SqlCommand.BeginExecuteNonQueryInternal(System.Data.CommandBehavior, System.AsyncCallback, System.Object, Int32, Boolean, Boolean)
   at Microsoft.Data.SqlClient.SqlCommand.BeginExecuteNonQueryAsync(System.AsyncCallback, System.Object)
   at System.Threading.Tasks.TaskFactory`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].FromAsyncImpl(System.Func`3<System.AsyncCallback,System.Object,System.IAsyncResult>, System.Func`2<System.IAsyncResult,Int32>, System.Action`1<System.IAsyncResult>, System.Object, System.Threading.Tasks.TaskCreationOptions)
   at System.Threading.Tasks.TaskFactory`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].FromAsync(System.Func`3<System.AsyncCallback,System.Object,System.IAsyncResult>, System.Func`2<System.IAsyncResult,Int32>, System.Object)
   at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQueryAsync(System.Threading.CancellationToken)
   at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__15.MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__15, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteNonQueryAsync>d__15 ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.RelationalCommand+<ExecuteNonQueryAsync>d__15, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteNonQueryAsync>d__15 ByRef)
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(Microsoft.EntityFrameworkCore.Storage.RelationalCommandParameterObject, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+<>c.<NonQueryResultAsync>b__14_0(Microsoft.EntityFrameworkCore.DbContext, System.ValueTuple`3<Microsoft.EntityFrameworkCore.Query.RelationalQueryContext,Microsoft.EntityFrameworkCore.Query.Internal.RelationalCommandCache,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<>c__DisplayClass30_0`2+<<ExecuteAsync>b__0>d[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<>c__DisplayClass30_0`2+<<ExecuteAsync>b__0>d[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<<ExecuteAsync>b__0>d<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<>c__DisplayClass30_0`2+<<ExecuteAsync>b__0>d[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<<ExecuteAsync>b__0>d<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<>c__DisplayClass30_0`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<ExecuteAsync>b__0(Microsoft.EntityFrameworkCore.DbContext, System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteImplementationAsync>d__31`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteImplementationAsync>d__31`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteImplementationAsync>d__31`2<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteImplementationAsync>d__31`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteImplementationAsync>d__31`2<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Func`4<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,System.Threading.CancellationToken,System.Threading.Tasks.Task`1<Microsoft.EntityFrameworkCore.Storage.ExecutionResult`1<Int32>>>, System.Func`4<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,System.Threading.CancellationToken,System.Threading.Tasks.Task`1<Microsoft.EntityFrameworkCore.Storage.ExecutionResult`1<Int32>>>, System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteAsync>d__30`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteAsync>d__30`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteAsync>d__30`2<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Start[[Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy+<ExecuteAsync>d__30`2[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.EntityFrameworkCore, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ExecuteAsync>d__30`2<System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,Int32> ByRef)
   at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[[System.ValueTuple`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Microsoft.EntityFrameworkCore.Relational, Version=7.0.5.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>, System.Func`4<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,System.Threading.CancellationToken,System.Threading.Tasks.Task`1<Int32>>, System.Func`4<Microsoft.EntityFrameworkCore.DbContext,System.ValueTuple`3<System.__Canon,System.__Canon,Microsoft.EntityFrameworkCore.Diagnostics.CommandSource>,System.Threading.CancellationToken,System.Threading.Tasks.Task`1<Microsoft.EntityFrameworkCore.Storage.ExecutionResult`1<Int32>>>, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.NonQueryResultAsync(Microsoft.EntityFrameworkCore.Query.RelationalQueryContext, Microsoft.EntityFrameworkCore.Query.Internal.RelationalCommandCache, System.Type, Microsoft.EntityFrameworkCore.Diagnostics.CommandSource, Boolean)
   at DynamicClass.lambda_method5972(System.Runtime.CompilerServices.Closure, Microsoft.EntityFrameworkCore.Query.QueryContext)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Linq.Expressions.Expression, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Linq.Expressions.Expression, System.Threading.CancellationToken)
   at Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.ExecuteDeleteAsync[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.Linq.IQueryable`1<System.__Canon>, System.Threading.CancellationToken)
   at PowerShellUniversal.DatabaseLogging.Truncate(System.DateTime)
   at UniversalAutomation.GroomService.GroomLogMessages()
   at UniversalAutomation.GroomService.Groom()
   at DynamicClass.InvokeStub_GroomService.Groom(System.Object, System.Object, IntPtr*)
   at System.Reflection.MethodInvoker.Invoke(System.Object, IntPtr*, System.Reflection.BindingFlags)
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at System.Reflection.MethodBase.Invoke(System.Object, System.Object[])
   at Hangfire.Server.CoreBackgroundJobPerformer.InvokeSynchronously(System.Object)
   at Hangfire.Server.CoreBackgroundJobPerformer.InvokeMethod(Hangfire.Server.PerformContext, System.Object, System.Object[])
   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(Hangfire.Server.PerformContext)
   at Hangfire.Server.BackgroundJobPerformer+<>c__DisplayClass10_0.<PerformJobWithFilters>b__0()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(Hangfire.Server.IServerFilter, Hangfire.Server.PerformingContext, System.Func`1<Hangfire.Server.PerformedContext>)
   at Hangfire.Server.BackgroundJobPerformer+<>c__DisplayClass10_1.<PerformJobWithFilters>b__2()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(Hangfire.Server.IServerFilter, Hangfire.Server.PerformingContext, System.Func`1<Hangfire.Server.PerformedContext>)
   at Hangfire.Server.BackgroundJobPerformer+<>c__DisplayClass10_1.<PerformJobWithFilters>b__2()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(Hangfire.Server.IServerFilter, Hangfire.Server.PerformingContext, System.Func`1<Hangfire.Server.PerformedContext>)
   at Hangfire.Server.BackgroundJobPerformer+<>c__DisplayClass10_1.<PerformJobWithFilters>b__2()
   at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(Hangfire.Server.PerformContext, System.Collections.Generic.IEnumerable`1<Hangfire.Server.IServerFilter>)
   at Hangfire.Server.BackgroundJobPerformer.Perform(Hangfire.Server.PerformContext)
   at Hangfire.Server.Worker.PerformJob(Hangfire.Server.BackgroundProcessContext, Hangfire.Storage.IStorageConnection, System.String, Hangfire.BackgroundJob, System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.Object> ByRef)
   at Hangfire.Server.Worker.Execute(Hangfire.Server.BackgroundProcessContext)
   at Hangfire.Server.BackgroundProcessDispatcherBuilder.ExecuteProcess(System.Guid, System.Object)
   at Hangfire.Processing.BackgroundExecution.Run(System.Action`2<System.Guid,System.Object>, System.Object)
   at Hangfire.Processing.BackgroundDispatcher.DispatchLoop()

Can't get UDTable to Update

avatar
avatar
avatar
avatar
avatar

It’s an array but you’re processing it like a single item.

New-UDTable -Title "Host" -Id 'vmhost_table' -Data $Hosts -PageSize 10 -ShowSearch -StickyHeader -ShowPagination -ShowSort -DisableSortRemove -ShowSelection -DisableMultiSelect -Columns $HostsColumns -DisablePageSizeAll -OnRowSelection { 
                Sync-UDElement -Id 'dyVpg'
                Sync-UDElement -Id 'vpg_table'
                }

New-UDDynamic -Id 'dyVpg' -Content {
    
    $SelectedVMHostList = $(Get-UDElement -id 'vmhost_table').selectedRows | Select-Object Name

    $VMPortList = $SelectedVMHostList | Foreach-Object {
        $VMName = $_.Name
        $VMHost = get-vmhost -Name $VMName
        $PortGroups = $VMHost | Get-VirtualPortGroup | Select Name, VirtualSwitch
        $PortGroups | ForEach-Object {
            [pscustomobject]@{
                VMName          = $VMName
                PortName        = $_.Name
                VirtualSwitch   = $_.VirtualSwitch
            }
        }
    }

    if ($VMPortList) {
        # New-UDTypography -Text "$($PortGroups | Out-String)" -Id "typography4" -GutterBottom
        New-UDTable -Title "Network" -Id 'vpg_table' -Data $VMPortList -RemoveCard -Dense
    }

PSU Logging Target using TCP or UDP

avatar
avatar
avatar

UDP works now.

New-PSULoggingTarget -Type "UDP" -Level "Debug" -Properties @{
    hostName = 'syslog'
    port     = '514'
} -Resource "Audit"

TCP version still throws an error.

2023-08-16 19:47:55.139 -04:00 [ERR] Failed to read configuration file. logging.ps1
System.ArgumentNullException: Value cannot be null. (Parameter 's')
   at System.Int32.Parse(String s)
   at UniversalAutomation.Services.LoggingTargetsConfigurationScript.<>c__DisplayClass8_1.<OnReadAfterAllAsync>b__3(LoggerConfiguration lc) in C:\actions-runner\_work\universal\universal\src\Universal.Server\Services\Configuration\LoggingTargets.cs:line 76
   at Serilog.Configuration.LoggerSinkConfiguration.Logger(Action`1 configureLogger, LogEventLevel restrictedToMinimumLevel, LoggingLevelSwitch levelSwitch)
   at UniversalAutomation.Services.LoggingTargetsConfigurationScript.OnReadAfterAllAsync(Boolean initialSync) in C:\actions-runner\_work\universal\universal\src\Universal.Server\Services\Configuration\LoggingTargets.cs:line 76
   at UniversalAutomation.Services.ConfigurationScript`1.ReadAsync(String rootPath, Boolean initialSync) in C:\actions-runner\_work\universal\universal\src\PowerShellUniversal\ConfigurationScript.cs:line 309

PSU Logging Target using TCP or UDP

avatar
avatar
avatar
Product: PowerShell Universal
Version: 4.0.9

Anybody get TCP logging to syslog working in 4.0.9?

File and database logs work. Also get an error with the configuration.

Invalid configuration: logging.ps1

Uri should be in the format tcp://server:port

New-PSULoggingTarget -Type "TCP" -Properties @{
    hostName = 'syslog'
    port     = '514'
} -Feature "Automation" -Resource "syslogtest"
New-PSULoggingTarget -Type "File" -Level "Debug" -Properties @{
    path = 'c:\logs\psu\syslogtest'
} -Feature "Automation" -Resource "syslogtest" 

Write-PSULog -Feature Automation -Message "msg=Write-PSULog syslog test, key1=value1, key2=value2" -Level Information -Resource "syslogtest"

System Log

2023-08-07 14:14:53.020 -04:00 [ERR] Failed to read configuration file. logging.ps1
System.ArgumentNullException: Uri should be in the format tcp://server:port
 ---> System.UriFormatException: Invalid URI: The format of the URI could not be determined.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
   at System.Uri..ctor(String uriString)
   at Serilog.Sinks.Network.NetworkLoggerConfigurationExtensions.BuildUri(String s)
   --- End of inner exception stack trace ---
   at Serilog.Sinks.Network.NetworkLoggerConfigurationExtensions.BuildUri(String s)
   at Serilog.Sinks.Network.NetworkLoggerConfigurationExtensions.TCPSink(LoggerSinkConfiguration loggerConfiguration, String uri, ITextFormatter textFormatter, LogEventLevel restrictedToMinimumLevel)
   at Serilog.Sinks.Network.NetworkLoggerConfigurationExtensions.TCPSink(LoggerSinkConfiguration loggerConfiguration, String host, Int32 port, ITextFormatter textFormatter, LogEventLevel restrictedToMinimumLevel)
   at UniversalAutomation.Services.LoggingTargetsConfigurationScript.<>c__DisplayClass8_1.<OnReadAfterAllAsync>b__3(LoggerConfiguration lc) in C:\actions-runner\_work\universal\universal\src\Universal.Server\Services\Configuration\LoggingTargets.cs:line 76
   at Serilog.Configuration.LoggerSinkConfiguration.Logger(Action`1 configureLogger, LogEventLevel restrictedToMinimumLevel, LoggingLevelSwitch levelSwitch)
   at UniversalAutomation.Services.LoggingTargetsConfigurationScript.OnReadAfterAllAsync(Boolean initialSync) in C:\actions-runner\_work\universal\universal\src\Universal.Server\Services\Configuration\LoggingTargets.cs:line 76
   at UniversalAutomation.Services.ConfigurationScript`1.ReadAsync(String rootPath, Boolean initialSync) in C:\actions-runner\_work\universal\universal\src\PowerShellUniversal\ConfigurationScript.cs:line 309

PSScriptAnalyzer "using module" marking as script parse error

avatar
avatar
Product: PowerShell Universal
Version: 4.0.9

I have a custom module. I noticed that PSScriptAnalyzer seems to have an issue with reliably analyzing the script and marks the first line “using module TestModule“ as an error. This is fine except it prevents me from ignoring it and saving the file.

Is it possible to disable this specific check?

One possibility may be updating psscriptanalyzersettings.psd1 defaults. But I can’t seem to get it to work.

RuleName                            Severity     ScriptName Line  Message
--------                            --------     ---------- ----  -------
ModuleNotFoundDuringParse           ParseError   Test.ps1   1     Could not find the module 'TestModule'.

Slow script performance and bandwidth amplification O(n^2) when pipeline outputting many large items with SQL server back-end

avatar
avatar

I wanted to provide a reproduction of PSU 4.0.9 performance/bandwidth issue when outputting to the pipeline. This may be helpful for other people experiencing this issue.

Conditions

  • Script outputs to pipeline with many objects of non-trivial sice (example is 4000 items of ~4KB = 16 MB)

  • Set Script properties to keep only a small number of job history

  • Pipeline output goes SQL Server backend triggering high bandwidth usage for duration of script run

Cause

As the pipeline gets filled, it send the whole thing back to SQL Server in an UPDATE statement for the job. In the example below, PSU needs to send to SQL about ~16 - 32 GB (4000 * 16 MB / 2 or ~32 GB) for a 32 MB object.

UPDATE [JobLog] SET [Log] = @p0
OUTPUT 1
WHERE [Id] = @p1;
@p1=3456,@p0=N'[{"Type' . . .

Workaround

Instead of streaming the 4000 objects to the pipeline, create one [pscustomobject] to contain the stream. And then output to pipeline once.

Example Code

param([switch]$StreamArray)
#Test-PSUPipelinePerformanceBug.ps1

# Create 4000 by ~4KB objects
$x = Foreach ($i in (1..4000)) {
    [pscustomobject]@{
        id = $_
        text = 'abcd'*(1KB)
    }
}

if ($StreamArray) {
    # This outputs to pipeline runs with O(N^2) based on number of objects in $x.
    # This estimates to send about 16-30 GB over the wire to SQL
    # because EF Core needs to fetch the full JobLog data first before you can append to it, then send the whole thing back to SQL Server in an UPDATE statement.
    # SLOW - ~58s
    $x
} else {
    # This outputs one object to pipeline and a single update statement which is fast
    # FAST  - ~1s
    [pscustomobject]@{
        objects = $x
    }
}

LiteDB -> SQL slowness

avatar
avatar
avatar
avatar
avatar

We switched from LiteDB to SQL. I have a bunch of dashboards that rely on very large pipeline output from scripts to drive tasks. Are there any performance recommendations that we should consider?

I do not understand the jobs status codes

avatar
avatar
avatar
avatar
avatar

What’s the expected timeline on 4.1? This is a useful feature for us. We kind of work with it but it makes way more sense for lots of jobs.

Vscode module PSU how trust self signed cert?

avatar
avatar
avatar
avatar
avatar

Can this be added to the PSU VS Code documentation?

This is a similar problem with using enterprise root certificates in VS Code. If you’re using a self signed cert, you’ll also need to have the right CN and SANs and added to trusted root certificates.

Then the procedure below should get it working. The extension explains what it does.

  1. Install the win-ca (win-ca - Visual Studio Marketplace). This extension allows VS Code to inject additional certificates into the Certificate Chain that Extensions use.

  2. Once this is installed open the command palate (control-shift-P) and type “Open User Settings” choose the “Open User Settings (JSON)” option and add the settings below:

"http.proxyStrictSSL":true,

"win-ca.inject":"append"

  1. With this complete you will need to reload VS Code. You can do this by opening the command palate again (control-shift-P) and searching for “Reload Window”.

Pass variables into Invoke-PSUScript

avatar
avatar
avatar
avatar

I have a script that takes input parameters. I want to pass the variables from a dashboard using Invoke-PSUScript -Integrate. I don’t see in the documentation a way to pass variables as script parameters. Is this possible?

Product: PowerShell Universal
Version: 2.9.2

1 - 24 of 24 items