uberAgent

Custom Scripts

uberAgent can collect data for arbitrary custom metrics through a generic script execution engine. It runs any type of script at any desired interval, either per machine or per user session.

How to Configure Custom Script Execution

The execution of custom scripts is handled by uberAgent’s endpoint agent. Scripts are configured as part of Timer stanzas in uberAgent’s configuration. The following lists the relevant configuration options:

#   Setting name: Name
#   Description: Arbitrary name for the timer.
#   Valid values: any string
#   Default: empty
#   Required: yes
#
#   Setting name: Interval
#   Description: How long to wait before collecting data again. Unit: milliseconds.
#   Valid values: any number
#   Default: [none]
#   Required: yes
#
#   Setting name: Script
#   Description: Run a script once or periodically, depending on the configured Interval (0 = run only once). The script's output to stdout is sent to the backend, each line as a new event. Can be specified more than once per timer.
#   Valid values: Any valid command line, optionally including command line parameters.
#   Default: empty
#   Required: no
#
#   Setting name: ScriptContext
#   Description: The user context to run a script in.
#   Valid values:
#      Windows:   Session0AsSystem | UserSessionAsSystem | UserSessionAsUser
#      macOS:     Root | User
#   Default: Windows: Session0AsSystem, macOS: Root
#   Required: no
#
#   Setting name: ScriptTimeout
#   Description: Time in ms until a running script is stopped.
#   Valid values: any number
#   Default: 0 (no timeout)
#   Required: no
<!--NeedCopy-->

Please note that uberAgent on the endpoint is running in the context of LocalSystem (Windows)/root (macOS), so the referenced script must be accessible by these accounts. This is particularly relevant when running scripts stored on a network file share.

Script

You can use any script written in your preferred scripting language, e.g., PowerShell, Python, VBScript... On macOS the value of Script is passed as argument to /bin/zsh -c.

uberAgent captures all script output sent to standard output (stdout), i.e., printed to the console. If your script writes output to stderr, then the script execution is considered failed and the script’s output is discarded. Every line of output is sent to the backend as one event. Script output must be formatted as key-value pairs (e.g., key1=value1 key2=value2).

The key name may contain characters that are invalid for field names on some backends. Such characters are automatically replaced with underscores (_). If field names do not start with a letter, they are prepended with uA_. This is done for every type of receiver to ensure that field names are identical on every backend.

Please keep in mind that any data collected in addition to our default dataset has an impact on the generated data volume. Running custom scripts generates additional load on the endpoint the amount of which depends on the executed process (e.g., powershell.exe or cscript.exe) and the underlying data source. Especially Windows Management Instrumentation (WMI) can cause a significant load.

Additionally, please choose an appropriate timer interval for your script. Data that does not change often, like inventory information, probably only need to be collected once a day whereas volatile metrics like network throughput might have to be collected once per minute.

Deployment

uberAgent does not manage the deployment process of custom scripts to the endpoints. Please feel free to use either your existing software distribution system or Splunk’s Deployment Server.

An alternative for PowerShell scripts is to encode the script in Base64 and reference the result as parameter.

# Place the script content in the variable MyScript
$MyScript = @'
script content goes here
'@

# Convert to base64 and output to a file to avoid word wrapping on the commandline.
[Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($MyScript)) > C:\base64_output.txt
<!--NeedCopy-->

Add the result as parameter to PowerShell in a timer:

[Timer]
Name              = Some name
Interval          = 30000
Script            = powershell.exe -executionpolicy bypass -EncodedCommand "JABFAHIAcgB ... vAGkAbgAgACcAIAAnACkA"
ScriptContext     = UserSessionAsUser
<!--NeedCopy-->

macOS command escaping

Example timer

[Timer]
Name              = Some name
Interval          = 30000
Script            = zsh /Library/Application\ Support/uberAgent/script/myscript.sh
<!--NeedCopy-->

Note that on macOS the script command is internally executed via /bin/zsh -c and special care must be taken when paths contain spaces. The following examples are correct ways to refer to scripts:

# correct strings for the script fields
/Library/Application\ Support/uberAgent/script/myscript.sh
zsh /Library/Application\ Support/uberAgent/script/myscript.sh
zsh "/Library/Application Support/uberAgent/script/myscript.sh"
<!--NeedCopy-->

While these commands fail:

# incorrect strings for the script fields
"/Library/Application\ Support/uberAgent/script/myscript.sh"
"zsh /Library/Application\ Support/uberAgent/script/myscript.sh"
<!--NeedCopy-->

When you test your command on your local machine in a shell, keep in mind that that outer shell interprets your quotes, which is not the case for the command/script path you put in the config.

Script Context

Custom scripts can be executed in different contexts, depending on the operating system.

Windows

  • Session0AsSystem: the script runs in session 0 as LocalSystem.
  • UserSessionAsSystem: the script runs in every interactive user session as LocalSystem.
  • UserSessionAsUser: the script runs in every interactive user session as the user logged on to the session.

macOS

  • User: specifies the user as which the script is executed. The script is executed once as every logged-in user at the time of the timer interval. This does include users logged in via SSH.
  • Root: either explicitly set or if no script context is specified, the script is executed once as the root user.

The script context is configured per timer. Of course, you can configure multiple timers for independent execution of different scripts.

Session GUIDs on Windows

To uniquely identify RDS sessions, uberAgent creates its own session GUIDs. These GUIDs are part of all sourcetypes containing data related to user sessions (e.g., logon and logoff).

If the data from a custom script needs to be associated with a specific session, the script should make use of the session’s GUID.

Scripts can read session GUIDs from the registry key HKLM\SOFTWARE\vast limits\uberAgent\SessionGuids. Each value name is the ID of a Windows session. The associated value data contains uberAgent’s session GUID.

Sourcetype

The sourcetype used for the script’s output is a concatenation of uberAgent:Script: and the timer name specified in uberAgent’s configuration.

Examples

For examples that make use of the custom script functionality please see the practice guide section. Another example can be found here.

Custom Scripts