Tag: <command> - Send A Device Command / Store a File

Definition

The <command> tag is used to send a command to the device. The <command> tag is also used to retrieve a file from a device or store the contents of a file.

This tag has the following attributes:

Parameters

  • response_timeout (int): The response timeout (in seconds) is the time the PxM Platform waits after issuing a command before it stops waiting for a response, and gives up. The default, when not specified, is 15 seconds.

  • shellprompt (str): This allows the templates <shellprompt> to be overwritten if the command being issued does not return with the standard prompt. See example below.

  • format (update_env, text_capture, output_text, textual_dataset, xml_dataset): When set to update_env it tells the PxM Platform to store the output of the command in a environment variable defined by the attribute attribute.

When set to text_capture this tells the PxM Platform that the output of the command to be run will be stored in a file.

It is set to output_text when used in the version command, more info here: :doc:tag_task_version_command.

The setting textual_dataset is used in the user_show_all task, more info here: Tag: <user-task-user-show-all> .

The setting xml_dataset is used to parse command line XML outputted from a command.

  • attribute (str) : The name of the environment variable that the PxM Platform will store the output of the command in, when format is set to update_env. Used with the regex_capture attribute.

  • regex_capture (str) : This regular expression defines what part of the command output to store when using the format update_env.

  • type (call, tftp, scp, local_shell, cmd, powershell) : Type is used to either call a subtask, or to instruct the PxM Platform retrieve a file. Type is also used to instruct the PxM Platform to run winrm commands on either a command prompt shell or via powershell using cmd and powershell respectively.

  • taskname (str) : This is the name of the subtask to be called, when type is set to call.

  • command (smb.get) : When type is set to local_shell, this instructs the PxM Platform to use the smb.get command to fetch a file from a Windows device.

  • action (retrieve): When the type is to scp, the action value of retrieve tells the PxM Platform to fetch a file over SCP.

  • destination (str) : When type is set to local_shell and command is set to smb.get, then this defines the destination filename where the copied file is to be stored on the PxM Platform.

  • source (str): When type is set to local_shell and command is set to smb.get, then this defines the source filename to be copied from the device via the the PxM Platform created SMB file share. This includes the share name and path.

  • random_filename (str): When type is set to tftp, this attribute defines the format of the random filename. %s being a random 8 characters long string. The resultant filename can then be used with the substitution: %(random_filename)s.

  • newline (crlf, cr, lf, none): Allows a specific new line character(s) to be defined to be sent at the end of the command. Can also be used to send just a new line character(s) with no element text defined.

  • entry_elem (str): When format="xml_dataset", the entry_elem defines the parent tag of the XML that holds each set of sub elements to be processed, i.e. each user data block in a user_show_all task. More info here: :doc:tag_task_user_show_all.

  • preamble_line_count (int) : Tells the output processor to skip the first n lines of text.

  • postamble_line_count (int): Tells the output processor to skip the last n lines of text.

  • section_end_delimiter (str): Used in the user_show_all task to change the delimiter to mark the end of a section. Default if not specified is a newline.

  • Element Text (str): This is the command to be sent down to the device. This can contain one or more substitutions.

Example: Simple Command

In it's most basic form the <command> tag sends a command to a device (in this case the command: iisreset). The and tags then process the response from the device.

1
2
3
4
<command type='cmd'>iisreset
   <success type='ci_match' value=''/>
   <failed type='default/>
</command>

More info here: Tag: <success> and here: Tag: <failed>.

Example: Long Running Task

By default, the PxM Platform waits 15 seconds for the device to reply with it's standard prompt. If a command needs to take longer than this, say a backup or gathering tech support information, then the timeout can be extended like this:

1
<command type='cmd' response_timeout='300'>iisreset</command>

This would override the default 15 second timeout and set the timeout to 300 seconds, or 5 minutes.

Example: update_env

The update_env command allows you to run a command on a device and then store the output in an environment variable. The environment variable can then be used later in the task using a substitution. It is used like this:

1
2
<command format='update_env' attribute='vlan' regex_capture='^Access Mode ```
VLAN: (.-)'>show interfaces %(port)s switchport | include Access</command>

In this example, we can get the vlan that a port is configured in by using (on a Cisco device)::

1
2
3
cisco-2960-001#show interfaces FastEthernet0/1 switchport | include Access
Access Mode VLAN: 1 (default)
cisco-2960-001#

We can use the regex with a single capturing group below to extract the text after Access Mode VLAN:::

