Writing scripts for remote actions on Mac for Finder (classic)

Nexthink Finder is a Windows-only desktop application whose functionality is now available within the Nexthink web interface. Nexthink can now be used directly from a browser and most functions no longer require an additional desktop application.

The payload of remote actions on macOS computers are Bash scripts that run on employee devices. Bash is a command-line shell and scripting language supported by many UNIX-like operating systems, such as macOS, and is suited for task automation and configuration management. Bash scripts are ideal for getting on-demand data from devices, performing self-healing tasks or modifying the configuration of a device, which are typical use cases for remote actions.

This article assumes that the reader is familiar with Bash scripting.

Refer to the Remote actions group in Community for more information.

Encoding

To write your own Bash scripts for remote actions:

  • Encode the files that contain the text of your scripts in UTF-8, without BOM.

  • End each line in the code with the usual character in UNIX systems: LF.

Failing to provide the right encoding to your script files will result in the inability of remote actions to run on employee devices.

Signing and packaging your own scripts

For security reasons, Nexthink requires Bash scripts for remote actions on macOS to be digitally signed with the codesign tool. Additionally, package your signed script as a tar.gz file to preserve its extended attributes. Finder only accepts files with the tar.gz extension when importing scripts for remote actions that target macOS.

Refer to the Signing remote action scripts on Mac (classic) documentation for a step-by-step guide.

Writing generic scripts

You can write scripts in a generic way to adapt them to particular use cases. To make your script generic, declare formal parameters at the beginning of the Bash script. Provide actual values to the parameters in Finder when editing the remote action that contains the script.

Genericity is especially useful for digitally signed scripts that require customization. When a script is signed, any modification to its text content breaks the signature. By making a signed script generic, you allow its customization through the parameters. With parameters, the script's text remains unchanged, and the digital signature remains valid. The values for the parameters that a remote action passes to the script determine its actual behavior.

Declare parameters at the beginning of a script for Bash positional parameters and enclose them between two special comments as follows:

# NXT_PARAMETERS_BEGIN
Parameter1=$1
Parameter2=$2
Parameter3=$3
# NXT_PARAMETERS_END

When uploading the script during the remote action configuration, the system the parameters between the special Nexthink comments in a Bash script and lists them in the Parameters section below the script text. Provide actual values to the parameters in the text input boxes displayed to the right of each parameter name.

The actual values are always passed to the script as text. If the script declares parameters with a type other than string, ensure that you provide values that the script can convert to their expected type.

Output variables

The execution of a script may generate some outputs that you want to store as on-demand data. To that end, Nexthink provides a Bash script (nxt_ra_script_output.sh) that is installed on the device of the employee at the same time as the Collector. The script includes functions to write results to the Engine.

To use the functions in the Nexthink script for remote action output, add the following header at the beginning of your Bash scripts:

#!/bin/bash
. "${NEXTHINK}"/bash/nxt_ra_script_output.sh

All write methods accept two arguments: the name of the output and the value to write. For instance, suppose you want to return the number of files in a directory to the Engine and that the variable nfiles in your script holds that number. To write the value of nfiles through output with the name FileNumber to the Engine, call the function to write unsigned integers:

nxt_write_output_uint32 'FileNumber' $nfiles

The editor of remote actions recognizes the calls to write outputs in the script and lists the output variables under the Outputs section below the script text. Set the output label to indicate how to refer to it in investigations and metrics.

The ending of each write method indicates the type of output. Because Bash is a loosely typed language, the output type is interpreted depending on the context. Find the list of available methods in the table below:

nxt write methodConstraints

nxt_write_output_string

0 - 1024 characters (output truncated if bigger)

nxt_write_output_bool

true / false

nxt_write_output_uint32

  • Min: 0

  • Max: 4 294 967 295

nxt_write_output_float

  • Min: -3.4E+38

  • Max: 3.4E+38

nxt_write_output_size

  • Min: 0

  • Max: 3.4E+38

nxt_write_output_ratio

nxt_write_output_bitrate

nxt_write_output_duration

  • Min: 0 ms

  • Max: 49 days

  • Precision in milliseconds

nxt_write_output_date_time

DD.MM.YYYY@HH:MM

nxt_write_output_string_list

0 - 1024 characters (output truncated if bigger)

Interacting with employees in self-help scenarios

Obtaining the UID of a campaign

The methods to run a campaign from a remote action require a UID campaign identifier to be passed as an argument.

To pass this UID to a remote action, declare a parameter in the script of the remote action for each required campaign. Use the UID as the actual value for the parameter when editing the remote action.

To get the UID of a campaign and pass it to a remote action as a parameter:

  1. Log in to Finder as a user with the right to edit campaigns and remote actions.

  2. In the Campaigns section of the left-side menu, right-click the name of a campaign you wish to launch from a remote action.

  3. Select Export > Campaign Uid to clipboard to copy the UID of the campaign.

  4. In the Remote actions section of the left-side menu, double-click the name of the remote action that should run the campaign to edit it. The remote action must include a script that declares parameters for storing the UID of the campaign.

  5. In the Parameters section under the script, select the parameter to hold the UID of the campaign.

  6. Press Ctrl+V to paste the actual UID of the campaign and assign it to the corresponding parameter.

