NEAL

NEAL is a simplified language for defining the design and behavior of workflows.

It is an administrative language that allows for advanced debugging and alterations to workflows outside of the Designer view. When using Designer, every addition or change to the workflow is saved as a NEAL definition, which makes Designer and NEAL language completely synchronous.

Structure

NEAL uses XML as its primary syntax which allows the steps within a workflow to be defined in consistent and easy-to-read tags.

Each NEAL-defined workflow requires the following minimum structure:

  1. ID

  2. Start

  3. Thinklet

  4. Path

  5. End

NEAL Example

This is a simple NEAL workflow with one Remote action Thinklet which restarts the print spooler.

<workflow id="MyWorkflowID" name="My Workflow">
    <description>My workflow description</description>

    <startEvent id="StartWorkflowID" name="Start workflow" />

    <thinklet type="act" id="RestartPrintSpooler" name="Restart Print Spooler" description="This will restart the print spooler service on the target device" timeout="900">
        <remoteActionId>#service_controller</remoteActionId>
        <parameter name="ServiceCommand" value="Restart"/>
        <parameter name="ServiceName" value="Spooler"/>
    </thinklet>

    <endEvent id="EndStateID" name="End State"/>

    <path id="step1" name="Step 1" sourceRef="StartWorkflowID" targetRef="RestartPrintSpooler" />
    <path id="step2" name="Step 2" sourceRef="RestartPrintSpooler" targetRef="EndStateID" />

</workflow>

Apart from the <workflow></workflow>tag which starts, encapsulates and ends the NEAL script, the order of the tags does not matter. However, the order in which the tags are processed by the workflow is defined within the <path></path> tag attributes like id="step1" and id="step2".

ID

Every workflow must have some basic details defined so that Nexthink can reference the workflow and other Nexthink users can identify it:

  • id: The unique identifier by which Nexthink identifies and references the workflow.

  • name: A name for the workflow that is displayed on the Versions tab of the workflow administration page.

  • description: A longer description of the workflow which helps to describe this workflow version to other Nexthink users. A good practice is to describe the reason why this version was created and how it improves upon previous versions.

<workflow id ="MyWorkflowID" name="My Workflow">
	<description>My long workflow description which will help my colleagues understand why this is here and what it does</description>
<workflow>

Thinklet

A Thinklet is the main action component within a workflow and has different configuration options depending on its type.

Every Thinklet, regardless of type, has the following parameters which need to be set:

  • type: The type of Thinklet this configuration is for.

  • id: The identifier used by Nexthink to identify the Thinklet in the workflow.

  • name: A friendly name for the Thinklet. The system uses this name to display the Thinklet visually and represent the current status of the workflow while it is running.

  • description: A longer description of what this Thinklet is intended to do. The system uses this to display the Thinklet visually.

  • timeout: How long, in seconds, the workflow waits for a response from the action that is run by this Thinklet before continuing.

Remote action

The Remote action Thinklet requests to run a remote action on an endpoint device. It has the following configuration parameters:

  • remoteActionId: The NQL ID of the remote action to be used by the Thinklet.

  • parameter: The tag describes the parameters to be sent to the remote action. You can define multiple parameters.

    • name: The name of the parameter being referenced from a remote action.

    • value: The value to be inserted into the remote action parameter. This syntax is used for a static value entered here.

    • source: Use the source to reference a global or output variable.

Either value or source must be used for each parameter, they cannot be used together in the same line.

Example of a Remote action Thinklet.

<thinklet type="act" id="RestartPrintSpooler" name="Restart Print Spooler" description="This will restart the print spooler service on the target device" timeout="900">
    <remoteActionId>#service_controller</remoteActionId>
    <deviceId>f0b002cf-3723-43ae-a2a2-84baf4881952</deviceId>
    <parameter name="ServiceCommand" value="Restart"/>
    <parameter name="ServiceName" source="global.serviceName"/>
</thinklet>

Campaign