1
^Access Mode VLAN: (.-)

This value is then placed in the variable named: vlan and can be used elsewhere in templates with the substitution::

1
%(vlan)s

See Regular expressions for a more detailed overview.

Example: shellprompt

When the PxM Platform issues a command to a device, it expects to see the devices normal prompt back.

Some commands may ask an additional question before the command completes and returns the normal prompt.

Consider deleting a config entry like this::

1
2
3
4
   router> no ip route 192.168.0.0
   Are you sure? y
   Route deleted.
   router>

In this case we would want to run the command, wait for the 'Are you sure?' question, then send a y to then complete the command:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<commands>
      <command shell_prompt='Are you sure?'>no ip route 192.168.0.0
         <success type='ci_in' value='Are you sure'/>
         <failed type="default"/>
      </command>
      <command>y
         <success type='ci_in' value='Route deleted.'/>
         <failed type='default'/>
      </command>
   </commands>

The above command would probably be better defined using the <commandstep> tag, see here: Tag: <commandstep>.

Example: Sending a newline

Variables created in update_env commands only become available in the next command. The commands in which they are set must return a success for this to happen. If you want to display the variable you just set, you must use a <success> element in the next command, and use a attribute inside it.

The simplest way to achieve this is by sending a carriage return or new line character to the device, then you can use the <success> tag set to default. To send an empty command string, the newline attribute MUST be specified:

1
2
3
4
<command format='update_env' attribute='some_var'>...</command>
   <command newline='lf'>
      <success type='default' message='The value is: %(some_var)s'/>
</command>

The values of the newline attribute translate to:

Value Sent to device
crlf \r\n
cr \r
lf \n
none blank

Example: Calling a Subtask

The <command> tag can be used to call other tasks as sub tasks. It is used like this:

1
2
3
4
5
6
<task ...>
   <commands>
      <command type='call' taskname='backup'/>
        <command>...
      </commands>
</task>

This simply calls the task named (in this example 'backup'). The called sub task must succeed before the next command in the commands block will run. Sub tasks can be called anywhere in a commands block, start, middle or end.

Example: SCP File Copy

The <command> tag can also be used to copy files using SCP. First, you need to identify the name of the file you wish to fetch. If you already know the filename and it remains constant, then you simply use:

1
2
3
4
5
6
<commands>
   <command type="scp" action="retrieve">
      <local_filename>%(local_techout_location)s/%(device_name)s/techout.tgz</local_filename>
      <remote_filename>/var/tmp/techout.tgz</remote_filename>
   </command>
</commands>

What this does is tells the PxM Platform to use SCP and to go and retrieve a file. The file to be retrieved is located at the element text of the <remote_filename> tag.

In the above example that is:

1
/var/tmp/techout.tgz

The file is then fetched and stored on |o| at the location defined by the <local_filename> tags element text. More on the <local_filename> tag here: Tag: <tag-local-filename>.

However, if you don't know the filename, i.e. when doing a techout on an F5 the output .tgz file from the techout command contains the hostname.

And as every devices hostname is different, you need to read the filename (containing the hostname) first before you can fetch it.

You would do this by adding an update_env command to get the filename, before the SCP retrieve command, like this:

1
2
3
4
5
6
7
<commands>
   <command format='update_env' attribute='filename_to_fetch' regex_capture='^.-/(.-\.tgz)$'>ls -1 --color=never /var/tmp/-.tgz</command>
   <command type='scp' action='retrieve'>
      <local_filename>%(local_techout_location)s/%(device_name)s/%(filename_to_fetch)s</local_filename>
      <remote_filename>/var/tmp/%(filename_to_fetch)s</remote_filename>
   </command>
</commands>

Here the update_env command uses a regular expression to pull out just the filename, without the path, and store it in filename_to_fetch. Then the scp command can be used to go and get this file and store it within the PxM Platform with the same filename as it was fetched with.

Example: TFTP File Copy

The <command> tag can also be used to copy files using TFTP. The way the PxM Platform uses TFTP is like this:

  • A random filename is created within the PxM Platform.
  • The command is send to the device to generate a file and send over TFTP, but specifically to the random filename thats just been created.
  • The PxM Platform starts the TFTP server and allows just this device to connect in and copy only a file with the random filename.
  • The PxM Platform then renames the file to one specified in that task and stores it.

A typical task to issue a command, and copy a file back over TFTP looks like this:

1
2
3
4
<command type="tftp" random_filename="%s.cfg">copy system:/running-config ```
tftp://%(|o|_address)s/%(random_filename)s
   <local_filename>%(local_backup_location)s/%(device_name)s/backup_%(O_TASK_UTC_STARTTIME)s.txt</local_filename>
</command>

The random_filename='%s.cfg' attribute sets the variable random_filename which can then be used as a substitution with:

1
%(random_filename)s

As seen in the actual command that is being sent to the device.

You can also add a time and date stamp string to a filename, using the following substitution:

1
%(O_TASK_UTC_STARTTIME)s

Example: WinRM Powershell command

It is possible to run both Command Prompt and Powershell code on a Windows server via the PxM Platform however we need to tell WinRM where to execute the command or script, we do this by using type='cmd' or type='powershell'. Here is an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<task display_name='Check for Installed Hotfix' name='check_for_installed_hotfix' type='status'>
    <input display_name="Windows Hotfix Number (Format: Q/KB######)" name="hotfix" type="string"/>
    <commands>
    <command type='powershell'>Get-Hotfix | where {$_.HotFixId -like "%(hotfix)s"}
    <success type="ci_in" value="HotFixID" message="Hotfix: &quot;%(hotfix)s&quot; is installed on this system."/>
    <success type="ci_match" value="" message="Hotfix: &quot;%(hotfix)s&quot; is NOT installed on this system."/>
    <failed type="default" />
    </command>
    </commands>
</task>

Example: Text Capture

Capturing the output of a command and storing it in a file is also possible. To do this setup the command as normal but add the format='text_capture' attribute. Then add a local_filename child tag to tell the PxM Platform where and with what filename to store the output. Like this:

1
2
3
4
5
6
<command format='text_capture'>show configuration expanded noprompts
with-keyrings unencrypted
   <local_filename>%(local_backup_location)s/%(device_name)s/backup_%(O_TASK_UTC_STARTTIME)s.txt</local_filename>
   <success type='ci_in' value='config'/>
   <failed type='default'/>
</command>

Example: Windows File Copy

Copying a file from a Windows device is slightly different. It uses the type='local_shell' and command='smb.get' attributes. This tell the PxM Platform that it needs to go and get a file from a Windows device. The source attribute says what file to fetch. This file is accessed through a file share, not through the directory structure. This relies on the fact that the the PxM Platform file share has been setup using the subtask verify_and_create_share, which must be called first.

More info here: verify_and_create_share.

This all needs the following configuration lines to be in place, which are already in place in all the release Windows templates:

1
2
3
4
<configurations>
      <configuration fieldname="share_directory" fieldtype="device" value="%SYSTEMDRIVE%\|o|"/>
      <configuration fieldname="share_root" fieldtype="device" value="|o|_"/>
</configurations>

This sets up two variables that can be used in substitutions to allow common access to both the directory that is shared and the share root that needs to be accessed to fetch any files.

Here's an example of a task that would fetch a file containing the IP configuration from a Windows device:

1
2
3
4
5
6
7
8
9
<task name='version_command' type='status'>
   <commands>
      <command taskname='verify_and_create_share' type='call'/>
      <command response_timeout='60'>ipconfig -all >> %(share_directory)s\%(device_name)s\ip_info.txt</command>
      <command type='local_shell' command='smb.get' source='//%(share_root)s%(device_name)s/ip_info.txt' destination='%(local_filename)s' >
      <local_filename>%(filestore_location)s/%(device_name)s/ip_info_%(O_TASK_UTC_STARTTIME)s.txt</local_filename>
      </command>
   </commands>
</task>

What the task does is:

  • Calls the subtask verify_and_create_share to setup and confirm the file shares
  • Then the command ipconfig -all is run and its output is sent to the file ip_info.txt in the directory that is setup for the the PxM Platform share. We use the default response tags for this command because although is is generating a lot of output (ipconfig -all) this is being sent to a file and the session sees just the device prompt return.
  • Then an SMB get command is used to fetch the file ip_info.txt from the file share on this device, that was mapped to the share directory by the verify_and_create_share task.
  • The <local_filename> tag is then used to define the path and filename of where to store the file on PxM Platform. This then gets substituted in the destination='%(local_filename)s' attribute of the SMB <command> tag.

This will then fetch the file from the share, authenticating using the device's control account and store the file in the PxM Platform. The file can then be downloaded from the -Files- page (for SuperAdmins) or from the My Files page for SysAdmins, if they have been given the 'Download File' task in the appropriate profile.

Parent Tags

Child Tags