Updated: Jun 15
With Fernando Garcia
In this article, we will cover background scripts. A background script is a free-form way of executing server-side code on the fly, without the need of building a trigger or script like a business row. We would use a background script when you want to clean a small or decent amount of data that doesn't require too many complex updates. If you need to update records that could have a lot of scripts executing against it — as long as it's a small or decent size, not in excess — you could get around it. You will learn a couple of functions to get around that.
Getting to the Background Script
To do this, you want to search in the filter navigator background and under ‘System Definitions’ you'll see Scripts Backgrounds. Click on that and it'll redirect you to this white screen page with a text area box, where you can resize in the lower right corner. A couple of things that you'll notice at the bottom — you have the button for running the actual script, and you also have ‘in scope’. If you're familiar with the application picker at the top, this basically functions in an identical way. You're going to execute that script on the application that you pick from here. You also will now have ‘Record for rollback’ — when this is selected, usually you would leave it by default. This creates a record of the history, allowing you to roll back your transaction if you need to.
Then you have two lesser common options. ‘Execute in sandbox’ is more for restrictive rights. If you're trying to execute a script and accidentally invoke a method that you didn't want to — for example, in a GlideRecord you call insert — this would stop you from doing those things. This might not be what your background is intended for, but if you're trying to be safe and just reading data, and you just want to avoid any issue, maybe that might be an option for you. Scriptlets was actually introduced in the Paris version of ServiceNow, but it's something that you could pretty much disregard when building a background script as of now.
When you execute a background script, your transaction can run for hours, and this one will kill it after four hours. Use this if you know that your script should finish in a reasonable amount of time, and not more than four hours later, especially if you're worried that your script might accidentally be executing stuff that it's shooting or updating records that you definitely don't want in excess to be updated.
Starter Functions: Setworkflow and AutoSysFields
There are two functions for starters that are important to read up on: setworkflow and autoSysFields. Setworkflow(false) works by deactivating all types of server scripts that could execute against a GlideRecord, such as a business rule or a workflow, and this is extremely useful if you're just trying to target updating a specific field and you don't want the repercussions of any scripts triggering that record giving you unintended updates that you didn't want.
AutoSysFields is more related to system update fields, such as created by, created on, updated by, and updated on. You would use this when you don't want to mess with the process; you just want to fix the data. It might depend on the timestamps of those processes that are the system fields. If you set this to false, those fields will not get updated, even if you update the record. If your background script requires fixing data and you don't want any other time stamps getting modified, then you would want to use AutoSysFields.
Another thing to note for the setworkflow function is that this also disables the audit history, so exercise with caution. If your plan is to update a record you want it to be captured in the history then, do not use setworkflow(false) because that will not allow you to see it in the history.
Creating a Background Script
In this example, we have already built a shell for querying an incident and updating the state simply, and in another tab, we have an incident. So let’s select the incident where you can view system update fields such as date created and updated. Upon clicking on the incident, you can see the state is ‘Closed’.
Let's say you accidentally created a defect in the environment, and it closed some incidents. Based on analysis, we can see such and such incidents were impacted, whether an individual set or something that marks them as part of my functionality. Let's say hypothetically, this is one that was identified, and this one should be ‘On Hold’. What you do is copy the sys_ID, go back to the query, and paste that sys_ID for that incident. Let’s say we don't want any of the rules to be triggered in case we change it to ‘On Hold’. You will set the workflow to false, and you’ll see that the history is not going to get updated either.
Now we also don't want to affect timestamps in whatever form; we want to leave them the way they are now, so you’ll keep this on. Before you do an incident update, you want to make sure you log what you're doing before you do the update. This is the most important tip on building a background script. It's important that you rigorously test to see what your background script actually does, prior to actually making the updates.
Background scripts can be dangerous; you can accidentally update a massive amount of data that you weren't supposed to update. Now there is a rollback option, but you shouldn’t depend on the rollback that the platform offers — use this as a last resort or for very small things that you know for sure can be rolled back. If you have a complex script, and you mess that up, rather than going for the roll back, try to build another fake script to mitigate it. On the first hand, try to always log your stuff and make sure that what you're updating is exactly how you want the results.
If you’re sharing the platform with other developers, you want to be able to see your logs, so you may want to put your initials. You’re going to call this ‘before’ and you’re going to output the incident state display value prior to being executed. Copy the logs, paste that, and then change that ‘before’ to say ‘after’. So we commented out the update. Run the script, and you can see before it was ‘Closed’, and after it's ‘On Hold’. If you really want to make sure what you’re executing it against, you can also add the number here as needed. For this example, we confirmed that from ‘Closed’, it’ll go to ‘On Hold,’ so we'll go ahead and update that.
Now you can see that the update happens here. If you click into the little link under ‘row count,’ it's going to send you to the actual rollback sequence for that record. You can see some details there and then the script execution history for what you executed. The scripted execution history is very useful to see who executed what background scripts and what occurred.
Rolling Back the Transaction/Script Execution History
There's also ‘Related Links’’ at the bottom, where you can actually roll back your transaction. If you go to the incident, you can see it changed to ‘On Hold’. If you reload the form real quick, you'll also notice that because you set the workflow to ‘false’, when you go to your history there is no entry in the audit. Now going to your list view for that incident, you can see the timestamps are also unaffected because you called the autoSys field function and set that to false. This preserved the time stamp and did not trigger any business rule or any other triggered scripts on the GlideRecord, which also includes updating the audit.
Let's say you messed up and did not want to update that incident. You usually would want to build a background script to try to fix it if at all possible, but if it seems very difficult and maybe you really want to go for a last resort or it's something simple in nature, you could go to your script execution history for that script. The way to do that in the platform is by searching for ‘script execution history.’ Navigate to the module under the rollback and recovery application, and find the script that you executed.
We will click the rollback script execution, type ‘yes’, and hit ‘OK’. This is going to go ahead and execute the rollback. Now if we go back to our incident, we notice how it went back to the way it was, ‘Closed’. Keep in mind if you had not set the workflow to ‘false’ and the audit history was captured, this is not going to get captured in the history.
If you go to script execution history, keep in mind that this by default out of the box, these entries last seven days before they get deleted from the system. If by any chance you need to keep them more, you could always go to the sys auto flush table, find the script execution history table and change the age in seconds if you want to preserve them for more than seven days.
Did you find this Background Scripts in ServiceNow article helpful? Are you ready to start your journey with ServiceNow? If you want to find out more information about GlideFast Consulting and our ServiceNow implementation services, you can reach out to us here.
About GlideFast Consulting
GlideFast is a ServiceNow Elite Partner and professional services firm that provides tailored solutions and professional services for ServiceNow implementations, integrations, managed support services, application development, and training. Reach out to our team here.