Running a campaign from the script of a remote action

The following functions extend the scripting capabilities of remote actions.

nxt_run_campaign( id )

The function runs the campaign matching the UID passed as a parameter and saves the answers internally.

  • The function returns 0 if the campaign status is received.

  • The function returns 1 in all other cases, and the error is reported in the logs.

Calling the function pauses the execution of the remote action until the employee either completes the campaign or dismisses it.

nxt_run_campaign_with_timeout (id timeout)

The function runs the campaign matching the UID with the timeout in seconds (0 < T < 1 week) passed as a parameter, and saves the answers internally.

  • The function returns 0 if the campaign status is received.

  • The function returns 1 in all other cases, and the error is reported in the logs.

Calling the function pauses the execution of the remote action until the employee either completes the campaign, dismisses it or fails to finalize the campaign before the timeout.

nxt_run_standalone_campaign( id )

The function runs the campaign matching the UID passed as a parameter and saves the answers internally.

  • The function returns 0 if the campaign status is received.

  • The function returns 1 in all other cases, and the error is reported in the logs.

Calling the function triggers the start of the campaign and continues the execution of the remote action without waiting for the employee's answers.

nxt_get_campaign_status( res_var )

The function returns the status of the last campaign.

  • fully: the employee has fully answered the campaign questions.

  • timeout: the campaign was timed out before the user finished answering.

  • postponed: the employee agreed to participate in the campaign.

  • declined: the employee declined to participate in the campaign.

  • connectionfailed: the script was unable to connect to the Collector component that controls campaign notifications.

  • notificationfailed: the script was unable to display the campaign successfully due to one of the following:

    • The campaign definition could not be retrieved from the platform because of a non-existing or non-published campaign.

    • Another campaign is already being displayed to an employee.

    • A non-urgent campaign cannot be shown due to the focus protection or do-not-disturb rules of Collector. Refer to Limiting the reception rate of campaigns for additional details.

  • Empty, if the last campaign failed.

nxt_get_response_answer( res_var question_key)

Query the last campaign using a question label as a string parameter query_key. The function extracts the answer as a string value and saves it in the given variable res_var.

  • Returns 0 if the campaign status is received.

  • Returns 1 otherwise.

Code examples

Calling a campaign

 # This is a simple example to demonstrate the basic call for a campaign

if nxt_run_campaign "11111111-aaaa-2222-bbbb-333333333333"; then
    nxt_get_campaign_status status
 if [[ status == "fully" ]]; then
        echo "Campaign succeeded"
 else
        echo "Status is $status"
    fi
else
    echo "Campaign failed"
fi 

Accessing the answers

# Simple access to the response data
 
nxt_get_campaign_status status
echo "The response status is $status"
nxt_get_response_answer answersArray key1
echo ${answersArray[1]}

# Careful - Bash uses 0 to n-1 whereas Zsh uses 1 to n.

Running a campaign with a timeout

# Run a campaign with timeout
# timeout is in seconds (100s or 00:01:40)

if nxt_run_campaign_with_timeout "11111111-aaaa-2222-bbbb-333333333333" 100; then
    nxt_get_campaign_status status
 if [[ status == "fully" ]]; then
        echo "Campaign succeeded"
 else
        echo "Status is $status"
    fi
else
    echo "Campaign failed"
fi 

Running a non-blocking campaign

# Run a non-blocking campaign
 
if nxt_run_standalone_campaign "11111111-aaaa-2222-bbbb-333333333333"; then
    nxt_get_campaign_status status
 if [[ status == "fully" ]]; then
        echo "Campaign succeeded"
 else
        echo "Status is $status"
    fi
else
    echo "Campaign failed"
fi

Script termination and timeout

If you launch subprocesses from your remote action script and the remote action script terminates or times out, Collector terminates the subprocesses automatically. If you want the subprocess to continue executing after the remote action is terminated, ensure that your script detaches the subprocess using the & character, for example:

some_script.sh -arg1 -arg2 &

Zsh command interpreter

Starting with Collector version 6.27.2, you can run scripts written for the Zsh Unix shell. You must add the following line of code at the very beginning of the shell script:

#!/bin/zsh

This is a character sequence known as a shebang (external link).

When the system triggers a remote action on a Mac, Collector checks the first line of code and then executes the rest of the instructions using the specified interpreter. A script without a shebang will be executed using the Bash command interpreter.

Nexthink recommends always using a shebang in shell scripts and sticking to the standard interpreters.

The operations described in this article should only be performed by a Nexthink Engineer or a Nexthink Certified Partner.

If you need help or assistance, please contact your Nexthink Certified Partner.


RELATED TOPIC

Last updated

#451: 2024.8-Overview of integration DOC

Change request updated