Using Functions, Operators, and Keywords
  • 11 Apr 2024
  • 16 Minutes to read
  • Dark
    Light
  • PDF

Using Functions, Operators, and Keywords

  • Dark
    Light
  • PDF

Article Summary

The following are some of the functions, operators, and keywords that you can use in Dynamic Value statements (also referred to as 'statements'):

Using min/max Functions

The min/max functions work for all statement types for number values only. It sets the value of the field in the Enforcement Action to the min/max value of a group of single value fields, an array (list) field, or a group of array fields indicated in the min/max clause.

Using the min/max Function with an Array (List) Field

min has the syntax:

set_value min([adapter.arrayfield])

max has the syntax:

set_value max([adapter.arrayfield])
  • Example - Sets the value of the form.field_integer field to the maximum value found in the device.specific_data.data.software_cves.cvss3_score list.
    device all then form.field_integer set_value max([device.specific_data.data.software_cves.cvss3_score])
    
  • Example - Sets the value of the form.field_integer field to the minimum value found in the device.specific_data.data.software_cves.cvss3_score list.
    device all then form.field_integer set_value min([device.specific_data.data.software_cves.cvss3_score])
    

Using the min/max Functions with Multiple Single Value Fields

min has the syntax:

set_value min(item1, item2, ..., itemN)

max has the syntax:

set_value max(item1, item2, ..., itemN)
  • Example - Compares the number of logical cores in the following three fields, and sets the value of the form.field_integer field to the maximum value.
    • device.adapters_data.aws_adapter.cpus.logical_cores
    • device.specific_data.data.cpus.logical_cores
    • device.adapters_data.bigid_adapter.cpus.logical_cores
    device all then form.field_integer set_value max([device.adapters_data.aws_adapter.cpus.logical_cores], [device.specific_data.data.cpus.logical_cores], [device.adapters_data.bigid_adapter.cpus.logical_cores])
    

Using the min/max Functions with Multiple Array Fields

The min/max functions can return the minimum or maximum value from multiple array fields. The minimum or maximum value from each field is found and then the minimum or maximum of those values is used.

min/max has the syntax:

set_value min([....],[....],...,[....])
or
set_value max([....],[....],...,[....])


  • Example - Sets the value of the form.field_integer field to the maximum value found in either of these array fields:
    • device.specific_data.data.software_cves.cvss3_score
    • device.adapters_data.tenable_security_center_adapter.software_cves.cvss2_score
device all then form.field_integer set_value max([device.specific_data.data.software_cves.cvss3_score], [device.adapters_data.tenable_security_center_adapter.software_cves.cvss2_score])

Using add, multiply, and divide Functions

The add, multiply, and divide functions can be used in the same way as concat or sum to add/multiply/divide one or more single value numerical fields to/by a number or numbers.

add has the syntax:

add (value1, value2,..., valueN)

multiply has the syntax:

multiply([some.field.name], value)

or

multiply (value1, value2,..., valueN)

divide has the syntax:

divide([some.field.name], value)

or

divide (value1, value2,..., valueN)
  • Example - Sets the value of the form.field_integer field to the sum of the following:
    • device.custom.asset_criticality multiplied by 0.4
    • device.custom.asset_severity multiplied by 0.6
device all then form.field_integer set_value
add (multiply([device.custom.asset_criticality], 0.4), multiply([device.custom.asset_severity], 0.6))
  • Example - In the following example, calculation is performed starting with the most internal parentheses, outward. Sets the value of the form.field_integer field, as follows:
    • Adds the following:
      cve_severity.critical_count multiplied by 0.9
      and
      cve_severity.high_count multiplied by 0.6

    • Adds cve_severity.high_count and cve_severity.critical_count.

    • Divides the first sum by the second sum to give the result.

device all then form.field_number set_value divide( add( multiply([device.specific_data.data.software_cves.cve_severity.critical_count], 0.9), multiply([device.specific_data.data.software_cves.cve_severity.high_count], 0.6) ), add([device.specific_data.data.software_cves.cve_severity.high_count], [device.specific_data.data.software_cves.cve_severity.critical_count]) )

Using the subtract Function

The subtract function can be used to return the difference between two numbers (typed or values from fields) or two date-time fields.

subtract has the syntax:

subtract (item1, item2)
  • Example - For all devices that match the query, sets the value of the DiffDates field (form.field_number) to the result of the current date and time (the value in device.adapters_data.gui.custom_nowdate) minus the date and time that the asset was last seen (value in device.specific_data.data.last_seen).
