PowerShell Execution Engine

Discover how the PowerShell Execution Engine processes commands, optimizes performance, and enhances script execution efficiency.

Overview

The ESMP PowerShell Execution Engine provides a flexible way to implement custom business logic using PowerShell scripts.

PowerShell scripts can be integrated with various ESMP processes, including Workflows, Engines, and Compliance Rules, covering a wide range of business use cases.

This article describes how to:

  • Configure PowerShell scripts
  • Define their execution environment
  • Author input and output parameters
  • Test and troubleshoot scripts
  • Execute scripts from Workflows
  • Load Matrix42 assemblies and modules

Starting with version 26.2, the new PowerShell Execution Engine is available through the PowerShell Script configuration item.

 

PowerShell Execution Engine

Starting with 26.2, ESMP provides a new PowerShell Execution Engine based on the PowerShell Script configuration item.

A PowerShell Script object contains both the script definition and its execution configuration, including:

  • Required Worker capabilities
  • Execution mode
  • Data Layer requirements
  • Input and output parameters
  • Execution timeout

PowerShell scripts are executed on a Functional Worker. They are no longer executed directly in the Web Application process.

Execution Process

The execution environment can be controlled through the script configuration.

Worker Capabilities

Use Capabilities to specify the requirements of the Worker that executes the script. A script is dispatched only to a Worker that provides all required capabilities. This allows scripts to run on a specific Worker or on a Remote Worker that provides access to required resources or installed components.

For example, capabilities can be used to implement a data-gateway pattern, where a script is executed on a Remote Worker with access to a specific network or system resource.

PowerShell Version

The new PowerShell Execution Engine runs scripts in a .NET process with PowerShell 7. This allows scripts to run on both Windows and Linux environments.

The legacy script execution triggered by the Invoke PowerShell Workflow Activity continues to use PowerShell 2.0 and can be executed exclusively in a Windows .NET Framework process.

Recommendation: Use the new .NET/PowerShell 7 execution model whenever possible. The legacy execution model is intended for scripts that still require the Windows .NET Framework environment and is planned for discontinuation in a future release.

Cross-Platform Execution

Depending on the ESMP deployment model, the same PowerShell script can be executed on different platforms. For on-premises deployments, the default process for script execution is the Windows .NET Realtime Worker. For Cloud container deployments, the default process is the Linux .NET Realtime Worker.

If a script is part of an Extension that can be installed in different ESMP environments, make sure that the script is either:

  • platform-agnostic, so that it can run on both Windows and Linux, or
  • configured with the required Capabilities to ensure that execution is dispatched to a Worker running on the required platform.

Tip: Avoid platform-specific dependencies in reusable Extensions whenever possible. If a script requires a specific operating system, use Worker capabilities to explicitly control where it is executed.

Isolated Execution

Enable Run Isolated to execute the script in a dedicated Functional Worker process.

The process is created for the script execution and released afterwards.

Use isolated execution when:

  • the script is long-running
  • the script consumes significant resources
  • the script has potential assembly or dependency conflicts
  • resources used by the script should be released after execution

Isolated execution requires additional resources because a separate process must be initialized, and needs to be used wisely.

 

Data Layer

Enable Require Data Layer only when the script uses Data Layer operations, for example $M42_DatabaseProvider.

Initializing the Data Layer requires additional memory and startup time.

Using Require Data Layer together with Run Isolated can therefore result in significant additional resource consumption. Use this combination primarily for heavy or infrequently executed scripts that actually require Data Layer access.

PowerShell Script Configuration Item

The PowerShell Script configuration item was introduced in 26.2.

You can manage PowerShell scripts under:  Administration → Services & Processes → Scripts

The configuration item stores both the script and its execution metadata.

Properties

Property Description
Capabilities Defines the minimum capabilities required from the Worker. The script is dispatched only to Workers providing all specified capabilities.
Purpose Categorizes the script by its intended purpose.
Require Data Layer Initializes the Data Layer for the script. Enable only when Data Layer operations are required.
Long Running Allows a Workflow to be suspended while the script is executing and resumed after the script completes.
Timeout Defines the maximum execution time for a Long Running script. The maximum timeout is 2 hours.

Long-Running Scripts

When Long Running is enabled for a script executed by a Workflow, the Workflow is suspended while the PowerShell script executes. After the script finishes, the Workflow is resumed.

This reduces the resources held by the Workflow during long-running operations and improves resilience. However, suspending and resuming a Workflow introduces additional processing overhead. Use the option only when the script execution justifies it.

