X2Shell Console Application Language

X2Shell

Originally code named “Batch Runner and Diagnostics for Operating/Networking” (BRANDON), X2Shell was developed as a toolkit to allow sysops and technicians to develop their own apps for performing various tasks. X2Shell apps can access SQL databases, make HTTP calls, send emails, and of course, work with files.

To make your own X2Shell application, simply copy X2Shell.exe to MyAppName.exe and make a new config file called MyAppName.xml. Then, edit the config file and start building as shown below. When you run an X2Shell app, the underlying code creates a memory-only working XML file, called the DataCloud, initially comprised of data collected from the environment. It then walks through the configuration file provided. Any Data elements are copied into the DataCloud(tests permitting) and any Run elements are further stepped through and their executions are performed. Every execution adds its results to the DataCloud and is also able to leverage from the any prior data or execution, as well as the original snapshot of the environment.

By default, the XML-based configuration file, is the given the same name of the EXE that was provided, and can consist of any valid root node, which then contains one or more <Data> or <Run> elements. Both of those elements may contain a ‘test’ attribute. The test should be in the style of an XPath, where a node hit is a pass and a miss is a fail. If no test exists, it is an automatic pass. Each Data element that passes will be copied as is into the Data Cloud. Each Run element can contain any combination of the below Execution Types.


Example (HelloWorld.xml)

<HelloWorld>
<echo>
<line>
Hello World!
</line>
<string>
At the tone, the time will be:
</string>
<string type="XPath">
/X2Shell/run-time/@systemtime
</string>
<line>
BEEP!
</line>
</echo>
</HelloWorld>

Result

C:\> HelloWorld.exe
Hello World!
At the tone, the time will be: 4/18/2020 10:25:42 PM
BEEP!

NOTE: Unless otherwise configured, the resultant data cloud will have a root element named “X2Shell”. To change this, include an attribute named “root-node” with a desired value in the root node of your configuration XML, or include the attribute “use-root” with either “yes” or “true” to use the name of your configuration XML root node as the data cloud root name.

Execution Types

The following are the types of exeuctions that can be performed. They will be the name of the XML element being performed within a Run or batch block.

Basic Commands

If you start by thinking of an X2Shell application as a powerful BAT file, then these commands or their concepts should be somewhat familiar to you. They are just executed a little differently than their BAT file counterparts.

echo

Write some text out to the console, or file (see output)

{ any text to be output }
-OR-
any combination of
<string>
...
</string>
and
<line>
...
</line>
Base Attributes:
new-line=="true|false"

Note: unlike most other commands, the echo execution does not have a <params> node, but instead allows complex strings to be created in the same fashion as complex arguments are creaed in the command process. The desired output is generated from any combination of <string/> or <line/> nodes.


Example

<echo id="ShowUsage" test="(count(/X2Shell/run-time/command-line/arguments/arg) = 1)">
<string>
[
</string>
<string type="xpath" no-preceding-whitespace="true">
/X2Shell/run-time/command-line/arguments/arg
</string>
<string no-preceding-whitespace="true">
] - v1.0
</string>
<line>
This program does some cool stuff
</line>
</echo>

Result

C:\> MyProgram.exe
[MyProgram.exe] - v1.0
This program does some cool stuff

pause

============================================================================== “pause” – Hold processing for some intervention —————————————————————————— Params: method=”console|msgbox|timer” timeout=”number-in-milliseconds” (for timer only) caption=”” text=”” buttons=”ok|ok-cancel|yes-no|yes-no-cancel|retry-cancel| abort-retry-cancel”

path

============================================================================== “path” – Used to get or set the working dir, or list the contents of a path —————————————————————————— Params: command=”get-cwd|set-cwd|list|exists|file-exists|… … copy|move[-file]|move-dir[ectory]|delete|make-directory|make-dir|mkdir” filepath=”somefilepath” (optional – “cwd” is default) destpath=”somefilepath” (only used for “copy” or “move”) This is used to manipulate a local drive or network drive path, or context.

output

============================================================================== “output” – Specify where echo content should be sent —————————————————————————— Params: method=”console|file|both|close” filepath=”somefilepath” filemethod=”create|append” The output command with the file (or both) method, forces all echo statements from that point forward to be sent to the filepath specified. If the filemethod is set to append, then the output file will be opened for and the echo statements will be written at the end, otherwise, any existing content before the output command was issued will be overwritten. The overriding of the echo command will continue until either a new output command is given, or the program terminates.

Spawn Processes

command