The Campaign Thinklet requests to send a campaign to a user on an endpoint device. It has the following configuration parameters.

  • CampaignId: The NQL ID of the campaign to be used by the Thinklet.

<thinklet id="campaign" name="Prompt for reboot" type="engage" timeout="5" description="Prompt employee to reboot their device to continue">
  <campaignId>#reboot_request</campaignId>
</thinklet>

Service/API

The Service/API Thinklet makes a REST call to an external public API. Use it to retrieve additional information or request actions to be performed.

<thinklet id="log_service_now_ticket" name="Log ServiceNow Ticket" type="sapi" description="Open a ticket in ServiceNow.">
    <credentialsId>conn_cr-5</credentialsId>
    <httpMethod>POST</httpMethod>
    <resourcePath>api/now/table/incident</resourcePath>
    <outputVariables>
      <outputVariable id="sys_id" name="Sys ID">$.result.sys_id</outputVariable>
    </outputVariables>
    <payloadTemplate>{
  &quot;assignment_group&quot;: &quot;Application Development&quot;,
  &quot;business_service&quot;: &quot;Zoom&quot;,
  &quot;caller_id&quot;: &quot;Terry Courtney&quot;,
  &quot;description&quot;: &quot;Hello Nexthink Flow&quot;,
  &quot;impact&quot;: &quot;5&quot;,
  &quot;short_description&quot;: &quot;Incident created by Nexthink Flow for {{nx.user.name}}&quot;,
  &quot;urgency&quot;: 4,
  &quot;cmdb_ci&quot;: &quot;{{nx.device.name}}&quot;
}</payloadTemplate>
  • credentialsId: The ID of the connector credentials to be used for the connection. You can obtain it from the URL on the credential page.

  • httpMethod: The method to be used to contact the external system, the supported methods are:

    • GET

    • POST

    • PATCH

    • PUT

    • DELETE

  • outputVariables: Define the ID, name and path for the expected value that needs to be retrieved from the call. Up to 5 outputs are supported.

  • resourcePath: The endpoint to connect to when making the call.

  • payloadTemplate: The JSON payload that will be sent to the external system.

For the payload in NEAL, you must use &quot; in place of quotation marks.

Values

When designing a workflow, you can define dynamic or static values. Use these values to make a workflow behave dynamically. Behavior depends on the inputs that have been provided in the workflow, values that have been obtained from outputs of Thinklets that have already been run, or even from the Nexthink database itself.

Workflows use three primary types of values:

Workflow parameters

Workflow parameters are values that have been either set as part of the workflow design, as inputs requested from the Nexthink user, or from a request to the Nexthink API. These values do not change for the lifetime of the workflow execution and can be referenced from the very beginning of the workflow execution that you are creating.

Note that the XML tag for a workflow parameter is referenced as <global variable> in NEAL due to historical language implementation.

For each workflow parameter that is required in the workflow, these must be set using a <global variable></global variable> tag.

For each global variable, you must define the following attributes:

  • name: The unique identifier that Nexthink uses to reference the workflow parameter. The name must be used when referencing values from other areas of the workflow. It will also be shown when executing the workflow.

  • type: This is the data type that the workflow parameter uses. Currently, the only data type is string. More data types will likely be supported in later versions.

  • customValue: Defines whether a Nexthink user can set the value when the automaton is triggered manually.

You can define workflow parameters within each tag. If you only define one, the system will only use this value. You must place these values within a <value></value> tag.

Example of how to declare a workflow parameter.

<globalVariable name="TargetServiceName" type="string" customValue="false">
    <value>Spooler</value>
</globalVariable>

<globalVariable name="DayoftheWeek" type="string" customValue="true">
    <value>Monday</value>
	<value>Tuesday</value>
	<value>Wednesday</value>
	<value>Thursday</value>
    <value>Friday</value>
</globalVariable> 

A Thinklet can reference a workflow parameter using the following syntax:

source="global.valueName"

