A little known fact about ServiceNow and MID Servers is that ServiceNow can be configured such that it can execute shell commands on a computer that hosts a MID Server. Of course, it will only execute commands that it has rights to execute as the user running the MID Server process, but this can be very handy with command line integrations.
In order to have a MID Server execute a shell command, simply create a record on the ECC Queue that has the following information:
Agent: YOUR MID SERVER
Topic: Command
Name (optional): THE COMMAND YOU WISH TO EXECUTE
Queue: Output
Payload (optional): An XML document defining a command to execute.
There are two ways to do this: the name method and the payload method. With the “Name” method, you place your command in the “Name” field fo the ECC Queue record in the format that you normally would on a Shell prompt. With the “Payload” method, you encapsulate the command in an XML document for the MID Server to process.
The advantage of the “Name” method is that it is easy to enter and very readable. The advantage of the “Payload” method is that you may need longer command strings than the name field can support (eg. 120 characters). The Payload field can handle a much larger command.
The Name Method
The following record will execute a directory listing with the “-l” option for the working directory of the MID Server:
Once this executes, a corresponding Input record will be generated:
If you open that record and read the Payload field, you will find the results to me “ls -l” query:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?xml version="1.0" encoding="UTF-8"?> <results probe_time="2165"> <result command="ls -l"> <stdout>total 52 drwxr-xr-x 2 john john 4096 Mar 28 11:11 bin drwxr-xr-x 2 john john 4096 Mar 6 11:25 conf -rwxr-xr-x 1 john john 5715 Mar 28 11:11 config.xml drwxr-xr-x 2 john john 4096 Mar 6 11:25 etc drwxr-xr-x 2 john john 4096 Mar 6 11:32 extlib drwxr-xr-x 8 john john 4096 Mar 6 11:25 jre6 drwxr-xr-x 2 john john 4096 Mar 6 11:25 lib drwxr-xr-x 2 john john 4096 Mar 6 11:33 logs drwxr-xr-x 2 john john 4096 Mar 6 11:25 properties -rwxr-xr-x 1 john john 16 Jan 16 14:38 start.sh -rwxr-xr-x 1 john john 15 Jan 16 14:38 stop.sh drwxr-xr-x 4 john john 4096 Mar 6 11:33 work</stdout> <stderr/> </result> <parameters> <parameter name="topic" value="Command"/> <parameter name="queue" value="output"/> <parameter name="error" value=""/> <parameter name="from_sys_id" value=""/> <parameter name="sys_id" value="bc7e5b29508520006d4913147419ba01"/> <parameter name="state" value="ready"/> <parameter name="from_host" value=""/> <parameter name="agent" value="mid.server.DEB1"/> <parameter name="processed" value=""/> <parameter name="ecc_queue" value="bc7e5b29508520006d4913147419ba01"/> <parameter name="response_to" value=""/> <parameter name="source" value=""/> <parameter name="sequence" value="1365a5ab1950000001"/> <parameter name="name" value="ls -l"/> <parameter name="table_name" value="ecc_queue"/> <parameter name="agent_correlator" value=""/> </parameters> </results> |
The “Payload” Method
The payload method will yield the same results as the “Name” method, but the difference is in the creation of the initial output ecc queue record.
Instead of placing the command in the “Name” field of the ECC Queue record we make up a small XML Document and place it in the Payload field.
In this example, we want to see what files within the MID Server installation have changed today:
find /home/john/mid/deb1 -type f -mtime -1 -exec ls -al {} \;
To do this using the Payload method, we create an ECC Queue record that looks like:
The payload as shown in the screenshot is:
1 2 3 | <parameters> <parameter name="name" value="find /home/john/mid/deb1 -type f -mtime -1 -exec ls -al {} \;"/> </parameters> |
The resulting record will be in the same format as using the Name method, so I won’t display it here.
Would it then be possible to pass parameters to the command from say a workflow?
@Adam. You bet. You can write a “Run Script” module in your workflow that takes workflow parameters and generates the Command to execute. Your script would additional post it out onto the ECC Queue and (optionally) wait for the response.
Sounds great, I’d love to be able to turn this into a user provisioning workflow in the future with powershell residing on a mid server.
Is this possible from a Windows command line as well?
OK, answering my own question. This can be done from a windows cmd line in the same way. The command I have been wanting to use however “type C:\xxx\xxx.xml” does not return anything. Perhaps it is because the file is too big, or has XML data inside?
@Dan…Make sure to try double slashing all your backward slashes to escape those characters.
hello John
I am very thankful to you & glad that I found this log.
Inline with this blog I was trying to use commands through midserver and got results as you described.
But when I try the same using powershell I get nowhere, I hope you can provide some pointers.
This is what I am trying –
I have a midserver on a AD server and from servicenow try “powershell -file “C:\PS\date.ps1″” but it doesnt work, meaning I dont get input record n it just stays as “processing”
date.ps1 just has date command.
But when I include this in a bat file and use bat file as a command in ECC record, it works and I get back datetime in XML payload.
My aim is to test AD account enable/disable using a short PS script from servicenow.
This script “UserTest.ps1” works on the AD server from PS console aswell as CMD –
$AdminUserName = “userabcdddd”
$AdminPassword = cat C:\ps\securestring.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminUserName, $AdminPassword
Disable-ADAccount -identity dal -credential $cred -server localhost
I included this “UserTest.ps1” in a bat file disableuser.bat and that also works from cmd but now when I call bat file from Command it stays in Processing and nothing happens.
Nothing in midserver log or system logs.
I can see in mid agent log –
Probe: Command:C:\PS\disableuser.bat Worker starting: Command
I really hope this is possible without an orchestration license 🙂
Regards
Kumar
Hi, John, I love this page! I’m having the exact same issue as Kumar, any help would be greatly appreciated!
Regards,
Dave
Excellent article, it helps us a lot!
Hi John,
I am trying to achieve this using the payload method, however, i am facing some issues. Can you please help me on this:
I receive an error while trying to create a csv file on mid server.
File does get created but some records are not inserted to it. When checked the ecc queue, noticed error messages in input.
The error is:
error=”Unable to find script(s) specified in parameters. Make sure the script(s) associated with probe are passed down properly.” probe_time=”0″ result_code=”82″
Here is the code I am using to form the payload:
sendECC: function (cmd) {
var payload = ” +
” +
” +
” +
”;
var sysid = ”;
var grECC = new GlideRecord(‘ecc_queue’);
grECC.initialize();
grECC.agent = ‘mid.server.’ + gs.getProperty(‘hcm.mid_server’);
grECC.topic = ‘Powershell’;
grECC.name = ‘Windows – PowerShell’;
grECC.source = ‘127.0.0.1’;
grECC.queue = ‘output’;
grECC.payload = payload;
sysid = grECC.insert();
return sysid;
},
cmd is a variable i am passing from another function.
When i try printing it in logs, it looks like this:
ROGER CMD = echo “Contract ID|Contract Description|Purchase Order ID|Purchase Order Description” | Out-File -Encoding utf8 -FilePath D:\PO_IDs_20180720130627.csv
And subsequent logs are also printed which contain the data, i am removing the data here and pasting:
ROGER CMD = echo “DATA GOES HERE” | Out-File -Encoding utf8 -FilePath D:\PO_IDs_20180720130627.csv -Append
I do not understand why that error then and how to fix it.
Any help would be appreciated.
Kind Regards,
Vineetha
I wonder why the payload in my last comment didn’t get pasted correctly.
It goes here:
var payload = ” +
” +
” +
” +
”;
How can i pass variables to the powershell script so it can be used in this script?