Skip to main content


From Agent Language to Tachyon Instruction

Writing and testing Instructions

Creating an instruction using the Agent Language is the first step in building a question or an action that can be used from Tachyon Explorer (or any other Tachyon consumer).

The easiest way to create an instruction is to refine and test it on a single device, and then incorporate it into a Product Pack which can be imported into Tachyon. 1E provides the Tachyon Instruction Management Studio (TIMS) which can be used to create and run instructions on your local machine. This tool also allows you to add your instruction into a Product Pack.

See Getting started with TIMS for how to use TIMS.

Continue reading to understand the Agent language.

Use the Functions and Methods Reference to use the power of Tachyon.

Instructions and Instruction Sets

Once the instruction has been written and tested, the instruction is then saved as an Instruction Definition, which is simply an XML file.

The definition of an instruction is explained fully in Instruction Definition Reference, but here is a summary:

  • A unique name

  • The type of instruction – whether it is a question or an action (which affects how it is displayed in Tachyon Explorer). Note that the Agent itself does not differentiate between questions and actions – it considers both as simply "instructions".

  • A "readable payload" – this is the instruction phrased as a question or action, and is what is displayed in Tachyon Explorer

  • Description - this is additional information that can also be displayed in the Tachyon Explorer; along with the Readable Payload, the Description is also parsed when searching in Tachyon Explorer

  • The instruction "payload" – this is the Agent Language script which will be sent to the target devices

  • Parameters for the instruction – this allows anyone running the instruction to substitute custom values within the payload

  • The instruction "schema" – this describes the structure of the data which the instruction returns, and is used to create the dynamic storage for the results of the instruction on the Tachyon Server

  • The instruction "aggregation schema" – this describes how data from multiple devices should be summarized, and is conceptually similar to a "GROUP BY" clause in SQL

  • The time-to-live (TTL) values for the instruction – how long to gather data (gather period - InstructionTtlMinutes) and how long to keep it (keep period - ResponseTtlMinutes)

A Product Pack can also include "resources", such as script files (e.g. PowerShell, BASH, etc.). Adding resources to a Product Pack makes them available for download by the Tachyon Agents. Using scripts within the Agent Language is described in detail later.

Instruction Parameters

Adding parameters to an instruction can make it flexible and enables the instruction to be reused. An instruction parameter is simply a substitution of a user-supplied value into the instruction’s payload.

In the following example, we extend the previous example by counting network connections per process where the connection is on a specific, user-supplied TCP port.

Example - parameter placeholders

@connections = Network.GetConnections();

SELECT   COUNT(1) AS ConnectionCount
,        ProcessName
FROM     @connections
WHERE    RemotePort = CAST("%MyPort%" AS NUMBER)
GROUP BY ProcessName;

We would then define a parameter to substitute the placeholder %MyPort% with a value supplied by the user. For guidance on using TIMS to define instruction parameters, please refer to Getting started with TIMS - Instruction Parameters.

Instruction parameter considerations

Since parameter values are substituted directly into the Agent’s payload, you must take care to avoid the possibility of SQL or statement injection. Tachyon takes precautions against this (e.g. escaping double-quotes and backslashes within string parameter values), but you should consider the following when parameterizing instructions:

  • Although the format %ParameterName% is the preferred convention for a parameter placeholder, you are free to use any substitution placeholder you wish

  • Parameters should be defined as the most appropriate data type (string, integer, float, Boolean)

  • String parameters should, where possible, be constrained using a regular expression to prevent invalid input

  • Placeholders for string parameters should be placed within double-quotes within the Agent Language – the Tachyon Consumer API will automatically perform escaping of the parameter’s value

  • Placeholders for non-string parameters should not be placed in double-quotes

  • Within SQL statements, you may wish to consider using a CAST("%parameter%" AS NUMBER) expression for type-safety

  • Although it is possible to use parameters to build "dynamic statements" within the Agent Language, it is NOT recommended unless you take extreme care (and limit the possible values which can be supplied for the parameter)

Handling multiple values in a single string instruction parameter
/* Transpose a comma-delimited string of KB numbers into a column, eliminating whitespace and blanks */
@kblist = Utilities.SplitLines(Text:"%kblist%", Delimiter:",");
@kblist = SELECT DISTINCT TRIM(Output) AS kb FROM @kblist WHERE TRIM(Output) <> "" ORDER BY kb;
Output content and column names

Column naming rules

  • only use basic alphanumeric characters when naming a column (A-Z, a-z, 0-9) - do not include spaces or other characters

  • must start with a letter - so "MyColumn", "Value1" and "Iteration3Data" are valid column names, whereas "my_column", "my column", and "3IterationData" are not

  • must be unique when considered case-insensitively - for example, you should not have instructions which returns columns named, "TEST", "test" and "Test", as this will cause conflicts.

The names of the columns within the data set returned by the Agent Language correspond to the column headings for the data when displayed in Tachyon Explorer. Tachyon Explorer performs a basic translation of the name based on changes in upper/lower-case. For example, ThisIsMyColumnName will be displayed as This Is My Column Name.

You can use column aliasing within SQL to name (or rename) a column. For example the instruction below returns two columns of data, one named ConnectionCount and the other named NameOfTheProcess. Tachyon Explorer will display these as Connection Count and Name Of The Process respectively.

Example - providing an alias for a column

@connections = Network.GetConnections();
SELECT   COUNT(1) AS ConnectionCount
,        ProcessName AS NameOfTheProcess
FROM     @connections
GROUP BY NameOfTheProcess;

You also have an alternative option for changing Column names displayed in Explorer by using the Render As option when defining the output schema of an instruction, as described in Getting started with TIMS: Adding a schema.

Aggregating data

We mention this here, just so you do not confuse aggregating data using SQLite with response aggregation at the server. The latter is not part of the Agent language, but is determined by the AggregationJson specified in the instruction definition. Then the Explorer portal will display the aggregated responses with a drill down into the detailed data.

If you don't need the detailed data, then aggregating data on each device is useful to reduce the quantity of data being reported back to the server and having to be processed.

Example - querying historic captured data

@products = Software.GetInstallations();
SELECT   Publisher
,        Count(*) AS Products 
FROM     @products
GROUP BY Publisher;