Instruction XML management cmdlets

Instruction XML management cmdlets allow you to create or modify instruction XML files, which can then be uploaded to the 1E Platform.

About instruction XML files

Platform instruction XML files are the standard encoding for instructions. Within an XML file, an instruction contains content, which is written using the SCALE language, and optionally one or more resources, which correspond to embedded files. Resources in an instruction XML file are copied to the platform background channel server when the instruction is uploaded to the 1E Platform. Subsequently, they can be retrieved during instruction execution and then used in the instruction. Typically, an embedded resource is a PowerShell script or an executable file, but embedded resources can specify any file that is appropriate.

When embedded resources are downloaded, the Content Distribution subsystem ensures they are transmitted to devices efficiently and quickly without consuming unnecessary network bandwidth.

Managing XML instructions

The XML management cmdlets provide two key areas of functionality as described below.

Dynamic instruction execution

The dynamic instruction invocation functionality creates XML instructions that are uniquely named, and then uploads and executes them. You can use dynamic instruction invocation to do the following:

  • Run a PowerShell script on devices.
  • Run an executable program on devices.
  • Query any of the platform Activity Record tables on devices.
  • Run a piece of SCALE code on devices.
  • Copy one or more files to a specified location on devices.

These functions are carried out via the invoke-1Edynamic cmdlet whose syntax is discussed below.

Permanent instruction management

You can also create permanent instruction files using the XML management cmdlets. These can contain arbitrary SCALE payloads. As a convenience feature, you can also wrap any inbuilt SCALE function in a permanent instruction. This makes it easy to leverage the powerful 1E Client capabilities directly.

Creating instructions dynamically

As discussed above, the invoke-1Edynamic cmdlet is the core cmdlet used when creating dynamic instructions. Using this cmdlet, you can execute a script, run an executable program, embed a  SCALE snippet, or query any platform Activity Record table quickly. You can also use it to create an instruction which will copy one or more files to a specified path on the target devices.

Invoke-1EDynamic -Script|-Query|-Scale|-Executable|-Files <path|query> [-Path <path>] -TargetScope|-TargetFqdns <scope|fqdns>  [-Force] [-Parameters <parameters>] [-Schema <schema>] [-DataSource <datasource>] [-RowSourceType <rowsourcetype>]

The -script argument must be followed with the name or path to a PowerShell script.

The -query argument must be followed by an appropriate query to a platform Activity Record table.

The -scale argument must be followed with the name or path to a file containing the SCALE code to be run.

The -executable argument must be followed with the name or path to an executable file.

The -Files argument must be followed with the name of one or more files. To specify multiple files, use a PowerShell array.

The -Path argument is ignored unless the -Files argument is specified. If -Path is specified, it defines the absolute path to which the files specified will be copied on the target devices.

The -Force argument is ignored unless the -Script argument is supplied. If specified, it causes the generated SCALE to override the PowerShell execution policy on the target device(s) so that the script will execute regardless of local execution policy.

The -Parameters argument optionally specifies one or more parameters as a string or a string array, for example. "param1" or @("param1","param2",...).

If specified, these parameters are passed to the invoked script or executable. The parameters argument is currently ignored for the -query and -scale options.

The -Schema argument optionally provides an alternative schema for the results to be returned by the script, query, or scale snippet. By default, the schema for these results is defined as an int64 ExitCode value and a String(8000) Output value.

The -DataSource argument specifies the data source for a server-side instruction. If supplied, this infers that the instruction is to run server-side. It is only effective if the -Scale argument has been provided to supply an instruction payload, otherwise, it is ignored.

The -RowSourceType argument specifies the type of row set that should be returned for a server-side instruction. If not specified, a default of Generic will be used.

If you override the schema, then the script, query, or scale snippet is assumed to return results that match the schema you provide. For a script, it should provide the results back in JSON format so they can be serialized correctly.

This argument is ignored for the -Files option.

You must have a valid instruction code signing certificate to use this cmdlet.