Below is an example of the DayoftheWeek workflow parameter from the previous example being referenced by a remote action Thinklet.

<thinklet type="act" id="GetDateRemoteAction" name="Get Date Remote Action" description="This Thinklet will fetch a date using the day of the week" timeout="900">
  <remoteActionId>#get_date</remoteActionId>
  <parameter name="DayName" source="global.DayoftheWeek"/>
</thinklet> 

Output

Output variables are values that are created and set as part of a Thinklet being run. For example, if a remote action collects information and presents it as outputs, these can be used later in the lifecycle of the workflow execution.

Reference output values using the following syntax: source="thinkletId.result.outputs.outputName"

For example, for a Remote action Thinklet that returns an output value named ServiceName that you then want to use as an input to a remote action, reference the Thinklet that starts the service as follows:

<thinklet type="act" id="StartService" name="Start Service" description="This Thinklet will start the service specified in the input" timeout="900">
    <remoteActionId>#start_service</remoteActionId>
    <parameter name="ServicetoStart" source="GetServiceName.result.outputs.ServiceName"/>
</thinklet>  

Database

Database values come from the Nexthink database. There are two objects that the system can access:

  • device

  • user

The device and user are objects that are sent as parameters to the workflow during runtime. When a device is targeted, both of these parameters are populated using the latest information at the time of the workflow being executed.

Only static values are currently available. Event data and custom data are not supported at this time.

Two examples of how to use such a value:

  • Device source="nx.device.name"

  • User source="nx.user.ad.email_address"

References to database objects such as device or user are always prefixed with nx.

Example of a device attribute being used in a condition:

<exclusiveCondition id="hostname_changed" name="Hostname Changed?" description="This condition checks whether the name of the device has been changed successfully by the last action" >
    <condition id = "hostname_changed_no" name="No" input="check_hostname.result.outputs.name" operator="eq" source="nx.device.name" targetRef="retry_name_change" />
    <condition id = "hostname_changed_yes" name="Yes" input="check_hostname.result.outputs.name" operator="neq" source="nx.device.name" targetRef="endstate" />
</exclusiveCondition>

Flow Control

Start block

Every workflow must have a starting point. Typically, you can keep the tag as is. It is primarily used for linking the first Thinklet in a pathway.

There can only ever be one start tag.

<startEvent id="StartWorkflowID" name="Start workflow" />

End block

In the same way that a workflow must start, it must also end. Every pathway through a workflow must ultimately reach an End block. If there is at least one possible path through the workflow that does not reach an End block, it is considered invalid and the system will not run it.

In contrast to the Start block, there can be multiple points at which the workflow is considered in an end state.

The End block is also the place where you can define the workflow outcomes. When the system executes the workflow logic and it reaches the End block, the outcome and outcome details are stored and available to query with NQL.

The End block requires the following attributes:

  • id: The unique identifier by which the system identifies and references the End block.

  • name: A descriptive name for the End block.

  • description: A longer description of what this End block represents, typically the expected outcome.

  • outcome: A mandatory outcome definition that describes what happens when the End block is reached. The possible values are:

    • ACTION_TAKEN

    • NO_ACTION_TAKEN

    • FAILED

    • OTHER

  • outcomeDetails: Description of what happens when the workflow reaches the End block. The character limit for this field is 64 characters. Nexthink recommends keeping this description concise in case the information is used on dashboards.

  <endEvent id="EndStateID" name="Remove Driver" description="Driver has been removed from the device as there is no matching hardware.">
    <outcome>ACTION_TAKEN</outcome>
    <outcomeDetails>Driver removed</outcomeDetails>
  </endEvent>

Path

A path is a method by which the workflow knows how each step is connected to the next.

A path requires the following attributes to be configured:

  • id: The unique identifier by which the system identifies and references the path.

  • name: A descriptive name for the path that is displayed in the Nexthink user interface.

  • sourceRef: The ID of the tag where this path starts.

  • targetRef: The ID of the tag where this path will go.