The maximum configurable timeout is 2 hours. If a process requires more than 2 hours, split it into multiple steps, for example by using two Workflow Activities.

ScriptParameters

The PowerShell Script object maintains the input and output parameters detected and populated after the first script execution. These parameters are used by the Execute PowerShell Workflow Activity and are displayed in Workflow Studio and Workflow Designer.

Once a parameter is detected, you can adjust the detected parameters to improve their presentation and data classification.

For example:

  • define a user-friendly parameter title
  • mark an input parameter as Required
  • classify a GUID as a specific Configuration Item or Data Definition
  • adjust the detected data type

Data Types

The engine automatically detects the data type of simple values and arrays of simple values. Complex values are represented as an Object or an array of Objects. For complex parameters, the detected Schema is also preserved. Workflow Designer can use this schema to provide the appropriate data model for the parameter.

Testing PowerShell Scripts

Use the Run Script action of the PowerShell Script configuration item to test the script.

Running the script with concrete input parameters and execution settings helps you:

  • verify the execution configuration
  • discover input and output parameters
  • stabilize the script
  • troubleshoot errors
  • verify Worker and execution-mode requirements

The first execution is particularly important because the PowerShell Script object uses the execution results to discover its input and output parameters.

For diagnostic output, use standard PowerShell Write-* commands, for example:

Write-Output "Processing started"
Write-Error "An error occurred"

The output is displayed in the Run Script terminal and can be used during script development and troubleshooting.

PowerShell Integration

The Product provides multiple integration points where custom logic can be implemented using PowerShell scripts, including:

Using PowerShell in Workflows

Execute PowerShell

The Execute PowerShell Workflow Activity was introduced in 26.2 and is available in both Workflow Studio and Workflow Designer.

The Activity references a dedicated PowerShell Script configuration item.

Before using the script in a Workflow, execute it at least once using Run Script. This allows the system to discover the input and output parameters. The Workflow Activity can then render the corresponding parameters and data models at design time.

Advantages

The dedicated PowerShell Script object provides several advantages compared with the legacy Invoke PowerShell Activity:

  • Independent script lifecycle — the script is maintained outside the Workflow and can be developed and tested independently.
  • Flexible execution — the script can run in the required Worker and execution mode.
  • Remote Worker support — capabilities can dispatch the script to a Remote Worker.
  • Isolated execution — scripts can run in a dedicated process when required.
  • Long-running execution — Workflows can be suspended while the script runs.
  • Configurable timeout — long-running scripts can have an explicit execution timeout.

Recommendation: Use Execute PowerShell for new Workflow implementations.

Properties

Name Description
Input Properties
Script Required. Reference to the PowerShell Script configuration item. Before selecting a script, make sure it has been executed at least once using Run Script so that its input and output parameters can be discovered.
Parameters List of PowerShell script input parameters. The parameters are automatically populated when the Script is selected. Provide the appropriate values for the input parameters, especially for required parameters.
Output Properties
Completed Indicates whether the script execution completed successfully.
Ignore on Error Specifies whether the Workflow Engine should continue executing the Workflow instance when the PowerShell script execution fails
Results List of output parameters returned by the PowerShell script. The results can be assigned to Workflow variables of the corresponding data types.
Errors List of errors that occurred during script execution. This parameter is available only when Completed is False.

Invoke PowerShell

"Invoke PowerShell" Workflow Activity is the legacy PowerShell Workflow Activity available in Workflow Studio.

It can still be used for existing Workflows, but it has several limitations compared with Execute PowerShell.

  • Script lifecycle. The script is defined directly inside the Workflow Activity and stored in the Workflow definition (XAML). This makes it harder to develop, test, and maintain the script independently and can result in additional Workflow versions during script development.
  • Execution environment. The script is executed in the Workflow process using the legacy .NET Framework PowerShell 2.0 environment. It cannot be dispatched to another Worker or executed in an isolated process.
  • Long-running scripts. A long-running script keeps the Workflow process occupied for the entire execution time. This can increase resource consumption and, in extreme cases, affect system stability.

Because the script executes directly in the Workflow process and does not require queue-based dispatching, Invoke PowerShell can have lower execution overhead for small scripts that execute frequently.

Run on Server Nehavior

Starting with 27.1, the Run on Server option of the Invoke PowerShell Activity no longer executes the script in the Web Application process.

 

Regardless of the configuration, the script is executed on the Windows Worker running the Workflow.

If a script must run on a specific machine, migrate it to Execute PowerShell and use Capabilities to control Worker dispatching.

PowerShell 7 in Invoke PowerShell

The legacy Invoke PowerShell Activity can execute a script through the queue using the .NET process with PowerShell 7.

