alexankaras
ServiceNow Employee

In this article, we'll be walking through how to automate goal progression in Strategic Planning by making an example based on the completion of aligned planning items against a goal or target. Going through this example, will give you an understanding of how you could build your own, scalable and user-friendly target automation and confidently expand on this for your own use-cases.

Do you need to understand how the Goal Framework for SPM works? You should go through this great walkthrough/demonstration by the product team: Youtube: Strategic Planning Workspace: Strategy and Goals

Disclaimer: The specific solution described is achieved through configuration. There is no liability for ServiceNow to provide support, apply changes, fix defects and review impact during future upgrades for the specific example that I provided in this article.

What could we achieve with target automation?
We'll start in reverse order - what are we trying to achieve with this & how does it look like?

Let's take an example HR Portfolio Plan where we've planned for 2 goals - both having a target defined:

alexankaras_2-1771431798647.png



- Goal 1: Digitize HR Workflows -> Target 1: Implement at least 5 new HR workflows by Q2 2026


Target Details
Start Value: 0
Final Target: 5
Unit of measure: Count (#)


There are 5 projects aligned with the parent goal and only 1 is completed thus far:

alexankaras_0-1771432021160.png



- Goal 2: Migrate Legacy Systems to Cloud Services -> Target 2: Complete migration to Cloud by Q2 2026


Target Details
Start Value: 0
Final Target: 100
Unit of measure: Percentage (%)

There are 3 projects aligned with the parent goal and one completed thus far:

alexankaras_1-1771432157119.png



Let's go ahead and automate them. We'll open Target 1 first in a new tab and scroll to the bottom of the form. We'll find an "Automated actual value" checkbox that we'll select and then an "Actual value source". I'll add the one I've created for now and click "Save".

alexankaras_2-1771432287202.png



After saving, a variables section has appeared and we're prompted to select some parameters. These are specific to the "Actual value source" and depend on how you've set it up. In my case I'll select "Count" for the Metric and "Aligned with Target or Parent Goal" for the Alignment and click Save:

alexankaras_3-1771432382969.png



After clicking save, an "Update Actual value" UI action appears. Clicking that will calculate the actuals of the target automatically:

alexankaras_5-1771432505681.png



Notice how the "Actuals to date" has updated to 1 (since only 1 of the 5 projects is completed) and the "Progress" is at 20% (since we need to have 5 items completed but so far we have 1 only).

Let's pick-up Target 2 in another tab and automate that as well, with the difference that we'll have the Metric variable set to "Percentage":

alexankaras_6-1771432706182.png



Notice now, that after we click the "Update Actual value" UI action, the "Actuals to date" has updated to 33.333333% and the "Progress" follows along (since we are also tracking a 0 to 100 target percentage as well).

 

alexankaras_7-1771432749117.png



Do we have to keep pressing the buttons to update these values?

NO: We can manually trigger the calculation via the UI action for testing, but we have an Out-Of-The-Box Scheduled Job that will do this for every target that you've automated based on the check-in frequency you've set when defining the target:

alexankaras_8-1771432939641.png



Also note, that a target stores all the score changes you do via "Target Breakdown" records. In our last example for Target 2, we can see that our latest "Actuals to date" that we captured in our previous step, is actually captured exactly against the "Check-in date" that we triggered the automation:

alexankaras_9-1771433013700.png



This allows us to track changes to the score at any day/time and also use/create charts against this info.

Ultimately, these targets drive our target progression and in term, aggregate their progression to the parent goal:

alexankaras_10-1771433155963.png



Considering that the Goal Framework can support a deep, hierarchical and weighted relationship between goals, sub-goals and targets, you can create a rich Goal & Target/OKR structure that is data-driven (see more about the progress propagation/calculations between parent/child goals and targets in our product documentation page (Goal Framework - Progress value calculation).

Setting up the Target Source (Automation)

So how can we setup these target automations for our SPM users to utilize?

Let's go over that by implementing the example we showcased above - driving the target actual value based on aligned planning item completion.

Let's use the navigator and go to "Enterprise Goal Management" -> Target Sources:

alexankaras_11-1771433607234.png



There should be a "Benefit Plans" target source record already - that can be reviewed as an example, although it might not be a practical one for all organizations.

alexankaras_12-1771433829834.png



Creating the Target Source Record

Switch to the "Goal Framework for SPM" Application Scope, create an Update Set and then create a new Target Source. I'll name mine "[Example] Planning Item Progression" and I'll set the type as "Custom script":

alexankaras_13-1771433930964.png



Making our automation modular via variables

Let's focus on our first important design concept, that is the modularity of the target source (automation) itself. We need to make our target sources as configurable as possible so that they may be used under different scenarios by different users and needs.

To achieve this, we can define and utilize Variables. These variables are exposed to the target form as we saw in our previous step, allowing the user to take configuration decisions on-the-spot for their target automation.


I'll add two backslashes for now in our script section of the target source (because it's mandatory) so I can save the record and then I'll create the following two variables:

Variable 1
Label: Metric
Type: Choice

Choices: (may need to switch to Advanced view to have them visible)
- Count
- Percentage

alexankaras_0-1771434379904.png



The idea is that we want the user to be able to shape the output actual value either as a count of how many aligned planning items are completed OR as a percentage of how many aligned planning items are completed over how many aligned items exist in total.

Variable 2
Label: Alignment
Type: Choice

Choices: (may need to switch to Advanced view to have them visible)
- Aligned with Target
- Aligned with Target or Parent Goal

alexankaras_1-1771434833482.png



Why we created this variable? SPW allows you to align a planning item either with the goal itself OR directly with a target. Depending on the portfolio, a portfolio manager might align their planning items on either the goal level or the target level. To keep this automation usable in both cases, we introduce this variable to keep things modular.

Quick Takeaway: Defining variables under a target source, is the same experience as creating a variable under a catalog item - you can even define variables that are mandatory, read-only and/or dependent on other variable values.


Building our script (automation logic)

The "Custom script" section of the target source contains the logic that the automation runs to calculate our target progression. Here are the important things to know about this script:

1. This is a Server-Side script giving us full access to any method we'd ever need - GlideRecord, Script Includes, REST Messages - your creativity is the limit.

2. This script will evaluate/run for every target record individually.

3. We have the following special objects available in the script:

- target: This is a GlideRecord object that is the Target record that the script is running against to calculate the actual value.

Example: target.sys_id and target.name give you the sys id value and the name value respectively of the target record.

- <variable_name>: This stores the variable value that is set by the user that has set-up the target automation.

Example: In our example, the metric variable would have the "count" or  the "percentage" value based on the user's selection.

- result: The actual value we're calculating. We should always assign a value to this variable - that's what will reflect in the end in the target record.

Example: if you try to set result = 1 as your script and try to use this target automation on a random target, it'd always return 1 as the actual value.

Before we jump into our example script, here's how the table relationships look like between Goal/Targets and Planning Items:

Untitled Diagram.svg



So, there is an m2m table that connects them - that's what we'll be focusing on our script to pull-up the numbers we're looking after. 


We'll be keeping things simple to understand the core concepts. Here's the script I used for my example - I've added comments on most lines to explain what I'm doing:

var gr_g2t = new GlideAggregate("sn_gf_goal_m2m_relationship"); //We'll be running a query directly on the m2m relationship
gr_g2t.addQuery("is_work_item", true); //Because a goal could be connected with non-planning item tasks, we want to focus on this example on only planning items - adding this query will ensure that we'll be looking only at those relationships.
gr_g2t.setGroup(false); //we don't want to do group-by in our simple example (just get row counts)

//Here's where we change our goal/target related query based on what's the value given by our alignment variable:
if (alignment=="target"){
    gr_g2t.addQuery("target", target.sys_id);
}
else{
    gr_g2t.addQuery("target", target.sys_id).addOrCondition("goal", target.goal);
}

gr_g2t.query(); //We run this initial query.

var total = gr_g2t.getRowCount(); //We store how many records satisfy the above query - that is the total count of all connected planning items with our target or goal.

gr_g2t.addQuery("planning_item_id.planning_state", "done");	//we add a new query on top of the previous one to now focus only on how many m2m records we have connected to the goal/target, that is in "done" planning state (your definition of done may be different!)
gr_g2t.query(); //We run our new query on top of the previous one.

var done = gr_g2t.getRowCount(); //We store how many planning items are done

if (total==0){ // If total is 0 - we don't have any connected planning items, so we return 0 as the actual value
    result = 0;
}
else if (metric=="percentage"){ //If the "Metric" variable is set to "Percentage" we calculate and return the percentage as the done over the total # of planning items multiplied by 100
    result = done / total * 100;
}
else{
    result = done; //if the metric is not percentage (i.e. it is count) we just return the done (how many planning items that are connected are marked as done)
}



Aaand we're done: This target source will now be available in all of your targets for use. Go ahead and test it out - then, start thinking about all the target sources you could expose to your users!


Related Links/Resources:

- ServiceNow Documentation - Goals in Strategic Planning

Version history
Last update:
3 hours ago
Updated by:
Contributors