============================================================================== “command” – Launch a new process / executable or shell extension —————————————————————————— Params: command=”some.exe” working-directory=”c:\” arguments=”/arg1 /arg2″ (*NOTE: see below) use-shell=”true|false” style=”min|max|hidden|normal” wait-for-exit=”true|false” capture-stdin=”true|false” (**NOTE: see below) capture-stdout=”true|false” capture-stderr=”true|false” * NOTE: Additional arguments may be given as <arg> nodes within the Param. These arg nodes should have the inner text reflecting the value to be used. Further, arg nodes may have “type” and “format” attributes, which will act exactly as the “_type” and “_format” suffixed attributes explained below. For more flexibility, the <arg> nodes also support two additional attributes: “no-preceding-whitespace” and “separator-character”. Giving the first of these a “true” value will simply instruct the argument builder to not add a space between it and the previous arg node. You may instead give your own separator value to be used instead of a space (” “). (i.e. separator-character=”+” ) **NOTE: The option to capture standard input is only used if use-shell = true. Further, an additional node given as <stdin> must be provided within the Param parent node. Like the <arg> nodes above, it supports type and format.

powershell

============================================================================== “powershell” – Run a PowerShell script or applet —————————————————————————— Params: working-directory=”c:\” capture-stdout=”true|false” NOTE: See definition for the “command” action for argument usage

Execution Control

reset

============================================================================== “reset” – Resets the DataCloud to remove all prior execution information —————————————————————————— Params: method=”soft|hard” Both resets will clear the DataCloud, but use a different manner. The soft reset will remove all prior exeuction nodes. The hard reset will rebuild the DataCloud from scratch. A hard reset will also update the systemtime.

run-batch

============================================================================== “run-batch” – Process another batch of commands (typically from transform) —————————————————————————— Params: { List of commands to be run }

dump-log

============================================================================== “dump-log” – Used to dump the current datacloud out to a file or console —————————————————————————— Params: filepath=”output.xml” (or empty for console) rootnode-xpath=”xpath-to-element” (default = “/”) Write out all or part of the XML of the datacloud

stop-if

============================================================================== “stop-if” – Stop processing if this command is run —————————————————————————— Params: method=”this-run|all”

skip-to

============================================================================== “skip-to” – Skip processing if this command is run —————————————————————————— Params: nextCommandType=”{ any valid command type }” (i.e. “pause”) nextCommandId=”{ id of an upcoming command }” end=”true” (actual value is ignored, must be non-empty text)

Transformations

transform

============================================================================== “transform” – Used to apply an external XSL file to a portion of the datacloud —————————————————————————— Params: filepath=”somefile.xsl” source-filepath=”somedocument.xml” -OR- rootnode-xpath=”/datacloud/xpath” The XSL will be applied to the datacloud, optionally at the rootnode-xpath. -OR- By specifying a source-filepath, an external document will be used. NOTICE: An XSLT may be embedded inline as well by NOT specifying a filepath, and instead including an <inline> element with a full XSLT contained Example: <transform> <params rootnode-xpath=”/datacloud/xpath”> <inline> <xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org…”> … </xsl:stylesheet> </inline> </transform>

x2tl

============================================================================== “x2tl” – Apply an {{ X2 Templating Language }} Template against the datacloud —————————————————————————— Params: execute-results=”true|FALSE” Template: (The first element in the commend that is NOT the params) Example: {{ Template }} ==============================================================================

In-Memory Byte Array

clear-bytes

============================================================================== “clear-bytes” – Used to empty out the binary data byte array (bytes) —————————————————————————— Clears out the “bytes” byte array when the contents are no longer needed.

compress-bytes

============================================================================== “compress-bytes” – Used to compress the binary data byte array (bytes) —————————————————————————— Performs ZIP compression on the “bytes” byte array, compressing the contents

decompress-bytes

============================================================================== “decompress-bytes” – Used to empty out the binary data byte array (bytes) —————————————————————————— Performs ZIP decompression on the “bytes” byte array, exploding the contents

User Interface

form

============================================================================== “form” – Build a GUI Dialog Box —————————————————————————— gui: definition gui Attributes: background-color=”” control-box=”true|false” minimize-box=”true|false” maximize-box=”true|false” auto-scroll=”true|false” show-icon=”true|false” show-in-taskbar=”true|false” icon=”” background-image=”” width=”300″ height=”200″ Note: unlike others, the “form” execution does not have a <params> node, but instead allows for a complete UI form to be defined in the XML as a child element called “gui”. A “gui” element can have one or more “layout” elements with attributes: layout Attributes: left=”0″ top=”0″ A “layout” can then have any of the following elements with attributes: label: label Attributes: use-mnemonic=”false” border-style=”none” textbox: textbox Attributes: border-style=”none” scroll-bars=”both” multi-line=”true” password=”false” password-char=”” read-only=”false” button: button Attributes: use-mnemonic=”false” style=”flat” use-style-backcolor=”true” type=”none|yes|no|abort|retry|cancel|ignore” form-accept=”false” form-cancel=”false” image: image Attributes: path=”” border-style=”none” checkbox: checkbox Attributes: auto-check=”true|false” appearance”normal” auto-ellipsis=”true|false” checked=”false|true” check-state=”checked|unchecked” radio: radio Attributes: auto-check=”true|false” appearance”normal” auto-ellipsis=”true|false” checked=”false|true” combobox: combobox Attributes: drop-down-width=”” A “combobox” should contain one or more “item” elements item Attributes: caption=”” listbox: listbox Attributes: allow-multiple=”false|true” A “listbox” should contain one or more “item” elements (see above) checked-listbox: A “checked-listbox” should contain one or more “item” elements (see above) numeric: numeric Attributes: (N/A) date: date Attributes: min-date=”” max-date=”” show-up-down=”false|true”