Protect-1EInstructionxml -Path <filepath>

This cmdlet invokes the platform instruction signing tool. The instruction file will be signed with the user's instruction code signing certificate, which must be in the local machine certificate store under the Personal store location.

An XML file must be signed before it can be uploaded. To upload a signed XML file, use the publish-1Einstruction cmdlet. Refer to Instruction management cmdlets.

Note the following:

You may need to configure the platform Instruction signing tool, which is used by the 1E PowerShell Toolkit, before signing instructions. To configure the signing tool, locate the configuration file, which is called Tachyon.InstructionSigner.exe.config located in your 1E PowerShell Toolkit installation folder.

The shipped copy of the configuration file is shown below.

You may want to change the following settings. (Note that the SigningExecutable value is not used in the context of the 1E PowerShell Toolkit and will not require configuration.)

  • The Signing.StoreLocation setting can be either "CurrentUser" to look for the certificate in the current user's certificate store, or "LocalMachine" to look for the certificate in the local machine certificate store.
  • The Signing.StoreName setting specifies which named store entry is to be searched for a certificate. The default setting, "My", specifies that the Personal certificate store entry is searched.
  • The Signing.Subject setting specifies the allowable subject name for a code signing certificate. If set to "*", any subject is accepted. Otherwise, the subject must match the value specified. As shipped, this is set to '*' and will match any subject.
Copy
<?xml version="1.0" encoding="utf-8"?>
<configuration>
 
  <appSettings>
 
    <add key="SigningExecutable" value="C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe"/>
    <add key="SigningParameters" value=""/>
 
    <!-- Signing certificate store, e.g., My (Personal), TrustedPublisher (Trusted Publishers) etc. -->
    <add key="Signing.StoreName" value="My"/>
 
    <!-- Signing certificate location. Valid values LocalMachine and CurrentUser. -->
    <!-- If you are signing the resources then this has to be CurrentUser -->
    <add key="Signing.StoreLocation" value="LocalMachine"/>
     
    <!-- To find certificate from cert store using subject name. This value can be set to "*" to mean "use the first active certificate in the StoreLocation that contains a private key" -->
    <add key="Signing.Subject" value="*"/>
  </appSettings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
  </startup>
</configuration>

If you have an error code attempting to sign an instruction, try running the tachyon.instructionsigner.exe utility directly, specifying the XML file as an argument. This will show detailed logging on the screen, which may help to troubleshoot the issue.

You must have a valid instruction code signing certificate to use this cmdlet.

Note that acceptable code signing certificates must be associated with a specific cryptographic provider.

You can create a test certificate like this using PowerShell:

Copy
New-SelfSignedCertificate -FriendlyName "Code Signing Lab Use Only" -CertStoreLocation Cert:\LocalMachine\My -Subject "Code Signing Lab Use Only" -Type CodeSigningCert -HashAlgorithm SHA512 -Provider "microsoft enhanced rsa and aes cryptographic provider"

Self-signed certificates should only be used in lab environments, not production environments.

Ensure that the tachyon.instructionsigner.exe.config file has the appropriate cert store (localmachine\my) and that the subject entry is configured like this:

Copy
<add key="Signing.Subject" value="CN=Code Signing Lab Use Only"/>

This certificate will be accepted for signing, but the platform will not accept it unless the certificate public key (as a .CER file) is in the trusted root and trusted publisher locations in the local machine cert store, and the appropriate thumbprint is associated with an instruction prefix in the platform license file.

Set-1EDynamicinstructionset -Name <set name>

This cmdlet sets the name of the instruction set to be used when publishing and running dynamic instructions. By default this is DynamicScripting, but you can use this cmdlet to override it. The instruction set is created automatically when an instruction is first published to it.

Get-1EDynamicinstructionset

This cmdlet returns the current dynamic instruction set name.

Set-1EInstructionPrefix

This cmdlet sets the instruction prefix to be used when creating dynamic instructions. The default will be the value of the $INSTPREFIX variable in the PS1ETachyonToolkit.psm1 module file.

