State Machine workflow Configuration

The workflow settings described in this section belong to SharePoint State Machine Workflows.

Type = "SHAREPOINT";

This specifies the workflow type. This must be SHAREPOINT in order to be an email workflow.

SubType = "STATEMACHINE";

This specifies the SharePoint workflow sub type. This must be STATEMACHINE in order to be an state machine workflow.

Platform = "";

You need to specify the used SharePoint platform here:

  • sp2013
  • sp2016
  • sp2019
  • spo
  • spon

Environment = "";

This can be used to specify the SharePoint Online hosting environment:

  • production : Default Office365 environment
  • usgovernment : Office365 for US Government
  • germany : Offic365 in the "German Cloud"
  • china : Office365 in China Cloud
  • ppe : ?

Platform must be spo to use this setting!

Connection = <object>

You can execute a SharePoint workflow on multiple lists in multiple webs. The executed workflow script is always the same. All other settings are identical (names of lists such as error list or data list). But the lists can be configured per web. If you configure this property you cannot configure Web, AlternateWebUrls and List in parallel. The <object> looks like this:

Connection = @(
  @{ 
    Web              = "https://firstweb.sharepoint.farm"; 
    List             = @("List 1", "List 2");
    AlternateWebUrls = @();
    spoAppId         = '';     #optional! 
    spoAppSecret     = '';     #optional! 
    spUser           = '';     #optional! 
    spPassword       = '';     #optional! 
    AzureAdApp       = $false; #optional! 
    spoCert          = '';     #optional! 
    spoCertPassword  = '';     #optional! 
    Environment      = '';     #optional!
  },
  @{ 
  Web              = "https://secondweb.sharepoint.farm"; 
List             = "List 3";
AlternateWebUrls = @();

}, @{ Web = "https://thirdweb.sharepoint.farm"; List = @("List 4", "List 5"); AlternateWebUrls = @(); } )


For a description of `Web`, `List`, `AlternateWebUrls` and the other settings please read the descriptions of the properties below.

The "optional" settings can be used to configure individual credentials for each connection. If they are not present the corresponding setting from the top level of the configuration is used!

Web = "";

Full URL to the SharePoint web where the workflow list is in.

Do not specify this setting if you have configured Connection!

List = @("");

Title (!) of one or more the SharePoint list where the workflow operates on. Each list are called "workflow list".

You can specify more than 1 list. All of them have to resist in the same web. But sometimes it's required to process multiple lists with the same script. There is no need for more than 1 workflow to do that.

You can continue to use a single string: List = "Custom List";. That is equal to List = @("Custom List");

Do not specify this setting if you have configured Connection!

StateList = "";

The name of the lookup list where the states are stored in. This list can be created with program switch --createstatelist.

It's a simple "custom list" with a single-line-of-text-field "State" that contains the state key. The default "Title" is used for the human readable state title.

In case of multiple connections to different SharePoint sites the name of the StateList is identical!!

StateField = "";

The internal name of the state field that is added to the workflow list with --addstatefield. Its a lookup field that points to the StateList.

Ensure that the name does not contain any special characters! If necessare change the technical name later in SharePoint manually. Do not use spaces etc.

RetryOnVersionConflict = $false;

Force workflow script to run again in case of "version conflict" (parallel item modifications in SharePoint).

Default: $false

UserProfileCacheLifetime = 60;

With Get-KFUserInfo a workflow script can query the SharePoint user profile store.

To reduce the calls in case of querying the same account during the workflow run the requested profiles are cached.

Default: global configuration. There: 60 seconds.

spUser = ""; and spPwd = '';

The following two parameters can be used to specify credentials for the workflow for SharePoint access.

If not specified the executing user will be used to access SharePoint.

This user need to have permissions on all object the workflow need to access, e.g. workflow list, items, data list, config list, ...

However it is possible to store credentials in a protected fashion using the parameter --setusername on kenaflow.exe. This will write the encrypted credentials to these two parameters. - Encryption of credentials uses the kenaflow encryption passphrase configured in global configuration. - If encrypted the setting contains a Base64 encoded string that starts with unicode character 0xFFFF. This means that the plain spUser and spPassword are not allowed to start this character!

spoAppId = ""; and spoAppSecret = ''; (without AzureAdApp or AzureAdApp = $false)

Only if platform is 'spo' = SharePoint Online or 'spon' = SharePoint Online New.

Here you can specify "app credentials" to access SharePoint online.

Please read article App ID & App Secret.

You can store encrypted credentials here with program switch --appid on kenaflow.exe. - If encrypted the setting contains a Base64 encoded string that starts with unicode character 0xFFFF. This means that the plain spUser and spPassword are not allowed to start this character!