To explicitly request this execution mode, add the following directive to the script:

#ps-execution-engine=7

Deprecated: This approach was introduced before 26.2. For new implementations, use the Execute PowerShell Workflow Activity instead.

Using PowerShell in UUX

In ESM Application PowerShell Script used in:

In the current implementation, User-defined System Diagnostic Rules and Scripted Web Operations provide their own script definition dialogs. Starting with 27.1, these integration points are being reworked to use the unified PowerShell Execution Engine.

Authoring PowerShell Scripts

Input Parameters

Define input parameters using the standard PowerShell param() statement.

param(
   [int]$Count = 5000,
   [Parameter(
       Mandatory = $true,
       HelpMessage = 'Also emit a pipeline stream on top of the variable outputs.'
   )]
   [bool]$EmitPipeline = $true,
   $NonTyped
)

The PowerShell Execution Engine analyzes the parameters during execution and makes them available through the PowerShell Script configuration item.

Output Parameters

Output values can be returned in two ways.

Use the predefined [Output] attribute to explicitly define named output parameters. 

[Output]$IntOutputParam = $Count * 10
[Output]$Summary = [pscustomobject]@{
     Count       = $Count
     ElapsedMs   = $sw.ElapsedMilliseconds
     GeneratedAt = (Get-Date).ToString('o')
 }

The resulting values are detected and added to the PowerShell Script object's output parameters after execution.

Importing Matrix42 Modules

PowerShell scripts run in a Functional Worker process. Depending on the execution mode, not all Matrix42 assemblies and business components are loaded automatically. Additional modules can be loaded using the standard PowerShell Import-Module command or the Matrix42-specific Import-M42Module cmdlet.

Import-M42Module <AssemblyName> [-PackageNameOrId <string>] [-RegisterDependencies]

Import-M42Module imports a Matrix42 assembly as a PowerShell module. Assemblies are searched in ESMP product folders and in custom assemblies provided by Sandboxed Extensions.

Parameters

AssemblyName  - Name of the assembly to import. Required.
PackageNameOrId - Optional package name or ID. Use it when the same assembly is provided by multiple extensions to explicitly select the required extension.
RegisterDependencies - Optional. Registers the assembly dependencies in the Matrix42 dependency container, making their services available through $M42_ComponentResolver.

Use ESMP API Components 

To enhance PowerShell scripting, the system exposes global PowerShell variables that provide direct access to the API Components, enabling commonly used functionalities without complex initializations.

Available Global Variables:

Variable Description
$M42_DatabaseProvider Reference to the Data Provider component, offering easy access to the Data Layer and various CRUD operations.
$M42_ServiceConnection Manages service connections, enabling seamless communication with external and internal services.
$M42_Log Provides logging functionality for tracking and debugging operations.
$M42_WebApiClient Reference to the WebClient Provider, which facilitates interaction with web APIs, simplifying HTTP-based integrations.
$M42_GlobalCache Global Cache is a singleton service for storing shared data across the whole application.
$M42_TempFileService Provides access to the Temporary File Storage service, which offers a unified mechanism for storing and managing temporary files across the ESM Platform.
$M42_ComponentResolver Available from version 26.2. Provides access to the Dependency Resolver, which can be used to obtain references to Business Components initialized within the process.

Example

#Read data from Data Layer
$dbData = $M42_DatabaseProvider.GetData("DWPSystemDiagnosticRuleClassBase", "ID,Title", "Disabled=0",$null)
# Write query results to log
foreach ($row in $dbData.Rows) {
  $M42_Log.Info("Rule {0} , ID= {1}", $row['Title'], $row['ID'])
}
# Get Access token from Service connection for further integrations
$authInfo = $M42_ServiceConnection.GetAuthData([System.guid]::New("4059eb6b-0af8-caa6-a69a-08dd5fbf9248"))
$M42_Log.Info("Service Connection {0} {1}", $authInfo.AuthHeader, $authInfo.Type)

# Get localization strings for KB Subject (Translation.GetLocalizationItemsById)
$arg = [Matrix42.Http.Client.Contracts.Argument]::new("id", "$($id)_SVMKBArticleClassBase_Subject")
$data = $M42_WebApiClient.Run([System.guid]::New("4ff4c98c-41ac-ca91-42a2-08d61fcebd53"), @($arg))

$type = [Type]::GetType("Matrix42.Persistence.Contracts.ISchemaService, Matrix42.Persistence.Contracts")
$M42_Log.Info("type resolved: $($type -ne $null)")

$schema = $M42_ComponentResolver.Get($type)