device all then form.field_number set_value subtract([device.adapters_data.gui.custom_nowdate], [device.specific_data.data.last_seen]) 

The following screen shows the results of the Enforcement Set run:

DateDifferenceRunResults

Using the average Function

The average function works for all statement types for number values only. It sets the value of the field in the Enforcement Action to the average of the number values in an array (list) field of numbers.

average has the syntax:

average ([adapter.arrayfield])
  • Example - For all vulnerabilities that match the query, sets the value of form.field_number to the average CVSS score (vulnerability.adapters_data.tenable_io_adapter.cvss).
vulnerability all then form.field_number set_value average ([vulnerability.adapters_data.tenable_io_adapter.cvss])

Using Boolean Operators in Case Statements

The Boolean operators true and false can be used in switch/case statements to test the value of a Boolean field.

  • Example - If device.rapid7.some_boolean_field has the value true, then set the value of form.category to 1234. If its value is false, then set the value of form.category to 4567.

     switch device.rapid7.some_boolean_field
     case field_equal (true) then form.category set_value "1234"
     case field_equal (false) then form.category set_value "4567"
    
  • Example - If device.rapid7.some_boolean_field does not have the value true, then set the value of form.category to 0000. If it does not have the value false, then set the value of form.category to 1111.

switch  device.rapid7.some_boolean_field
case field_not_equal (true) then  form.category set_value "0000"
case field_not_equal (false) then form.category set_value "1111"
Note:

When used on a Boolean field, case field_not_equal (false) is equivalent to case field_equal (true), and case field_not_equal (true) is equivalent to case field_equal (false).

Using the contains Operator

The contains operator for switch statements applies the Enforcement action if the string or array contains the indicated value:

  • A string may contain a substring.
  • An array must contain the exact value.

contains has the syntax:

switch some.field.name case contains("value") then ...
  • Example - This statement verifies that the labels list device.labels contains a value 'TAG', and if true, sets the value of the form.color field to 'blue'.
    For example, if the labels list has the values [“123”, “TAG”, “ANOTHER”], the switch statement applies the enforcement action, i.e., sets the form color field to blue.
    switch device.labels case contains("TAG") then form.color set_value "blue"
    
  • Example - This statement verifies that 'ABC' is a substring of (or the entire) asset name. (e.g., 'ABCDEFG' as asset name returns true), and if yes, assigns the device (device.specific_data.data.assigned_to) to Group ABC.
    switch device.specific_data.name case contains("ABC") then device.specific_data.data.assigned_to set_value "Group ABC"
    

Using the not_contains Operator

The not_contains operator for switch statements applies the Enforcement action if the string or array does not contain the indicated value:

  • Checks that a string or substring do not contain the value.
  • Checks that an array does not contain the exact value.

not_contains has the syntax:

switch some.field.name case not_contains("value") then ...
  • Example - This statement verifies that 'x' is not a substring of (or the entire) asset name (device.specific_data.data.name). (e.g., 'ABCDEF' as asset name returns true), and if yes, assigns the tag name (form.tag_name) the value 'success'.
switch device.specific_data.data.name
case not_contains ("x") then form.tag_name set_value "sucesss"

Using the also Operator

The also operator enables applying dynamic content on multiple action fields in a single dynamic value statement.

  • Relevant for 'switch/case' and 'all' statements.
  • In the 'all' statement below: In all devices, set form.field1 to the value of adapter.fieldX or if empty, to the value of adapter.fieldY. Also, set form.field2 to the value of adapter.fieldZ.
  • In the 'switch/case' statement below: If the value in adapter.fieldX begins with 'A' then set form.field1 to 'aaa' and also set form.field2 to 'XXX'.

also has the syntax:

device all then form.field1 set_value [adapter.fieldX] or [adapter.fieldY] also form.field2 set_value [adapter.fieldZ] 