AzureAdApp = $true with
spoCert = ""; and spoCertPassword = ''; and spoAppId = '<tenant-id>|<app-only-credential-id>';

This combination of credentials can be used with the "new" SharePoint Online connection using PnP Core.

Here you use a certificate for the app-only login.

You need to register an "Application" in the Azure AD of your (SharePoint Online / Microsoft 365) tenant, upload a certificate, grant permissions and enter the data in _wfconfig.ps1

SkipNotLoadedItems = $false

In very rare cases the engine is not able to download the details of a single list item, such as all field values.

With the setting SkipNotLoadedItems you can skip these items and continue with the next one.

If FALSE (default!) the workflow will stop with an error.

If TRUE the workflow will issue a warning but continue to work.

AlternateWebUrls = @();

A list of alternate URLS, e.g. if a web application has Alternate Access Mappings.

Remove Events could be received with such an alternate URL.

Do not specify this setting if you have configured Connection!

ConfigList = "Workflow Configuration";

Defines the name of the workflow config list.

DataList = "Workflow Data";

Defines the name of the workflow sata list

HistoryList = "Workflow History";

Defines the name of the workflow history list

ErrorList = "Workflow Errors";

Defines the name of the workflow error list

PreQueryProcessing = "preQueryProcessing.ps1";

If specified this script is executed before querying.

Default: no pre-query script.

Please read Workflow Scripts.

RER = $false;

Specified whether the workflow offers "Remote Event" endpoints.

A list workflow can receive SharePoint Remote Events, Custom Data Remote Events and Link Remote Events.

Please read Remote Event.

MemBasedRer = $false;

In case of a "permanent" running workflow this setting can be used to process remote events in a memory based queue instead of a file based queue.

AllowParallelRer = $false;

In case of a "permanent" running workflow ... By default ($false) remote events are executed one by one.

When setting it to $true remote events can be executed in parallel.

REREvents = @();

List of strings that contain the subscribed remote events

Valid strings:

  • ITEMADDED
  • ITEMUPDATED

Default: Both.

RERHandlerName = "kenaflow_wf1";

Optional. Used as prefix for the name of the SharePoint Remote Event Receiver.

The default name is configured in the global configuration. It is "kenaFlow".

MaximumRerLifetime = 120;

Specifies how long a Remote Event is valid before it is skipped forever (if not processed).

Default: configuration in global config. There is default: 120s.

PostponeFailedRer = 5;

Specifies how long a a remote event is postponed in case of errors during processing.

Default: configuration in global config. There is default: 5s.

ItemBatchCount = -1;

Count of list items queried from SharePoint at one request.

Default: -1

-1 = use default from global configuration. Default: 1000.

ItemReCheckTime = -1;

Amount of time before each item is checked to be processed.

Default: -1

  • -1 = use default from global configuration. Default: 60 seconds;
  • 0 = check immediately

Background: If you query 1000 items from SharePoint to be processed by your workflow it could take minutes until item #200 is processed. Maybe the item does not need processing at this point in time because e.g. it was changed since them and would not match the query if it would be requested now. - Thats what kenaflow does. It "re-checks" all follwoing items to be "in query" right before executing them.

IgnoreFoldersInQuery = $false;

Handle lists and libraries "flat" by ignoring folders.

Default: $false.

ItemChangeHashFields = <value>;

If you only want to process item with changes in certain item fields (columns) you can specify the list of names here.

If you want only process items with changes in any field you can set this simply to $true.

This setting can be overwritten for each state.

Example:

ItemChangeHashFields = @("Title");

StateSpecificItemChangeHash = $false;

If you set this to $true than each workflow state will have its own change hash.

The default for this setting is $false.

Permission Sets Settings

PermissionSetCreate="kenaflow Create"; PermissionSetRead="kenaflow Read"; PermissionSetUpdate="kenaflow Update"; PermissionSetDelete="kenaflow Delete"; PermissionSetManage="kenaflow Manage"; PermissionSetApprove="kenaflow Approve"; ... can be used in _wfconfig.ps1 to configure the names of kenaflow created permission sets for the kenaflow specific SharePoint permission cmdlets:

Please read article Permissions for details.

Workflow State Configuration

The power of state machine workflows comes from the ability to execute code depending on the current item state.

Each state has a key as technical name and its own configuration.

The state key must not contain characters that are forbidden in file names, because the state key is used for file names, such as the state script file.

All states together are defined in a Hashtable property with the technical state name as key:

States = @{
    "<state-key>" : <state-config-hashtable>
    "(empty)" : @{...}
    "State2" : @{...}
    "State3" : @{...}
}

The name (empty) for the "empty State" - if the workflows state field in SharePoint is $null for the list item - is fixed and cannot be changed.

Each state configuration (<state-config-hashtable>) has the following options:

