Change the class of a CI

General Add comments
by:

Sometimes you may find that a CI is in a wrong class, and you need to move it to another class.
Obviously you can delete the CI and recreate it using the correct class, but if you want to preserve relationships (to Tasks or other CI’s), this may not be an option.

 

There are two methods that can be used to accomplish this, both with the same results:

  1. Add the Class field to the CI form, and update the class to the desired class
  2. Create a script that updates the sys_class_name field of the CI specified to the new class name

Other methods – mentioned below – do NOT work:

  1. Export the records as an XML file, change the class name and import it again (this will corrupt the record)
  2. Using a transform map, import the CI with a coalesce on the Name into the new class (this will create a duplicate)

The reason that 1 and 2 work is because ServiceNow takes care of following:

  • The sys_id will be preserved, as will all its relationships
  • Any records from extended tables that are no longer required will be deleted
  • New records will be inserted in extended tables as is required

The result of this is that the new record will preserve all data that is in attributes that are shared by the old and the new class.
Please be aware that the same attribute name is not enough; these attributes must also be in the same tables.
This is illustrated by the example below:

Moving a server from Windows to Linux

CMDB setup is:

Now we have the following Windows Server

[cc lang=”javascript”]
name = ‘SRV001’
sys_class_name = ‘cmdb_ci_win_server’
os = ‘Windows’
u_newfield = ‘New Field Value’
[/cc]

Next we use the following script

[cc lang=”javascript”]
var gr = new GlideRecord(‘cmdb_ci’); //you can use the actual class or any base class here
gr.addQuery(‘name’,’SRV001′);
gr.query();
if(gr.next()){
gr.sys_class_name=’cmdb_ci_linux_server’;
gr.update();
}
[/cc]

The result is a Linux server

name = ‘SRV001’
sys_class_name = ‘cmdb_ci_linux_server’
os = ‘Windows’ // because we didn’t change it and it is a shared attribute in th cmdb_ci_server table
u_newfield = ” // because this field is not shared by the cmdb_ci_win_server class and the cmdb_ci_linux_server class.

If you have any questions you can contact me by mail on martijn.odijk@2e2.nl.

5 Responses to “Change the class of a CI”

  1. Martijn Says:

    Another article that is worthwile reviewing is:
    http://www.servicenowguru.com/scripting/promote-field-extended-table-servicenow
    Please be aware that this is quite dirty, and you may run into issues when executing this on a cluster.

  2. Jeff Kellar Says:

    There is anxiety at my client about allowing CI class changes. They have the class added to the forms, but they only allow an admin to change it.

    The reasons for the anxiety have been lost, but the fear lingers.

    Is there any downside, apart from losing previously collected (likely irrelevant) data in the extension table?

    Thanks!

  3. Martijn Says:

    Solid testing is recommended before you allow users to update the class of a CI. We found that in some cases the task_ci records that are related to CI X are deleted when you change the CI Class of CI X. It only seems to happen when during the Class Change a record on an extended table gets deleted. (maybe due to some invisible cascade rule. we didn’t find any code that could be responsible for it yet).

  4. Jeff Kellar Says:

    Thanks! Does the second method you describe (a script that updates the sys_class_name) have the same potential effect?

  5. Martijn Says:

    Yes, it does, but there you can use .setWorkflow(false), which may prevent it.
    Since we used it for a mass data conversion, we created a business rule (current.setAbortAction(true)) on task_ci to prevent this from happening. This method will obviously not be useful for your setup, where users can manually update singel CIs.

Leave a Reply