External Data

http

============================================================================== “http” – Used to get or post contents via HTTP web request —————————————————————————— Params: method=”get|post” uri=”http://….” post-rootnode-xpath=”/” (if method is “post”, what is sent) post-format=”text|xml” (and what format is it sent in)

mail-to

============================================================================== “mail-to” – Used to send results to one or more e-mail recipients. —————————————————————————— Params: smtp-host=”” (either IP address or DNS name of SMTP server) tcpip-port=”25″ (optional – can change for custom port) from=”” (email address of sender) to=”” (one or more email addresses of recipients) subject=”” credentials=”network|none” (if server requires authorization) uri=”http://….” rootnode-xpath=”/” (path to what is being sent) format=”text|xml” (and what format is it sent in)

msmq

============================================================================== “msmq” – Used to send, receive or list contents of a Microsoft Message Queue. —————————————————————————— Params: queue-name=”.\Private$\MyQueue” (path/name of MSMQ) method=”send|receive|list” (note: “list” is non-destructive) rootnode-xpath=”/” (if “send”, path to what is being sent) format=”text|xml” (and what format is it sent in) priority=”lowest|very-low|low|normal|above-normal| high|very-high|highest” (default is “normal”)

sql

============================================================================== “sql” – Perform a Microsoft SQL Server Execution —————————————————————————— Params: method=”recordset|xml|bytes|execute-only” server=”sqlserver\instance” connect=”DataSource=Connection_String” query=”exec my_query @param1, @param2″ row-label=”mydataitem” (default: row) For standard recordsets, the row-label (default is “row”) will be used for each entry in the resulting recordset, with the field names as attributes. NOTE: When using recordset (default) method, do NOT use spaces or special characters for the names of the columns, or you will generate an error. NOTE: Use of the bytes return type will store the resulting single image response in the general byte array “bytes”. If the result will be XML (for instance using the FOR XML option of SQL) use the xml method, and the row-label to indicate the wrapper element. NOTE: If your query or stored procedure has parameters, include them as “param” child elements of the “params” element. Give them a “name” attribute, a “value” attribute, and optionally a “test” attribute. No value attribute will indicate a NULL. A value format of “bytes” to use the general byte array. Example: <sql id=”…” test=”” xpath=””> <params server=”” connect=”” query=”exec my_sproc @p1, @p2, @pImage”> <param name=”@p1″ value=”1″/> <param name=”@p2″ /> <param name=”@pImage” value_type=”bytes”/> </params> </sql>

registry

============================================================================== “registry” – Manage the machine registry (get, set, create, list) ** NOTICE: USE WITH CAUTION!! ** —————————————————————————— Params: hkey=”HKLM|HKCU|HKCR|HKU|HKCC|HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER| HKEY_CLASSES_ROOT|HKEY_USERS|HKEY_CURRENT_CONFIG” subkey=”” method=”get(-value)|set(-value)|create(-key)|list” value-name=”” value-type=”REG_SZ|REG_DWORD” value-data=”” format=”text|xml” Either get, set, create or list a subkey within a branch of the registry.

Compress / Decompress

compress

============================================================================== “compress” – Used to ZIP a file —————————————————————————— Params: filepath=”compressed.zip” mode=”create|update” source-filepath=”some-file-to-compress” saveas-filepath=”directory/path/file_name.ext” delete-onsuccess=”false|true” Either create a new or update an existing ZIP file by adding the source file and saving it in the ZIP as the specified filepath. If delete-onsuccess, then the source file will be deleted after compression.

zip

============================================================================== “zip” – (aka zip-files) Creates or Updates a ZIP file from one or more files —————————————————————————— Params: filepath=”some-files-to-zip*.*” destpath=”my-zip-file.zip” action=”ADD | move” overwrite=”true | FALSE” If the action is set to “move”, the source file will be deleted once added If overwrite is set to “true” then any pre-existing zip will be overwritten Example: <zip id=”…” test=”” xpath=””> <params filepath=”” destpath=”” action=”” overwrite=”” /> </zip>

unzip

============================================================================== “unzip” – (aka unzip-files) Expands a ZIP file to a specified directory —————————————————————————— Params: filepath=”source-file-name.zip” destpath=”file-path-to-extract-into” Example: <unzip id=”…” test=”” xpath=””> <params filepath=”” destpath=”” /> </unzip>

list-zip

============================================================================== “list-zip” – (aka read-zip) Lists the contents of a ZIP file —————————————————————————— Params: filepath=”source-file-name.zip” Example: <list-zip id=”…” test=”” xpath=””> <params filepath=”” /> </list-zip>

Miscellaneous

new-id (guid)

============================================================================== “new-id” – (aka guid) Used to generate one or more GUIDs —————————————————————————— Params: count=”1″