Below is an example of a path that goes from the starting tag to a Remote action Thinklet.

<path id="step1" name="Step 1" sourceRef="StartWorkflow" targetRef="RestartPrintSpooler" />

Condition

Use conditions to control which path of a workflow is processed by performing checks on values that have been passed to them. These values are collected via variables. Conditions are exclusive, which means that the system only uses one pathway from the condition.

Conditions are encased in an <exclusiveCondition></exclusiveCondition> tag.

Each exclusive condition tag requires the following:

  • id: The unique identifier by which the system references the exclusive condition.

  • name: A descriptive name that is displayed in the Nexthink web interface.

  • description: A longer description of this condition to help other Nexthink users determine what this condition is for.

Within each exclusive condition tag the conditions themselves are defined as and require the following:

  • id: The unique identifier by which the system references the condition. Note that the uniqueness of this attribute applies across the entire workflow, not only the exclusive condition that it is contained within.

  • name: A descriptive name for the condition that is displayed within the Nexthink web interface. This can be used to mask any complexity of the value which is being tested by the condition.

  • input: The variable, either global or output which this condition will be tested against.

  • operator: The type of test to be performed on the value of the variable. Possible operators are:

    • Is "eq"

    • Is not "neq"

    • Less than "lt"

    • Greater than "gt"

    • Less than or equal to "lte"

    • Greater than or equal to "get"

    • Contains "contains"

    • Does not contain "notcontains"

    • Is empty "isempty"

    • Is not empty "isnotempty"

  • value: The expected value of the variable if the condition is true.

  • targetRef: The id of the step in the workflow to jump to in the event this condition is true.

The following example shows the result of a remote action checking for the presence of an installed software application. If the application is installed the workflow will end. If the application is not present the workflow will run the remote action Thinklet to install the application.

    <thinklet type="act" id="CheckProduct" name="Check Product" description="This Thinklet will check to see if the product is installed on the device" timeout="900">
        <remoteActionId>#check_product_presence</remoteActionId>
        <parameter name="ProductName" source="global.productName"/>
    </thinklet>

    <exclusiveCondition id="ProductInstalled" name="Is Product Installed?" description="This condition checks the output of the remote action looking for a specific product install to see if it was found or not" >
        <condition id = "ProductInstalled_Yes" name="Yes" input="CheckProduct.result.outputs.InstallState" operator="eq" value="true" targetRef="endState" />
        <condition id = "ProductInstalled_No" name="No" input="CheckProduct.result.outputs.InstallState" operator="eq" value="false" targetRef="InstallApplication" />
    </exclusiveCondition>

    <thinklet type="act" id="InstallApplication" name="Install Application" description="This Thinklet will install the specified application on the device" timeout="900">
        <remoteActionId>#general_application_install</remoteActionId>
        <parameter name="InstallProductName" source="global.productName"/>
    </thinklet>

    <endEvent id="endState" name="End"/>

    <path id="step2" name="Step 2" sourceRef="CheckProduct" targetRef="ProductInstalled" />

Wait

The Wait flow control lets you pause a workflow and wait for either a period of time or an API call from an external system. This is helpful when the system has to wait for something externally that it does not have control over.

There are two types of Wait, the type of Wait can be set using the type parameter which has values of:

  • delay

  • api

Time delay

A time delay has the following parameters:

  • id: The unique identifier by which the system references the Wait flow control.

  • name: A descriptive name that is displayed in the Nexthink web interface.

  • description: A longer description to help other Nexthink users determine what this Wait flow control is for.

  • value: The number of time units to pause once this stage in the workflow has been reached.

  • unit: The time unit used for the delay in:

    • minutes

    • hours

 <waitFor id="wait_for_updates" name="Wait for updates" type="delay" description="Wait for 5 hours for restart and updates to complete." value="5" unit="hours"></waitFor>

API Listener

