Datasources with MID Server incorrect after clone

Dirk Hillmer
Tera Contributor

After clone from PROD to TEST the Mid Server configuration is incorrect. This is due to the differnt Sys_Id on the different environments. 

Instead of changing all MID Servers to the have the same Sys_ID on all environments is there a fix script that could be used?

 

1 ACCEPTED SOLUTION

Markus Kraus
Kilo Sage

Hello, so basically you can either follow ServiceNow Best Practice as described in the following KB Article: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0719301

 

Or you add a relatively complex Cleanup Script (System Clone > Cleanup Scripts):

/* global GlideRecord, gs, GlideUpdateSet */
/* global global */
/* eslint no-undef: "error" */
(function () {
	var dataSources = {}; // { 'application1': ['sys_id1', 'sys_id2'] }
	var dataSourceGr = new GlideRecord('sys_data_source');
	dataSourceGr.addNotNullQuery('mid_server'); // only update data sources that already had an mid server
	dataSourceGr.setLimit(100);
	dataSourceGr.query();
	while (dataSourceGr.next()) {
		var midServerGr = dataSourceGr.mid_server.getRefRecord();
		if (midServerGr.isValidRecord()) {
			// there is already a valid mid-server - we do not touch this record
			continue;
		}
		
		var appSysID = dataSourceGr.getValue('sys_scope');
		(dataSources[appSysID] || (dataSources[appSysID] = [])).push(dataSourceGr.getUniqueValue());
	}
	
	if (Object.keys(dataSources).length > 0) {
		// at least one data source needs to be updated
		
		var sccmMidServer = 'MY_MID_SERVER_SYS_ID';
		for (var appSysID in dataSources) {
			var updateSetGr = new GlideRecord('sys_update_set');
			updateSetGr.newRecord();
			updateSetGr.application = appSysID;
			updateSetGr.name = 'Data Source Fix';
			var usSysID = updateSetGr.insert();
			if (usSysID) {
				// use the newly created update set as "current update set"
				new GlideUpdateSet().set(usSysID);

				// all changes to the Data Source should be encapsulated within a special update set
				var dataSourceGr = new GlideRecord('sys_data_source');
				dataSourceGr.addQuery('sys_id', 'IN', dataSources[appSysID]);
				dataSourceGr.query();
				// now update the data sources
				// note: we do not use .updateMultiple because this sometimes runs async,
				// and we want to close the update set after update sources have been set
				while (dataSourceGr.next()) {
					dataSourceGr.mid_server = sccmMidServer;
					dataSourceGr.update();
				}

				updateSetGr = new GlideRecord('sys_update_set');
				if (updateSetGr.get(usSysID)) {
					updateSetGr.state = 'ignore';
					updateSetGr.update();
				} else {
					gs.error('Failed to find update set with SysID=' + usSysID);
				}
			} else {
				gs.error('Failed to create update set');
			}
			
			gs.info('Updated the following Data Sources: ' + dataSources[appSysID]);			
		}
	}
})();

View solution in original post

2 REPLIES 2

Markus Kraus
Kilo Sage

Hello, so basically you can either follow ServiceNow Best Practice as described in the following KB Article: https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0719301

 

Or you add a relatively complex Cleanup Script (System Clone > Cleanup Scripts):

/* global GlideRecord, gs, GlideUpdateSet */
/* global global */
/* eslint no-undef: "error" */
(function () {
	var dataSources = {}; // { 'application1': ['sys_id1', 'sys_id2'] }
	var dataSourceGr = new GlideRecord('sys_data_source');
	dataSourceGr.addNotNullQuery('mid_server'); // only update data sources that already had an mid server
	dataSourceGr.setLimit(100);
	dataSourceGr.query();
	while (dataSourceGr.next()) {
		var midServerGr = dataSourceGr.mid_server.getRefRecord();
		if (midServerGr.isValidRecord()) {
			// there is already a valid mid-server - we do not touch this record
			continue;
		}
		
		var appSysID = dataSourceGr.getValue('sys_scope');
		(dataSources[appSysID] || (dataSources[appSysID] = [])).push(dataSourceGr.getUniqueValue());
	}
	
	if (Object.keys(dataSources).length > 0) {
		// at least one data source needs to be updated
		
		var sccmMidServer = 'MY_MID_SERVER_SYS_ID';
		for (var appSysID in dataSources) {
			var updateSetGr = new GlideRecord('sys_update_set');
			updateSetGr.newRecord();
			updateSetGr.application = appSysID;
			updateSetGr.name = 'Data Source Fix';
			var usSysID = updateSetGr.insert();
			if (usSysID) {
				// use the newly created update set as "current update set"
				new GlideUpdateSet().set(usSysID);

				// all changes to the Data Source should be encapsulated within a special update set
				var dataSourceGr = new GlideRecord('sys_data_source');
				dataSourceGr.addQuery('sys_id', 'IN', dataSources[appSysID]);
				dataSourceGr.query();
				// now update the data sources
				// note: we do not use .updateMultiple because this sometimes runs async,
				// and we want to close the update set after update sources have been set
				while (dataSourceGr.next()) {
					dataSourceGr.mid_server = sccmMidServer;
					dataSourceGr.update();
				}

				updateSetGr = new GlideRecord('sys_update_set');
				if (updateSetGr.get(usSysID)) {
					updateSetGr.state = 'ignore';
					updateSetGr.update();
				} else {
					gs.error('Failed to find update set with SysID=' + usSysID);
				}
			} else {
				gs.error('Failed to create update set');
			}
			
			gs.info('Updated the following Data Sources: ' + dataSources[appSysID]);			
		}
	}
})();

Wow works like a charme!

Thanks