Get-1EInstructionPrefix

This cmdlet gets the instruction prefix to be used when creating dynamic instructions.

Creating permanent instruction XML files

You may also wish to create instructions which are intended for long-term use. Unlike the dynamically created instructions associated with the invoke-1Edynamic cmdlet, these instructions are intended to be uploaded to the platform and then used repeatedly.

The dynamic instruction invoke-dynamic cmdlet is convenient when you want to create ephemeral instructions to perform simple tasks. For more complex instruction management tasks, you can use the cmdlets below to create permanent instructions. These cmdlets simplify the process of creating instruction XML files which can then be uploaded to the platform or loaded into the Tachyon Instruction Management Studio (TIMS) authoring tool for further modification.

For some practical scenarios using these cmdlets listed below, refer to Scenarios using the instruction XML cmdlets.

New-1EInstructionxml -Name <name> -Path <path> -ReadablePayload <payload> -Content <content> [-Description <description>] [-Schema <schema>] [-Resources <resources>] [InstructionType <type>] [-Version <version>] [-Parameters <params>

-Name: Specifies the name of the instruction. If not fully specified, for example, with the appropriate instruction prefix (for example, 1E-Explorer), then the prefix will automatically be added. For example, a name of MyInstruction will become 1E-Explorer-MyInstruction if the code signing certificate and instruction prefix are set for 1E-Explorer.

-Path: Specifies the name and path of the XML file to be created.

-ReadablePayload: Specifies the readable payload that the instruction will define. For example, return all local disk drives.

-Content: Specifies the SCALE code that will be contained in the instruction. Optionally, you can specify a resource object, which is returned from the New-1EResource cmdlet discussed below. This will add both SCALE content and a resource to the XML instruction.

-Description: Specifies a description for the instruction. If not specified, the ReadablePayload property is used.

-Resources: Specifies one or more resource files to be embedded in the instruction. To specify multiple resources, pass them as an array, for example, @("ResourceFile1.ps1","ResourceFile2.exe")....

You do not need to specify resource files in the -resources property if you use the new-1Eresource cmdlet to manage them. This is because the object returned by new-1Eresource is automatically understood by new-1Einstructionxml to be a resource specification. The purpose of having the -resources property is to allow you to embed additional resources that you will manage in SCALE code yourself.

If you just want a single resource in an instruction to execute, you will probably find it easier to use new-1Eresource, as discussed below, to automatically manage this process.

-InstructionType: Either Question or Action. The default is Question.

-Schema: Specifies a schema for the instruction. If not specified, the default schema is used. The default schema is ExitCode int64, Output string(8000). Refer to Instruction schemas.

-Version: The version for the instruction. If not specified, a version of 1.0 is used.

-Parameters: A set of parameters for the instruction. Refer to Instruction parameters.

You must have a valid instruction code signing certificate to use this cmdlet.

Instruction parameters

Instructions may define one or more input parameters. Input parameters form part of the instruction's readable payload and are then substituted into the instruction body. For example, an instruction might define a parameter UsbOnly, which might be provided to an instruction that was intended to report all device drivers found. Then if this parameter was set, it would cause the instruction to report only USB devices. The mechanism for doing this would be defined in the instruction's SCALE code.

Simple instruction parameters

You can define an instruction parameter list as a simple set of named parameters, for example, MyParam1, MyParam2, ....

In this case the parameters are assumed to be simple unconstrained string parameters. For example, we can create a simple instruction that simply returns the parameters that were passed in. For clarity, this has been split out over several lines.

Copy
new-1Einstructionxml
 -name paramdemo
 -path paramdemo.xml
 -readablepayload ParamDemo
 -Content 'select "%Param1%" result1, "%Param2%" result2;'
 -Parameters "Param1, Param2"
 -schema "result1 string(256), result2 string(256)"

This defines a simple instruction with a single line of SCALE in the payload. The SCALE payload simply selects the passed-in parameters, which are always referred to with % characters around them, and aliases them to two return columns, result1 and result2. The -schema argument then defines these two result columns as string(256).

When we create this instruction and then sign and upload it to the 1E Platform, we will see this when we invoke it:

Copy
Invoke-1EInstruction 1E-Exchange-ParamDemo

You can see that the instruction now has two parameters which are mandatory. The values you supply are then in this case simply returned as the result of the command.

The instruction's readable payload includes the parameters. This information is used by the platform UI to show the instruction and its parameters when it is invoked.

Complex parameters

Parameters can be defined to have a specific data type, which is one of the following:

  • String
  • Int
  • Float
  • Date
  • Time

They can also be specified to have a default value. The default value is used if it is not specifically overridden when the instruction is invoked.

To specify complex parameters to an instruction, you need to create an array of objects that define the parameters and their data type and default values (if any). To understand how to create this object array, see the section below on SCALE method parameters. The cmdlet that retrieves SCALE method parameters creates an array of objects in the required format. This is because, normally, when you use this feature, you will be creating instructions that invoke SCALE methods. However, you can manually create the required object array if you wish.

Creating an instruction that invokes a SCALE method 

SCALE provides a large number of inbuilt methods that the device agent can execute. These provide sophisticated cross-platform capabilities. You might want to invoke one of these methods directly in an instruction.

You can also use the get-1Einfo cmdlet to get information on all methods or detailed information for any individual method. This is discussed in more detail below. For a detailed example, refer to Scenarios using the instruction XML cmdlets.

You can also explore a scenario where we author an instruction using the TIMS tool and then create a similar instruction directly from PowerShell that calls an agent method. Refer to Creating your own cmdlet from a 1E Platform instruction.

For example, the Patch.List method returns the status of Microsoft patches on a target device. You can easily create an instruction that invokes any SCALE method, providing the required parameters, and with the output schema automatically created for you. You do this using the new-1Einstructionxmlformethod cmdlet that is discussed in more detail below.

When you use this cmdlet, code to run the specified method is translated into a platform instruction XML file, ready to be signed (using the protect-1Einstruction cmdlet) and uploaded to the platform (using the publish-1Einstruction cmdlet).

Any parameters associated with the method are automatically created as instruction parameters and will be passed to the method when the instruction is executed.

Once you have uploaded the instruction, you can run it from PowerShell using the invoke-1Einstruction cmdlet, or turn it into a PowerShell cmdlet using the new-1Ecmdlet cmdlet. 

New-1EInstructionXmlForMethod -MethodName <method> [-IncludeOptionalParams] [-OptionalParams <params>]

This cmdlet creates an XML instruction file that invokes the specified method. The file is automatically named based on the method specified.

-MethodName is the name of the scale module and method. For example, Patch.List.

-IncludeOptionalParams: If specified, optional parameters for the method are also included as parameters to the instruction. For example, Patch.List has five optional parameters and no mandatory parameters. If the -IncludeOptionalParams switch is not specified, then no parameters are specified for the instruction. If -IncludeOptionalParams is specified, then all three optional parameters are specified as instruction parameters.

-OptionalParams: This parameter allows you to specify that optional method parameters will be included as instruction parameters. If not specified, optional method parameters are not included as instruction parameters.
This is because optional method parameters do not necessarily have default values and may change the behavior of the method if specified, so you don't normally want to include them unless you are going to provide values for them. When the OptionalParams parameter is specified, it allows you to supply a list of parameters separated by commas that, if they correspond to method parameters, will be included in the instruction input parameters. For example, the Patch.List method has the optional parameters, Source, PatchSpec, CheckOnline, CabFilePath, and TimeoutSecs. You can specify that any or all of these optional parameters will be included in the input parameters for the generated instruction by specifying them in the -OptionalParams argument. For example, to include the Source and PatchSpec arguments, specify -OptionalParams "Source, PatchSpec".

If you then run the generated instruction, it will support the optional parameters -Source and -PatchSpec.

This cmdlet requires a file, methods.json. This file contains metadata about all available SCALE methods and their parameters.

You can examine this information with the Get-1EMethodInfo cmdlet discussed below.

Historically, this file was bundled with the 1E PowerShell Toolkit. However, because methods change over agent releases, you now create this file using the TIMS tool. TIMS supports the ability to export all SCALE methods to a metadata file.

To export the data, run the TIMS tool with the /debugging command line option and then select the Tools/Download SCALE metadata option from the menu. Copy this file to the Toolkit folder and name it methods.json, and you will have an up-to-date list of methods that the Toolkit can use when creating instructions and cmdlets.

Example:

Copy
New-1EInstructionXmlForMethod agent.echo

You must have a valid instruction code signing certificate to use this cmdlet.

Get-1EMethodInfo [-MethodName <method name>]

This cmdlet retrieves information about all SCALE methods or a selected method.

Copy
Get-1EMethodInfo agent.log

Each SCALE method takes zero or more parameters, and returns a result set which is defined by a schema. To examine the SCALE method parameters and schema, use the get-1Emethodparameters and get-1Emethodschema cmdlets below.

Get-1EMethodParameter -MethodName <method name> [-NoTranslate]

This cmdlet returns the parameters associated with a method. The -NoTranslate option causes the parameters to be returned with their data types and default values as defined directly for the method.

However, these data types and default values do not always map directly to the available input parameters for instructions. Therefore, by default they are translated. For example, a parameter of type boolean with a default value of true is translated to be of type int with a default value of 1 because instruction parameters do not support boolean types.

The example below shows the available method parameters for the Agent.Echo method.

Copy
Get-1EMethodParameter agent.echo

Get-1EMethodSchema -MethodName <method name> [-AsText]

This cmdlet returns the schema for a method. If the -AsText option is specified, the schema is returned in text form. In this format, it can be directly supplied as the -schema argument to new-1Einstructionxml if you wish.

Note that when you use the New-1EInstructionXmlForMethod cmdlet, this cmdlet is used internally to ensure that the generated instruction has the appropriate schema.

Copy
Get-1EMethodSchema agent.echo

New-1EResource -Path <path> [-ResourceVar <varname>] -CopyTo <destpath> [-Execute] [-InterpretAsJson] [-Force]  [-Parameters <parameters>] [-Schema <schema>]

This cmdlet returns a resource object that can be used directly as an argument to the -Content property of the New-1EInstructionXml cmdlet. Resource objects are discussed in more detail below.

-Path: Specifies the path to the file to be used as the resource object.

-ResourceVar:  If specified, it defines the SCALE variable name to be used when retrieving the resource. If this is not specified, a default name Resource is used, as you can see in the examples below.

-CopyTo: If specified, it causes the resource object SCALE code to include code to copy the embedded resource to the specified destination path.

-Execute: If specified, it causes the resource object SCALE code to include code to execute the embedded resource. This option is mutually exclusive with -CopyTo.

-InterpretAsJson: If the -Execute option is set, it specifies that the resource object SCALE code to execute the resource should require that the results from executing the resource be interpreted as Json.

The -Force argument is ignored unless the -Execute argument is supplied and the resource object is a PowerShell script. If specified, it causes the generated SCALE to override the PowerShell execution policy on the target devices so that the script will execute regardless of local execution policy.

-Parameters: Specifies one or more parameters to be passed to the executed resource. Multiple parameters are defined as an array.

-Schema: If specified, it overrides the default schema which is "ExitCode Int64, Output string(8000)".

Using New-1EResource in conjunction with New-1EInstructionXml

The New-1EResource cmdlet is intended to simplify the creation of instructions that use embedded resources. In many cases, the resources are intended to be executed, which requires some SCALE code to be created. New-1EResource automates this process.

The simplest usage of New-1EResource is to specify just a source file. In this case the -Path parameter is assumed by PowerShell.

The output from New-1EResource is a resource object. It contains the resource type, the SCALE content, which will load the resource inside an instruction, a full path to the resource file, and a schema, which is currently fixed to define an exitcode and output result.

Copy
New-1EResource script.ps1 | format-list *

If the optional -Execute parameter is passed to New-1EResource, then the SCALE code includes the necessary code to download and execute the resource instead of just downloading it.

In this case, two SCALE variables are used. The second variable will be named xxxResult where xxx is the value assigned to the -ResourceVar property. By default, since we did not specify it, it is set to Resource, so the second variable is named ResourceResult.

You can pass the object returned by New-1EResource to the new-1Einstructionxml -Content parameter. For example:

Copy
new-1Einstructionxml -name MyInstruction -path MyInstruction.XML -ReadablePayload "My New Instruction" -Content (new-1EResource script.ps1 -execute)

When you do this, new-1Einstructionxml automatically adds the resource to the instruction and adds the code to execute it. This means that the resulting instruction will immediately be useable to execute the resource specified. You only need to sign it with protect-1Einstruction, then upload with publish-1Einstruction, and then run it.

The instruction name in this example was given as MyInstruction. When the instruction XML file is created, this will automatically contain the full prefixed instruction name. The full prefixed name depends on the name prefix that you have defined using the Set-1EInstructionPrefix cmdlet. For example, if the instruction prefix is 1E-Explorer, then the full instruction name will be 1E-Explorer-MyInstruction.

To sign and subsequently upload the instruction for execution, you need to possess a code signing certificate and you need a platform license for the instruction prefix that you are using.

Running executables instead of scripts

New-1EResource also handles executable resources. Additionally, you can pass parameters to both scripts and executables. For example, we could run the devcon.exe utility and pass it the parameter classes. As you can see, the SCALE code to download the resource, then append the parameters and execute it is automatically generated.

Copy
New-1EResource c:\downloads\devcon.exe -execute -parameters classes | format-list *

You can use the -InterpretAsJson parameter to New-1EResource to specify that the results from the resource should be interpreted as JSON. Note that in this case you will probably want to override the default schema for the instruction, which is suitable for simple scripts and executables, and define the results you want to return as a set of columns.

Get-1EResourceInfo -Path <path>

This cmdlet returns information about all embedded resources in the instruction XML file referenced by <path>.

Copy
Get-1EResourceInfo -path 1E-Exchange-OSQuery.xml

Export-1EResource -Path <path> -Name <name> [-Outfile <outfile>]

This cmdlet exports the resource whose name is specified. If -Outfile is not specified, an output file whose name corresponds to the resource name is written to the current directory. Otherwise, it is written to a file specified by -OutFile.

Update-1EResource -Instruction <instruction xml path> -Path <resource path>

This cmdlet updates the resource (if present) in an instruction and changes any reference to the old resource in HttpGetFile requests so that the hash and size match the new resource.

When the resource has been updated, the instruction XML file is re-signed.

This cmdlet allows you to automate the updating of embedded resources in an instruction as part of a build process. For example, if an executable or script resource used by the instruction changes, you can automatically embed the new updated resource in the instruction.

You must have a valid instruction code signing certificate to use this cmdlet.

Instruction schemas

An instruction must define the schema of the result set that it returns. A default schema which is adequate to run embedded resources that do not return JSON is automatically used unless you override it. The default schema specifies two columns, an integer ExitCode and a string(8000) Output.

The following data types are supported:

  • int32
  • int64
  • string
  • clob
  • guid
  • datetime
  • double
  • bool

You define your schema by simply listing the column names and types, for example:

Copy
column1 string(200), column2 int32, column3 double

If you do not specify a string length, a value of 256 is used by default.

Column names are case-sensitive. You must specify a column name to exactly match the case of the returned data in your instruction.

The Get-1EMethodSchema cmdlet returns a schema directly useable as an instruction schema when the -AsText option is specified.