An API Listener has the following parameters:

  • id: The unique identifier by which the system references the Wait flow control.

  • name: A descriptive name that is displayed in the Nexthink web interface.

  • description: A longer description to help other Nexthink users determine what this Wait flow control is for.

  • timeout: Set the timeout in minutes. This dictates how long the workflow waits for the desired API call. When the timeout limit is reached, the workflow enters a failed state and stops processing.

Outputs are defined within an <outputVariables></outputVariables> element, up to 5 outputs can be defined. Each output is encased in <outputVariable></outputVariable>

Within each output there are the following parameters

name: A descriptive name to describe the parameter which will be displayed in the Nexthink web interface.

id: The unique identifier for the output. This id will be used to identify the parameter in the expected API call for this API Listener.

  <waitFor id="wait_for_moveworks" name="Wait for Moveworks" type="api" description="Wait for Moveworks to respond with the user response" timeout="60">
    <outputVariables>
      <outputVariable id="command" name="Command"></outputVariable>
    </outputVariables>
  </waitFor>

Repeat

The Repeat flow control allows you to group thinklets together into a sequence that repeatedly executes until a specific condition is met, thereby creating a loop.

A repeat has the following parameters:

  • id: The unique identifier by which the system references the Repeat flow control.

  • name: A descriptive name that is displayed in the Nexthink web interface.

  • description: A longer description to help other Nexthink users determine what this Repeat flow control is for.

  • startRefId: Id of the first Thinklet or Flow control in the sequence.

  • maxIterations: The maximum number of times that the sequence of actions can be repeated.

  • waitDelay: The amount of time the Repeat Flow control will pause before attempting the sequence again.

    • value: Time value

    • unit: Unit of time, either minutes or hours

  • flowElements: Describes the Thinklets, Flow controls and Paths that make up the sequence of actions contained in the repeat. The flow elements are contained within <flowElements> </flowElements>.

  • exits: Describes the available exits for the Repeat Flow control. exits and contained within <exits> </exits>.

    • default: Describes the default exit for the Repeat Flow control. This requires an id and targetRef value.

    • maximumRetries: Describes the exit reached when the maximum number of configured retries for the repeating sequence has been reached. This requires an id and targetRef value.

    • customs: Describes the custom exits for the Repeat Flow control, up to two of these can been configured and are contained within <customs> </customs>. Each exit is defined with custom and has the following values id, name and targetRef.

<repeat id="myRepeat" name="My Repeat" description="Description of the repeat">
    <startRefId>connector</startRefId>
 
    <maxIterations>3</maxIterations>
    <waitDelay value="30" unit="minutes"/>
 
    <flowElements>
        <thinklet id="getCompliance" name="Get Compliance" type="connector">
            <credentialsId>conn_cr-2</credentialsId>
            <connectorId>IntuneConnector</connectorId>
            <connectorActionId>GetDeviceComplianceState</connectorActionId>
            <parameter name="DeviceName" source="nx.device.name"/>
        </thinklet>
        <exclusiveCondition id="condition" name="condition">
            <condition id="condition-ef04de19-40da3e84" input="connector.result.status" name="Default exit"
                       targetRef="defaultExit" operator="eq" value="200"/>
            <condition id="condition-ef04de19-ef0d5528" input="connector.result.status" name="Retry exit"
                       targetRef="maximumRetries" operator="eq" value="425"/>
            <condition id="condition-ef04de19-ef0d5528" input="connector.result.status" name="Retry exit"
                       targetRef="customExit1" operator="eq" value="500"/>
        </exclusiveCondition>
        <path id="path-73dfa7b8" sourceRef="connector" targetRef="condition"/>
    </flowElements>
 
    <exits>
        <default id="defaultExit" targetRef="exitCondition"/>
        <maximumRetries id="maximumRetries" targetRef="maximumRetriesEnd"/>
        <customs>
            <custom id="myCustomExit" name="My Custom Exit" targetRef="end-dea4c159" />
        </customs>
    </exits>
</repeat>

Last updated

#451: 2024.8-Overview of integration DOC

Change request updated