spu_-_servicenow_plugin_updater

GetInstallPlan.js
// This script will retrieve the most recent Mass Update First 50 plan from the sys_batch_install_plan table and log its name, sys_id, and a URL to access it.
// created by: JWJ0215
// created on: 2024-06-15   
// Replace 'Mass Update First 50' with the desired plan name prefix if needed.
// use this script in the Scripts - Background module to quickly access the latest plan.
// Note: This script assumes that there is at least one plan with the specified name prefix in the sys_batch_install_plan table.
// It will log the name, sys_id, and a URL to access the plan in the system.
// USE THIS FIRST TO CHECK IF THE PLAN EXISTS BEFORE RUNNING ANY OTHER SCRIPTS THAT DEPEND ON IT.
var gr = new GlideRecord('sys_batch_install_plan');
 
gr.addQuery('name', 'STARTSWITH', 'Mass Update First 50');
gr.orderByDesc('sys_created_on');
gr.setLimit(1);
gr.query();
 
if (gr.next()) {
 
    gs.info('Name: ' + gr.getDisplayValue('name'));
    gs.info('Sys ID: ' + gr.getUniqueValue());
 
    gs.info(
        gs.getProperty('glide.servlet.uri') +
        'sys_batch_install_plan.do?sys_id=' +
        gr.getUniqueValue()
    );
} else {
    gs.info('No Mass Update First 50 plan found');
}

ListBatchPlan.js
// This script will list the last 20 batch plans created in the system, along with their name, state, and sys_id.
// created by: JWJ0215
// created on: 2024-06-15
var gr = new GlideRecord('sys_batch_install_plan');
gr.orderByDesc('sys_created_on');
gr.setLimit(20);
gr.query();
 
while(gr.next()){
    gs.info(
        'Name=' + gr.getDisplayValue('name') +
        ' | State=' + gr.getDisplayValue('state') +
        ' | SysID=' + gr.getUniqueValue()
    );
}

javascript GetPluginsFirst50wDetails.js
// This script retrieves the first 50 applications from the sys_store_app table that have an available update and constructs a payload with their details.
// It includes additional metadata such as the application's name, scope, short description, current version, and latest version.
// Use this payload to create a Mass Update Plan for updating the first 50 applications to their latest versions.
// created by: JWJ0215
// created on: 2024-06-15
var appsArray = [];
var prevName = '';
var maxApps = 50;
var updateCount = 0;

var grSSA = new GlideRecord('sys_store_app');
grSSA.addEncodedQuery('install_dateISNOTEMPTY^hide_on_ui=false');
grSSA.orderBy('name');
grSSA.orderBy('version');
grSSA.query();

while (grSSA.next()) {
    if (appsArray.length >= maxApps)
        break;
        
    var curName = grSSA.getValue('name');

    if (curName == prevName)
        continue;

    prevName = curName;

    var currentVersion = grSSA.getValue('version');
    var latestVersion = grSSA.getValue('latest_version');
    var updateAvailable = currentVersion != latestVersion;

    if (updateAvailable) {
        appsArray.push({
            id: grSSA.getUniqueValue(),
            type: 'application',

            // Requested update information
            requested_version: latestVersion,
            load_demo_data: false,

            // Additional metadata
            name: grSSA.getValue('name'),
            scope: grSSA.getValue('scope'),
            short_description: grSSA.getValue('short_description'),
            current_version: currentVersion,
            latest_version: latestVersion,
            update_available: true
        });
    }
}

var payload = {
    name: 'Mass Update First 50 ' + new GlideDateTime(),
    packages: appsArray
};

gs.info('Total applications with updates: ' + appsArray.length);
gs.info(JSON.stringify(payload, null, 2));

OpenLatestPlan.js
// This script will open the latest batch plan created in the system that starts with "Mass Update" in a new tab.
// created by: JWJ0215
// created on: 2024-06-15
var gr = new GlideRecord('sys_batch_install_plan');
gr.addQuery('name','STARTSWITH','Mass Update');
gr.orderByDesc('sys_created_on');
gr.setLimit(1);
gr.query();
 
if(gr.next()){
    gs.info(gs.getProperty('glide.servlet.uri') +
    'sys_batch_install_plan.do?sys_id=' +
    gr.getUniqueValue());
}

SampleJSONPayload.js
{    
  "name": "Mass Update First 50 2026-07-08 12:11:17",
  "packages": [
    {
      "id": "b1109a94e32a4691b42666ae61b72124",
      "type": "application",
     "requested_version": "1.1.0",
      "load_demo_data": false,
      "name": "ACC Admin Workspace",
      "scope": "sn_acc_wrksp",
      "short_description": "ACC Admin Workspace",
      "current_version": "1.0.0",
      "latest_version": "1.1.0",
     "update_available": true
    }
  ]
}

markdown README.md
# SNOW CICD Mass Update Kit V2
# V2 Created on 7/6/26
# Created by JWJ0215

Contents:
- get_plugins_top_50_all_INFO.js
- generate_all_updates.js  -- Only use this script if there are less than 100 plugins to upgrade. (or to view the total number of upgrades)
- get_install_plan.js -- Use this to view the newly created 'First 50' applications
- sample_payload.json
- open_latest_plan.js
- list_batch_plan_status.js
- cancel_mass_update_plans.js

