- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tuesday - last edited yesterday
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tuesday
Hey @Asmita7,
Skip the bulk-edit route entirely and go straight at the field with a background script. The list collector you're seeing is really cmdb_model_category on cmdb_hardware_product_model, and it's a glide_list under the hood, a comma-separated string of category sys_ids. That's exactly why bulk update overwrites the whole list instead of swapping one value out of it, and why your filter has to be "Model Category Contains Laptop" instead of an equals, list collectors don't do exact-match filtering.
Get the sys_id for your custom Laptop category and the sys_id for Computer, then run this in Scripts - Background (test with gr.setLimit(5) first, no limit once you trust it):
var laptopId = 'LAPTOP_SYS_ID';
var computerId = 'COMPUTER_SYS_ID';
var gr = new GlideRecord('cmdb_hardware_product_model');
gr.addEncodedQuery('cmdb_model_categoryLIKE' + laptopId);
gr.query();
while (gr.next()) {
var arr = gr.cmdb_model_category.toString().split(',');
var idx = arr.indexOf(laptopId);
if (idx > -1) {
arr.splice(idx, 1);
}
if (arr.indexOf(computerId) == -1) {
arr.push(computerId);
}
gr.cmdb_model_category = arr.toString();
gr.setWorkflow(false);
gr.update();
}Notes on the logic:
- The addEncodedQuery LIKE match is literally what your CONTAINS filter is doing behind the scenes.
- The indexOf check on computerId stops duplicate Computer entries on models that already carry both categories, like the ones in your screenshot.
- setWorkflow(false) keeps the run from tripping business rules or notifications tied to category changes.
Thank you,
Vikram Karety
Octigo Solutions INC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tuesday
Hi @Asmita7 ,
Looking at your example, some Hardware Models have only Laptop, while others have Computer, Laptop or Computer, Windows Server, Laptop. Since Model Categories is a list collector field, a simple update may overwrite existing values rather than selectively removing one category.
For a large number of records, I'd recommend using a Background Script/Fix Script. The script can:
- Find all Hardware Models where Model Categories contains Laptop
Remove only the Laptop category
Retain all other existing categories (e.g., Computer, Windows Server)
Add Computer only when it is not already present - This approach is more scalable and safer than creating multiple Update Jobs. Make sure to test in a non-production instance first and take a backup/export of the affected records.
Also, before retiring the Laptop model category, check whether it is referenced by Discovery, Asset Management, CMDB Health, reports, or any custom logic.
A Fix Script should be the most efficient option for this type of bulk cleanup.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tuesday
Hey @Asmita7,
Skip the bulk-edit route entirely and go straight at the field with a background script. The list collector you're seeing is really cmdb_model_category on cmdb_hardware_product_model, and it's a glide_list under the hood, a comma-separated string of category sys_ids. That's exactly why bulk update overwrites the whole list instead of swapping one value out of it, and why your filter has to be "Model Category Contains Laptop" instead of an equals, list collectors don't do exact-match filtering.
Get the sys_id for your custom Laptop category and the sys_id for Computer, then run this in Scripts - Background (test with gr.setLimit(5) first, no limit once you trust it):
var laptopId = 'LAPTOP_SYS_ID';
var computerId = 'COMPUTER_SYS_ID';
var gr = new GlideRecord('cmdb_hardware_product_model');
gr.addEncodedQuery('cmdb_model_categoryLIKE' + laptopId);
gr.query();
while (gr.next()) {
var arr = gr.cmdb_model_category.toString().split(',');
var idx = arr.indexOf(laptopId);
if (idx > -1) {
arr.splice(idx, 1);
}
if (arr.indexOf(computerId) == -1) {
arr.push(computerId);
}
gr.cmdb_model_category = arr.toString();
gr.setWorkflow(false);
gr.update();
}Notes on the logic:
- The addEncodedQuery LIKE match is literally what your CONTAINS filter is doing behind the scenes.
- The indexOf check on computerId stops duplicate Computer entries on models that already carry both categories, like the ones in your screenshot.
- setWorkflow(false) keeps the run from tripping business rules or notifications tied to category changes.
Thank you,
Vikram Karety
Octigo Solutions INC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tuesday
Hi @Asmita7 ,
Looking at your example, some Hardware Models have only Laptop, while others have Computer, Laptop or Computer, Windows Server, Laptop. Since Model Categories is a list collector field, a simple update may overwrite existing values rather than selectively removing one category.
For a large number of records, I'd recommend using a Background Script/Fix Script. The script can:
- Find all Hardware Models where Model Categories contains Laptop
Remove only the Laptop category
Retain all other existing categories (e.g., Computer, Windows Server)
Add Computer only when it is not already present - This approach is more scalable and safer than creating multiple Update Jobs. Make sure to test in a non-production instance first and take a backup/export of the affected records.
Also, before retiring the Laptop model category, check whether it is referenced by Discovery, Asset Management, CMDB Health, reports, or any custom logic.
A Fix Script should be the most efficient option for this type of bulk cleanup.