Enabled = $true;

Each state can be disable for processing by setting this to $false.

Default is $true.

Title = "";

This is the human readable name of the state. It will be written to the state list, which is a lookup list that gets connected to the workflow list and stores the current state for each item.

Type="lastmodified";

Valid values are:

  • query : All items in the current state that match the query.
  • lastmodified : All items in the current state that were modified sind last running the script.
  • all : All items in the current state are processed.

Default is: all

This is used to query list items from SharePoint. First the state field is always used for the query.

Query="";

If Type is query...

This uses by default the kenaflow query language: Queries.

However if the query string starts with "<" it will be treated as CAML.

ExecutionOrder = 100;

You can define the execution order for states by defining this key.

All states that have not defined this setting the number 0 is used. Except for state "(empty)" for which -1 is used by default. So (empty) will be executed first.

All scripts with the same "ExecutionOrder" (or none which means "0") are executed by the order of their keys.

ItemReCheckTime = -1;

Amount of time before each item is checked to be processed.

Default: -1

  • -1 = use default from workflow configuration.

MaxExecutionTime = -1;

After this amount of time elasped the workflow execution will be stopped

Default: -1

-1 = use default from _wfconfig.ps1.

ItemBatchCount = -1;

Count of list items queried from SharePoint at one request.

Default: -1

-1 = use default from _wfconfig.ps1.

Debug = $false;

You can mark a workflow state as being "in debug".

You can evaluate the debug state with Cmdlet Get-KFInDebug.

This can be used to have script portions that are only executed during debug.

Default: $false.

LastModifiedBasedOnLastRun = true;

If $true :

  • the timestamp LastRun of the workflow state will be used to identify "last modified" items
  • the queried items for processing this state are sorted by ID.

If $false :

  • a time stamp file is written after processing all items for the state or
  • a time stamp file is written if the workflows is timed out and the state script is forced to stop and
  • the queried items for processing are sorted by their "Modified" timestamp.

IgnoreFoldersInQuery = $false;

Handle lists and libraries "flat" by ignoring folders.

Default: $false.

Script = "";

The name of the state script file.

By default (if not specified) the state script name is S_ plus the technical state name.

State = @{
  # Script name is S_(empty).ps1  
  "(empty)" : @{...}  
    
  # Script name is S_State2.ps1    
  "State2" : @{...}   
    
  # Script name is S_State3.ps1
  "State3" : @{...}   
    
  # Script name is State4.ps1
  "State4" : @{ ... Script="State4.ps" ... }
}

TBE = 30;

This means "Time Between Execution".

Between two starts of the state script the configured amount of seconds must elapse.

Cron = "60 * * * *";

You can specify an CRON-style pattern for the time based execution of the workflow state.

This CRON pattern will be calculated relative to the last state run timestamp.

If the state is never run this setting is ignored. The state script will execute once immediately.

The calculated time for the next execution is not guaranteed by kenaflow, because exact scheduling is not possible.

ItemChangeHashFields = <value>;

If you only want to process item with changes in certain item fields (columns) you can specify the list of names here.

If you want only process items with changes in any field you can set this simply to $true.

If this setting is not specified for a certain state but is specified for the whole workflow in the corresponding setting ItemChangeHashFields than the workflows setting is used for the state. If you want to disable this feature for the current state and the global setting of the then you can set this to $false.

If this setting is specified it will overwrite the workflows setting if this is specified.

Examples:

ItemChangeHashFields = @("Title");
State = @{
  # This disabled the feature
  "(empty)" : @{
     ItemChangeHashFields = $false
  }  
    
  # This uses the setting of the workflow
  "State2" : @{
  }  
    
  # This will use field "CustomField" as reference for the change hash instead 
  #  of the global defined "Title" field.
  "State3" : @{
     ItemChangeHashFields = @("CustomField")
  }  
    
  # This uses all fields for the hash.
  "State4" : @{
     ItemChangeHashFields = $true
  }  
}

If workflow-level setting StateSpecificItemChangeHash is $true than each state will have its own change hash saved in the kenaflow Field. Default for this setting is $false.

Execution Order

Starting with kenaflow v4.0.26 you can specify the execution order of the states using ...

OrderedStates = @( "(empty)", "State2", "State3" ) #...as list of strings
#or
#OrderedStates = "(empty), State2, State3" #...as string (if the state keys do not contain characters ',' (comma) and ' ' (space))

If you specify NO states here or skip the setting at all than the state order uses ExecutionOrder from above.

IF you specify the setting OrderedStates with at least one state than it overwrites the ExecutionOrder. Missing states are not executed as the are ignored.

Also starting with kenaflow v4.0.26 you can specify how often should all (enabled) states should be executed again.

RepeatStates = 1