- TroubleShooting
    - 01_find_running_pending_trackers.js
    - 02_cancel_mass_update_trackers.js
    - 03_check_tracker_progress.js
    - 04_check_installers.js
    - 05_active_trackers.js
    - 06_running_only.js
    - 07_mass_update_status.js
    - 08_batch_install_plans.js
    - 09_progress_workers.js
    - 10_pending_count.js
    - 11_pending_parent_check.js
    - 12_parent_record.js
    - 13_parent_walk.js
    - 14_pending_children.js

Workflow:
1. Run generate_first_50.js in Scripts - Background.
2. Copy JSON output.
3. Submit JSON to REST API Explorer -> sn_cicd -> CICD Batch Install API.
4. Monitor batch plans using list_batch_plan_status.js.
5. Open latest plan using open_latest_plan.js.
6. Cancel Mass Update plans using cancel_mass_update_plans.js if needed.


TroubleShooting Workflow:
01. This script will find all running and pending execution trackers in the system.
02. This script will cancel all Mass Update Tracker records that are currently in progress or queued.
03. This script will check the progress of a specific execution tracker in the system.
04. This script will check the progress of specific installer records in the system.
05. This script will list all active execution trackers in the system that are not in a final state (successful, cancelled, or failed).
06. This script will list all execution trackers in the system that are currently in the 'Running' state.
07. This script will list all execution trackers in the system that have names starting with "Mass Update".
08. This script will list all batch install plans in the system that are not in the states of cancelled, completed, or failed.
09. This script will list all progress workers in the system that are currently in the 'starting' or 'running' states.
010. This script will count the number of execution trackers in the system that are currently in the 'Pending' state.
011. This script will retrieve a specific execution tracker by its unique ID and log its name, parent, and state.
012. This script will retrieve a specific execution tracker by its unique ID and log its name, state, state value, parent, and sys_id.
013. This script will walk up the parent chain of execution trackers starting from a specific sys_id and log the name, state, and unique ID of each tracker in the chain.
014. This script will count the number of pending child execution trackers for a specific parent execution tracker.

markdown STEPS.md
# JWJ0215 7.7.26 Follow these steps to update the ServiceNow Plugins/Apps.
# To know what each script is used for, view the README.md
# If you notice any errors in any of my code, please let me know so I can address the issues.  I have spent a lot of time to automate the upgrade process so there could   # be errors.

## The plugins/apps are updated with the CI/CD API. I have found it is best to use the REST API Explorer

- Step 1.
    · Open the REST API Explorer; https://<instanceName>.service-now.com/now/nav/ui/classic/params/target/%24restapi.do
    · Namespace should be 'sn_cicd'.  API Name should be 'CICD Batch Install API'. API Version should be 'latest'

- Step 2.
    · Open the scripts - backgroud window in a new tab of the instance;  https://<instanceName>.service-now.com/now/nav/ui/classic/params/target/sys.scripts.modern.do

- Step 3.
    · Copy the code of the 'MAIN_get_plugins_first_50_w_DETAILS.js' and paste it in the background script. Run the script.
        - an example output
        *** Script: Total Applications with updates 6
        *** Script: {        /// copy from the left of this opening bracket to the end of the script
            "name": "Mass Update First 50 2026-07-08 12:11:17",
            "packages": [
                {
                    "id": "b1109a94e32a4691b42666ae61b72124",
                    "type": "application",
                    "requested_version": "1.1.0",
                    "load_demo_data": false,
                    "name": "ACC Admin Workspace",
                    "scope": "sn_acc_wrksp",
                    "short_description": "ACC Admin Workspace",
                    "current_version": "1.0.0",
                    "latest_version": "1.1.0",
                    "update_available": true
                }
            ]
        }    ///  end of script. If you fail to copy any of these 3 closing brackets, the API will fail. ///

        - This will show the first 50 script results with the information above.  after the scripts, you will see one last script '*** Script: {' copy from the left of the opening bracket to the end of the log.  

    · Once it runs, capture the output from the logs and input it into the 'raw data' of the api explorer, then press 'send' then 'ok'.
    There is no need for conversion of any kind.  The last line of the script actually converts the output to JSON.

- Step 4.
    · Scroll to the bottom of the REST API Explorer and you will see the 'Response Body'.  Copy the full response body and paste it in a new page for the instance plugin  update in OneNote. NO LONGER NEEDED. SEE BELOW.
    · Due to the newest script I have written, there is no need to copy and keep the results as there is now a backout plan for each batch install plan created.  In the 'sys_batch_install_plan' list, you will now see a 'Rollback Context' column with example BAK0140672.  This will allow you to backout the last batch install. You will have to be patient as the backout takes as long as the install.
 
- Step 5.
    · Now proceed to the table, 'sys_batch_install_plan', and open the latest install plan in a new window.
    · When the backout plan first opens, it will have a state of 'ready' and will not have a backout plan.
    · BE PATIENT!  It could take a few minutes for the state to update to 'in_progress'.
    · You will want to keep this form open and refresh every 5 minutes or so until you see the state change to 'installed', or 'partial_install'.
    · 'Partial_Install' is fine. It just shows when one of the updates were skipped due to no update needed, or it failed.
    · Here is a link to a batch install plan that shows 'partial_install' due to only one of the plugins having 'failed' state.
    · There can also be notes in the plan while the process is running giving you reasons for the skipped update.

- Step 6.
    · Once the 50 plugins have been updated, you can start the process over from step 3. Make sure to click the 'clear response' that is under the Request body, then paste the new results and click 'send'

- Step 7.
    · Do this until there shows 0 on the number of updates needed.  
  • spu_-_servicenow_plugin_updater.txt
  • Last modified: 07/10/2026 09:12
  • by johnsonjohn