switch adapter.fieldX
case starts_with "A" then form.field1 set_value "aaa" also form.field2 set_value "XXX"
  • Example -
    The following statement does the following:
    For each device that matches the query, set the tag name (form.tag-name) to "gt 2" and the tag color to green (RGB color #32a852).
device all then form.tag_name set_value "gt 2" also form.color set-value "#32a852"  

The following screen shows the results of running the Axonius - Add Tag to Assets enforcement action with the above statement.
ExampleAlsoRunDrawer

Clicking the Successful link displays the 'successful' devices returned from the Enforcement Set query with their tags. The green "gt2" tag is from the current run.

ExampleAlsoSuccessfulDevices

Clicking a device on the above screen (in this case, the one with the enclosed tag) opens its Asset Profile. You can click the Tags category to see the asset's tags:
ExampleAlsoAssetrofileTag

Using the join Function for Array Fields

The join function converts a list (array) into one single string with the items separated by a delimiter. The delimiter can be any character.

join has the syntax:

join (items, delimiter)
  • Example - For each device, converts the list of vulnerabilities (device.specific_data.data.vulnerabilities.vulnerability_name) found on the device into a joined string of vulnerabilities separated by a space and comma (vulnerability1, vulnerability2, ..., vulnerabilityN) and places it in the Incident Description field of the ticket.

    device all then form.incident_description set_value join ([device.specific_data.data.vulnerabilities.vulnerability_name], " ,")
    
  • Example - Join the listed values into one string with the values separated by semicolon and a space.

    join(["string_1", "string_2"], "; ") 
    

    The output will be

    *string1; string2*.
    

Using the by_key Function for Complex Field Objects

The by_key function accepts a complex field path [adapter_complex_field_path] as input, and searches in the specified object (key_to_search_by) of the complex field for a specified value (value_to_search). It then returns the value from a corresponding specified object (key_to_pick).

by_key has the syntax:

by_key ([adapter_complex_field_path], key_to_search_by, value_to_search, key_to_pick)
  • Example -
    The following statement does the following:
    For each device that matches the query, for all tag_key objects in the AWS Adapter Tags complex field (device.adapters_data.aws_adapter.tags) that have the string 'ax:state', returns the string in the corresponding tag_value object. It then creates a tag, by concatenating 'the value for the owner is ' with the returned string.
device all then form.tag_name set_value concat ("the value for the owner is ", by_key ([device.adapters_data.aws_adapter.tags], "tag_key", "ax:state", "tag_value")) 

The following screen shows the results of running the Axonius - Add Tag to Assets enforcement action with the above statement.
EC_Tags-Run_History

Clicking the Successful link displays the devices returned from the Enforcement Set query. The following screen shows the resulting tags of the 'successful' devices (added using Edit Columns).
EC_by_key_tagged_devices

Clicking a device on the above screen (in this case, the one with the enclosed tag) opens its Asset Profile displaying All Fields.
AssetProfileAdapterTags

Under Tables, you can click the Adapter Tags complex field to open its objects arranged in a table. Enclosed under Tag Key (key_to_search_by) is ax:state (value_to_search). The function returns 'remove' under Tag Value (key_to_pick).

EC_by_key_Adapter-Tags_table

You can click the Tags category to see the asset's tag:
EC_by_key_Adapter-Tags

Using the concat Function for String Arguments

The concat function concatenates the string arguments (values and/or single value string type fields) in a list.

concat has the syntax:

concat (item1, item2,…, itemN)
  • Example - Concatenate a list with a string using join.
    You can use nested functions to concatenate a list with a string.

  • Flattens the array device.field.array.1 into its elements with a comma delimiter between each two elements.

  • Concatenates 'and', the string in device.field.mystring, and 'comment' to the joined string, and places the resulting string in form.incident_description.

     device all then form.incident_description set_value 
     concat (join ([device.field.array.1], ","), "and",      [device.field.mystring],"comment")
    

    This statement generates a (single string) value of:

    itemarray.1, itemarray.2, ..., itemarray.n and mystring comment
    

Using the date_format Function for String Manipulations

The date_format function formats the date and time according to the specified format.

date_format has the syntax:

date_format ([adapter.field], "format")

Where format can be any of the following combinations:

  • %Y - Year (four digits)
  • %m - Month (01-12)
  • %d - Day of the month (01-31)
  • %H - Hour (00-23)
  • %M - Minute (00-59)
  • %S - Second (00-60)
  • %L - Millisecond (000-999)
  • %j - Day of the year (001-366)
  • %w - Day of the week (0-6, Sunday is 0)
  • %a - Abbreviated weekday name (Sun, Mon, Tue, etc.)
  • %A - Full weekday name (Sunday, Monday, Tuesday, etc.)
  • %Z - Timezone (e.g., EST, PST, UTC)

Note: M = minute; m = month

Note:
  • M = minute; m = month
  • The date_format function does not work with lists (arrays). In order for this function to work when used on list fields, add a function that selects one value from the list, for example, the max function.
    date_format ((max([adapter.field]), "format")
  • Example - Sets the value of the tag name (form.tag_name) to the fetch time (device.specific_data.data.first_fetch_time), formatted as YYYY-mm. For example, 2024-01.
     device all then form.tag_name set_value date_format([device.specific_data.data.first_fetch_time], "%Y-%m")
    
  • Example - Sets the value of the current date and time (form.field_date.now) to the current date and time (now()), formatted as YYYY-mm HH-MM-SS. For example, 2024-01 21-12-58.
 device all then form.field_date.now set_value date_format(now(), "%Y-%m %H-%M-%S")

Using the regex_replace Function

The regex_replace function checks if a specified
field's string value matches the pattern in regex_expression, and if it does, replaces it with the string in replace_value.

Note:

replace_value can also be a function that returns a string.

regex_replace has the syntax:

regex_replace ([field], regex_expression, replace_value)
  • Example - If the regex_replace function finds one or more digits ("\d+") in the device.labels field, it replaces the digits with "Catlg".
 regex_replace ([device.labels], "\d+", "Catlg") 

Using the split Function

The split function splits the string in the indicated field at the specified delimiter, and creates a list of the separate strings separated by a comma.

split has the syntax:

split([field], delimiter)
  • Example - A string is split at the delimiter character $.
split("My$Cool$String", "$") 

The output is a list:

["My", "Cool", "String"]

Using the count Function

The count function returns the number of values in a list field.

count has the syntax:

count([field])
  • Example - Counts the number of CISA vulnerabilities in the device.adapters_data.gui.cisa_vulnerabilities list field and places the number in form.field_number.
device all then form.field_number set_value count([device.adapters_data.gui.cisa_vulnerabilities])

Using the substring Function

The substring function returns a substring of the field value, beginning from the specified start position in the string until the specified end position in the string.

substring has the syntax:

substring([adapter.field], start_index, end_index)
  • Example - For devices with host names (device.specific_data.data.hostname) that all begin with an up to 4-character prefix, sets the value of the form.field_value list field to the host names without their prefixes, i.e., removes the first four characters of the hostname.
device all then form.field_value set_value 
substring( [device.specific_data.data.hostname],5,50)

Using the to_lower Function

The to_lower function converts a string field to lower case.

to_lower has the syntax:

to_lower([field])
  • Example - Sets the tag name value (form.tag_name) to the tag source (device.specific_data.data.tags.tag_source) in lower case.
device all then form.tag_name set_value to_lower([device.specific_data.data.tags.tag_source])

Using the to_upper Function

The to_upper function converts a string field to upper case.

to_upper has the syntax:

to_upper([field])
  • Example - Sets the tag name value (form.tag_name) to the ID (device.specific_data.data.id) in device.specific_data.data.id case.
device all then form.tag_name set_value to_upper([device.specific_data.data.id])

Using the unique Function for Array Fields

The unique function removes all duplicate elements in the list (array) and keeps only the unique values.

unique has the syntax:

unique ([field])
  • Example - For each device, removes the duplicate hostnames in the list field (device.specific_data.data.hostname) and leaves only the unique hostnames in form.field_list.value.

    device all then form.field_list.value set_value unique ([device.specific_data.data.hostname])
    
  • Example - For each device, counts the number of unique hostnames in the device.specific_data.data.hostname list field and places the number in form.field_integer.

device all then form.field_integer set_value count (unique([device.specific_data.data.hostname]))

Applying the unique Function on a Nested Function

The unique function can be applied on a nested function to return the unique results of the nested function.

unique has the syntax:

unique (nested function)
  • Example - Ideally, each device should be loaded with one version only of each installed software application. For each device, the following statement counts the number of unique major/minor versions of installed software in the device.specific_data.data.installed_software.major_minor_version array (list) field. If the number of unique versions is greater than 1, places the string Needs remediation in the form.field_value string field.
    For example:
    List of major/minor versions in the device: {1.0, 2.0, 3.0, 3.0, 3.0, 4.0, 5.0}
    Count: 7
    Unique count: 5
switch unique(count([device.specific_data.data.installed_software.major_minor_version]))
case gt(1) then form.field_value set_value "Needs remediation"

Using the field_exists Operator

The field_exists operator tests whether the specified field exists.

The following code tests whether the field device.specific_data.data.name exists. If true, sets the value of form.field_value to 'exists'.

switch device.specific_data.data.name
case field_exists then form.field_value set_value "exists"

Using the field_not_exists Operator

The field_not_exists operator tests whether the specified field does not exist (i.e., is empty).

Note:

The field_not_exists operator should be used only when empty values are checked and are not thrown out of aggregations.

The following code assigns a value to form.field_value based on the device.specific_data.data.name field value:

  • If the device.specific_data.data.name field contains 'X', form.field_value is set to 'aaa'.
  • If the device.specific_data.data.name field contains 'Y', form.field_value is set to 'bbb'.
  • If the device.specific_data.data.name field does not exist (i.e., is empty), form.field_value is set to 'ccc'.
Note:

Conditions are checked in the order that they appear in the statement. Once a condition is met, the remaining conditions are not checked.

switch device.specific_data.data.name
case contains ("X") then form.field_value set_value "aaa"
case contains ("Y") then form.field_value set_value "bbb" 
case field_not_exists then form.field_value set_value "ccc"

Using the in_net Operator

The in_net operator tests whether the specified IP address field is in the specified IP address range or ranges.

in_net has the syntax:

in_net (ip address field)

The following code tests whether the IP addresses in the list field device.specific_data.data.network_interfaces.ips is in any of the following IP address ranges:

  • 10.0.2.0-10.0.2.4
  • 10.0.2.7-10.0.2.9
  • 12.3.4.1-12.6.7.8

If true, sets the value of the tag name (form.tag_name) to 'in network!'.

switch [device.specific_data.data.network_interfaces.ips]
case in_net("10.0.2.0-10.0.2.4,10.0.2.7-10.0.2.9,12.3.4.1-12.6.7.8") then form.tag_name set_value "in network!"

Using the not_in_net Operator

The not_in_net operator tests whether the specified IP address field is in the specified IP address range or ranges.

not_in_net has the syntax:

not_in_net (ip address field)

The following code tests whether the IP addresses in the list field device.specific_data.data.network_interfaces.ips is in any of the following IP address ranges:

  • 10.0.2.0-10.0.2.4
  • 10.0.2.7-10.0.2.9
  • 12.3.4.1-12.6.7.8

If false, sets the value of the tag name (form.tag_name) to 'not in network!'.

switch [device.specific_data.data.network_interfaces.ips]
case in_net("10.0.2.0/4,10.0.2.7/9,12.3.4.1/6.7.8") then form.tag_name set_value "not in network!"

Using lt in Switch Statements

The lt operator (less than) compares numeric field 1 to numeric field 2 or to a number, and if numeric field 1 is smaller, performs the 'then' clause.

  • Example - The following example compares two device fields fetched from the adapter.
    • Compares the value of custom_intest to the value of custom_intest2.
    • If custom_intest < custom_intest2, then sets the tag-name field on the form to "failure".
switch device.adapters_data.gui.custom_intest
case lt ([device.adapters_data.gui.custom_intest2]) then form.tag_name set_value "failure"

Using gt in Switch Statements

The gt operator (greater than) compares numeric field 1 to numeric field 2 or to a number, and if numeric field 1 is greater, performs the 'then' clause.

  • Example - The following example compares two device fields fetched from the adapter.
    • Compares the value of custom_intest to the value of custom_intest2.
    • If custom_intest > custom_intest2, then set the tag-name field on the form to 'success'.
switch device.adapters_data.gui.custom_intest
case gt ([device.adapters_data.gui.custom_intest2]) then form.tag_name set_value "success"

Using the Wildcard Character in Statements

You can use the wildcard character * in dynamic value statements.

Using Operators with Arrays (Lists)

When testing an array with any of the operators below, if at least one value matches, the result is TRUE.

This works for the following operators:

  • contains
  • not_contains
  • in
  • not_in
  • starts_with
  • not_starts_with (no matches)
  • ends_with
  • not_ends_with
  • gt
  • lt

Nesting Functions

You can nest functions (functions within functions) when writing dynamic value statements.

  • Example - The following statement includes a sum function within the concat function.

    • sum() - Adds the values in the device.specific_data.data.field array.
    • concat("sum is", sum()) - Adds 'sum is' before the calculated sum sum().
    • set_value concat("sum is", sum()) - Sets the tag name on the form (form.tag_name) to 'sum is' followed by the calculated sum of the list values. For example: "sum is 124".
    device all then form.tag_name set_value concat("sum is", sum([device.specific_data.data.field]))
    


Was this article helpful?

Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.