
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
07-31-2018 09:46 AM - edited 12-29-2023 11:10 AM
NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.
DIFFICULTY LEVEL: ADVANCED
Assumes having taken the class SSNF and has good advanced level of knowledge and/or familiarity with Scripting in ServiceNow. Assumes good knowledge and/or familiarity of Orchestration, Workflows, and Scripting in ServiceNow.
Originally Orchestration contained a baseline Run PowerShell Activity. Unfortunately this was deprecated in way back in the Helsinki release Patch 1. With this article I show how you can bring back that functionality using Orchestration's Custom Activity Builder.
I will also introduce a couple of best practices I use when creating Custom Workflow Activities:
1. Post-Processing boiler plate scripts
2. Custom Activity Script Includes
Pre-Requisites
- This lab will work fine on your Personal Developer Instance (PDI).
- You will need to activate the Orchestration plugins to be able to create Custom Activities.
Mini-Lab: Activating Orchestration - Some Notes - You will need to install your own local MID Server if you do not have one already.
ServiceNow Discovery 101: Setting Up a Local MID Server
TIP: We will build this example Globally scoped. If you want to put this into the actual baseline PowerShell folder then you will need to change the application scope to PowerShell, create the new Custom Activity, and clear out the Category. The new activity will then appear in the PowerShell folder, and you can still use it in your Globally scoped workflows.
TIP: You might want to create an update set to capture your work. You can click on the Publish button on the new Custom Activity and the Test Workflow to save your work in the update set.
Lab 1.1: Script Include Library
1. The first step is to create a Script Include library to support our new Custom Activity. This is a best practice with the following benefits:
- Maintainability: The code is centralized into a single location for easy searchability, and only needs modification in a single location.
- Reusability: Creation of a script function library promotes reusability, and reduces time-to-completion.
- Generic code base: Promotes greater reuse, and data driven scripting. The script can be used by a wider variety of calling functions. Think Swiss-Knife!
2. Navigate to System Definition > Script Includes.
3. Click on the New button.
4. Fill in the form with the following:
Name: ML_WorkflowActivityUtils (ML stands for Mini-Lab 😁)
Accessible from: All application scopes.
Description: Workflow Custom Activity utility functions
Script:
var location = 'SI:' + this.type;
var ML_WorkflowActivityUtils = Class.create();
ML_WorkflowActivityUtils.prototype = {
initialize: function (location) {
this.location = location;
},
// method to handle the post process results of a Custom Activity
postProcessing: function (executionResult, activityOutput) {
if (gs.nil(executionResult.error)) {
// initialize our result variable
activityOutput.result = "success";
try {
var output = executionResult.output;
// if our output returned information then capture it
if (output != null) {
activityOutput.output = output.substring(output.indexOf('<Objects>'));
gs.info('---> [{1}] activityOutput.output: {0}',
[activityOutput.output, this.location + '.postProcessing']);
}
} catch (err) {
gs.error('---> [{1}] ERROR: {0}', [err, this.location + '.postProcessing']);
}
} else {
// we had something bad happen, handle it!
activityOutput.result = "failure";
activityOutput.errorMessage = executionResult.errorMessages;
gs.info('---> [{1}] activityOutput.errorMessage: {0}',
[activityOutput.errorMessage, this.location + '.postProcessing']);
}
},
type: 'ML_WorkflowActivityUtils'
};
5. Click on the Submit button to save your work.
Lab 1.2: Custom Workflow Activioty
1. In your instance navigate to Orchestration > Workflow Editor, and open the Workflow Editor
2. In the Workflow Editor navigate to the Custom tab, and click the plus ("+") button to create a new Activity.
3. Choose the Powershell Template from the menu. This will display the Activity Designer with the template form.
4. Fill out the form with the following:
Name: PowerShell Command
Short Description: Execute a PowerShell Command
Accessible from: All application scopes
Category: PowerShell
Description: Activity to run a custom PowerShell
5. Click on the Continue button.
6. On the Inputs form Add three fields
Name: Hostname, Type: String
Name: Command, Type: String
Name: Credential, Type: String
7. Click on the Continue button.
8. Fill in the form with the following:
Target Host: drag the Hostname input to this field
Script Type: Custom PowerShell command
Command: drag the Command input to this field
Credential tag: drag the Credential input to this field
9. Click the Continue button.
10. Add three Output fields (from this point forward the creation of the new activity will be the same as in my previous article).
Name: result, Type: String
Name: output, Type: String
Name: errorMessage, Type: String
11. Click on the Go to Post-Processing button.
12. Fill in the Post-Processing form with the following:
Output process script:
var location = 'WFCA: PowerShell Command';
new ML_WorkflowActivityUtils(location).postProcessing(executionResult, activityOutput);
13. Click the Continue button.
14. Add two condition fields:
Name: Success
Condition: activityOutput.result == 'success'
Else: false
Order: 100
Name: Failure
Condition: leave blank
Else: true
Order: 200
15. Now click on the Save button to save your work.
Test the Workflow
Now we are ready to actually test our new Custom Activity!
1. In the Workflow Editor navigate to Custom > Global > PowerShell. You will now see your new PowerShell Command Activity present.
2. Navigate to the Workflows tab, and click the plus "+" button to create a new workflow.
3. Fill in the New Workflow form with the following:
Name: PowerShell Command Workflow
Table: Global
Description: Testing the PowerShell Command Custom Activity
If condition matches: -- None –
4. Click the Submit button to start building your workflow.
5. Drag your custom PowerShell Command Activity onto the new workflow and fill in the properties form with the following:
Name: PowerShell Command Test
Hostname: 127.0.0.1
Command: dir
6. Click the Submit button to save the activity to the workflow.
7. To hang onto our results for the Custom Activity we will need to add a Run Script Activity after the PowerShell Command; in the Success branch. The after-activity results from your Custom Activity are available for coding in the Data tab, and might have a different number. The number is based on when the activity was put onto the canvas and represents the order in which it was placed on the canvas. So a "3" means it was the third activity placed on the canvas.
NOTE: It is important to understand that workflow.scratchpad (and other workflow variables) are not available inside the Custom Activity! They can only be passed around through activity parameters.
8. Navigate to Core tab > Utilities and drag out a Run Script Activity onto the Success output line of your custom activity.
9. Fill in the properties form with the following:
Name: Handle Results
Script:
var location = 'WF:' + context.name + '.' + activity.name;
var psCommandTest = data.get(3);
gs.info('---> [{1}:{2}] previous_activity.result: {0}',
[psCommandTest.result, new GlideDateTime().getNumericValue(), location]);
gs.info('---> [{1}:{2}] previous_activity.output: {0}',
[psCommandTest.output, new GlideDateTime().getNumericValue(), location]);
// package up the results for pushing onto the workflow (future use)
var results = {output : '', error : ''};
results.output = psCommandTest.output;
results.error = psCommandTest.errorMessage;
workflow.info('---> [{1}:{2}] {0}',
[results.output, new GlideDateTime().getNumericValue(),location]);
workflow.scratchpad.output = results; // pass the results out onto the data stream
10. Click the Submit button to save your Activity to the workflow.
NOTE: The "data.get(3)" numeric value must match your Activity Outputs numeric value!
11. Add another Run Script Activity into the Failure output of the Run PowerShell Script Test activity.
Best Practice: You should always handle potential errors!
12. Fill out the form with the following:
Name: Handle Failure
Script:
var location = 'WF:' + context.name + '.' + activity.name;
var psCommandTest = data.get(3);
try {
gs.info('---> [{1}:{2}] previous_activity.result: {0}',
[psCommandTest.result, new GlideDateTime().getNumericValue(), location]);
gs.info('---> [{1}:{2}] previous_activity.output: {0}',
[psCommandTest.output, new GlideDateTime().getNumericValue(), location]);
gs.error('---> [{1}:{2}] previous_activity.errorMessage: {0}',
[psCommandTest.errorMessage, new GlideDateTime().getNumericValue(), location]);
// package up the results for pushing onto the workflow (future use)
var results = {output : '', error : ''};
results.output = psCommandTest.output;
results.error = psCommandTest.errorMessage;
workflow.info('---> [{1}:{2}] {0}',
[results.output, new GlideDateTime().getNumericValue(),location]);
workflow.scratchpad.output = results; // pass the results out onto the data stream
}
catch(err) {
gs.error('---> [{1}:{2}]\n{0}',
[err, new GlideDateTime().getNumericValue(),location]);
}
13. Wire up the workflow to match the following diagram:
14. Run the workflow.
15. You should have a successful run that looks like this:
16. From you instance navigate to System Logs > System Log > All. The System Logs list view will be displayed.
17. Filter for messages starting with "--->", and order by Created descending. You should see an entry similar to the following:
TIP: Notice the millisecond times in the messages. This can help you know exactly when something was run and in what order (the Created column only goes to the second).
SAD NOTE: Currently developers are not allowed to modify existing or to create their own Custom Activity templates.
SECOND SAD NOTE: You are limited to String, Integer, Boolean, Decimal, Object, Array, and Encrypted for Custom Activity input variable types. Choice and Reference fields are not unfortunately not available.
COOL NOTE: Notice that if you want to modify your Custom Activity script you don't have to get into the Workflow Editor/Custom Activity Editor to do so, you just have edit the Script Include! Thus the beauty of Script Includes.
And there you go! You have created your first generic PowerShell Custom Activity!
Enjoy!
Steven Bell.
If you find this article helps you, don't forget to log in and mark it as "Helpful"!
Originally published on: 08-22-2018 7:32 AM
I updated the code, fixed broken links, and brought the article into alignment with my new formatting standard.
- 4,177 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
I basically followed it with SSH instead PowerShell and 'ls' command instead 'dir' and it worked just fine on Linux MID server

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Excellent, thanks for checking it out for SSH!