change-management

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Change Management for ServiceNow

ServiceNow 变更管理

Change Management ensures controlled modifications to IT infrastructure through standardized processes and approvals.
变更管理通过标准化流程与审批机制,确保对IT基础设施的修改处于可控状态。

Change Types

变更类型

TypeApprovalRiskExample
StandardPre-approvedLowPassword reset template
NormalCAB approvalMediumServer patching
EmergencyPost-implementationHighProduction outage fix
类型审批要求风险等级示例
标准变更预先审批密码重置模板
常规变更CAB审批服务器补丁安装
紧急变更事后审批生产故障修复

Change Request Structure

变更请求结构

Change Request: CHG0010001
├── Risk Assessment
│   ├── Impact: Medium
│   ├── Risk: Low
│   └── Conflict Status: Clear
├── Schedule
│   ├── Planned Start: 2024-03-15 22:00
│   └── Planned End: 2024-03-15 23:00
├── Approvals
│   ├── Manager Approval: Approved
│   └── CAB Approval: Pending
├── Change Tasks
│   ├── Task 1: Backup current config
│   ├── Task 2: Apply patches
│   └── Task 3: Verify functionality
└── Affected CIs
    ├── PROD-WEB-001
    └── PROD-DB-001
Change Request: CHG0010001
├── Risk Assessment
│   ├── Impact: Medium
│   ├── Risk: Low
│   └── Conflict Status: Clear
├── Schedule
│   ├── Planned Start: 2024-03-15 22:00
│   └── Planned End: 2024-03-15 23:00
├── Approvals
│   ├── Manager Approval: Approved
│   └── CAB Approval: Pending
├── Change Tasks
│   ├── Task 1: Backup current config
│   ├── Task 2: Apply patches
│   └── Task 3: Verify functionality
└── Affected CIs
    ├── PROD-WEB-001
    └── PROD-DB-001

Creating Changes

创建变更

Normal Change (ES5)

常规变更(ES5)

javascript
// Create normal change request
var change = new GlideRecord('change_request');
change.initialize();

// Basic info
change.setValue('short_description', 'Apply security patches to web servers');
change.setValue('description', 'Monthly security patch deployment for production web tier');
change.setValue('type', 'normal');  // normal, standard, emergency

// Classification
change.setValue('category', 'Software');
change.setValue('priority', 3);

// Risk assessment
change.setValue('risk', 'low');  // high, moderate, low
change.setValue('impact', 2);     // 1-High, 2-Medium, 3-Low

// Schedule
var startDate = new GlideDateTime();
startDate.addDaysLocalTime(7);
startDate.setValue('2024-03-15 22:00:00');
change.setValue('start_date', startDate);

var endDate = new GlideDateTime(startDate);
endDate.addSeconds(3600);  // 1 hour
change.setValue('end_date', endDate);

// Assignment
change.setValue('assignment_group', getGroupSysId('Change Management'));
change.setValue('assigned_to', getOnCallUser());

// Implementation plan
change.setValue('implementation_plan',
    '1. Take backup of current configuration\\n' +
    '2. Stop web services\\n' +
    '3. Apply security patches\\n' +
    '4. Restart services\\n' +
    '5. Verify functionality'
);

change.setValue('backout_plan',
    '1. Stop web services\\n' +
    '2. Restore from backup\\n' +
    '3. Restart services\\n' +
    '4. Verify rollback successful'
);

change.setValue('test_plan',
    '1. Check web server response\\n' +
    '2. Verify all pages load\\n' +
    '3. Run automated health checks'
);

var changeSysId = change.insert();
javascript
// Create normal change request
var change = new GlideRecord('change_request');
change.initialize();

// Basic info
change.setValue('short_description', 'Apply security patches to web servers');
change.setValue('description', 'Monthly security patch deployment for production web tier');
change.setValue('type', 'normal');  // normal, standard, emergency

// Classification
change.setValue('category', 'Software');
change.setValue('priority', 3);

// Risk assessment
change.setValue('risk', 'low');  // high, moderate, low
change.setValue('impact', 2);     // 1-High, 2-Medium, 3-Low

// Schedule
var startDate = new GlideDateTime();
startDate.addDaysLocalTime(7);
startDate.setValue('2024-03-15 22:00:00');
change.setValue('start_date', startDate);

var endDate = new GlideDateTime(startDate);
endDate.addSeconds(3600);  // 1 hour
change.setValue('end_date', endDate);

// Assignment
change.setValue('assignment_group', getGroupSysId('Change Management'));
change.setValue('assigned_to', getOnCallUser());

// Implementation plan
change.setValue('implementation_plan',
    '1. Take backup of current configuration\\n' +
    '2. Stop web services\\n' +
    '3. Apply security patches\\n' +
    '4. Restart services\\n' +
    '5. Verify functionality'
);

change.setValue('backout_plan',
    '1. Stop web services\\n' +
    '2. Restore from backup\\n' +
    '3. Restart services\\n' +
    '4. Verify rollback successful'
);

change.setValue('test_plan',
    '1. Check web server response\\n' +
    '2. Verify all pages load\\n' +
    '3. Run automated health checks'
);

var changeSysId = change.insert();

Emergency Change (ES5)

紧急变更(ES5)

javascript
// Create emergency change
var emergencyChange = new GlideRecord('change_request');
emergencyChange.initialize();

emergencyChange.setValue('short_description', 'Emergency: Fix production database connection leak');
emergencyChange.setValue('type', 'emergency');
emergencyChange.setValue('priority', 1);
emergencyChange.setValue('risk', 'high');
emergencyChange.setValue('impact', 1);

// Emergency justification
emergencyChange.setValue('justification',
    'Production database connections exhausted causing service outage. ' +
    'Immediate fix required to restore service.'
);

// Immediate start
emergencyChange.setValue('start_date', new GlideDateTime());

var endDate = new GlideDateTime();
endDate.addSeconds(7200);  // 2 hours
emergencyChange.setValue('end_date', endDate);

emergencyChange.insert();

// Emergency changes bypass normal CAB
gs.eventQueue('change.emergency.created', emergencyChange);
javascript
// Create emergency change
var emergencyChange = new GlideRecord('change_request');
emergencyChange.initialize();

emergencyChange.setValue('short_description', 'Emergency: Fix production database connection leak');
emergencyChange.setValue('type', 'emergency');
emergencyChange.setValue('priority', 1);
emergencyChange.setValue('risk', 'high');
emergencyChange.setValue('impact', 1);

// Emergency justification
emergencyChange.setValue('justification',
    'Production database connections exhausted causing service outage. ' +
    'Immediate fix required to restore service.'
);

// Immediate start
emergencyChange.setValue('start_date', new GlideDateTime());

var endDate = new GlideDateTime();
endDate.addSeconds(7200);  // 2 hours
emergencyChange.setValue('end_date', endDate);

emergencyChange.insert();

// Emergency changes bypass normal CAB
gs.eventQueue('change.emergency.created', emergencyChange);

Standard Change (ES5)

标准变更(ES5)

javascript
// Create from standard change template
function createStandardChange(templateName, variables) {
    // Find template
    var template = new GlideRecord('std_change_producer');
    template.addQuery('name', templateName);
    template.query();

    if (!template.next()) {
        gs.error('Standard change template not found: ' + templateName);
        return null;
    }

    // Create change from template
    var change = new GlideRecord('change_request');
    change.initialize();

    // Copy template values
    change.setValue('short_description', template.getValue('short_description'));
    change.setValue('description', template.getValue('description'));
    change.setValue('type', 'standard');
    change.setValue('std_change_producer', template.getUniqueValue());

    // Apply variables
    for (var key in variables) {
        if (variables.hasOwnProperty(key) && change.isValidField(key)) {
            change.setValue(key, variables[key]);
        }
    }

    return change.insert();
}

// Usage
createStandardChange('Password Reset', {
    requested_by: userSysId,
    cmdb_ci: applicationSysId
});
javascript
// Create from standard change template
function createStandardChange(templateName, variables) {
    // Find template
    var template = new GlideRecord('std_change_producer');
    template.addQuery('name', templateName);
    template.query();

    if (!template.next()) {
        gs.error('Standard change template not found: ' + templateName);
        return null;
    }

    // Create change from template
    var change = new GlideRecord('change_request');
    change.initialize();

    // Copy template values
    change.setValue('short_description', template.getValue('short_description'));
    change.setValue('description', template.getValue('description'));
    change.setValue('type', 'standard');
    change.setValue('std_change_producer', template.getUniqueValue());

    // Apply variables
    for (var key in variables) {
        if (variables.hasOwnProperty(key) && change.isValidField(key)) {
            change.setValue(key, variables[key]);
        }
    }

    return change.insert();
}

// Usage
createStandardChange('Password Reset', {
    requested_by: userSysId,
    cmdb_ci: applicationSysId
});

Change Tasks

变更任务

Creating Change Tasks (ES5)

创建变更任务(ES5)

javascript
// Add tasks to change
function addChangeTask(changeSysId, taskConfig) {
    var task = new GlideRecord('change_task');
    task.initialize();
    task.setValue('change_request', changeSysId);
    task.setValue('short_description', taskConfig.description);
    task.setValue('order', taskConfig.order);
    task.setValue('assignment_group', taskConfig.group);
    task.setValue('planned_start_date', taskConfig.start);
    task.setValue('planned_end_date', taskConfig.end);
    return task.insert();
}

// Create implementation tasks
var tasks = [
    { description: 'Pre-implementation backup', order: 100, group: 'Database Team' },
    { description: 'Apply patches', order: 200, group: 'Server Team' },
    { description: 'Verify functionality', order: 300, group: 'QA Team' },
    { description: 'Update documentation', order: 400, group: 'Change Management' }
];

for (var i = 0; i < tasks.length; i++) {
    addChangeTask(changeSysId, tasks[i]);
}
javascript
// Add tasks to change
function addChangeTask(changeSysId, taskConfig) {
    var task = new GlideRecord('change_task');
    task.initialize();
    task.setValue('change_request', changeSysId);
    task.setValue('short_description', taskConfig.description);
    task.setValue('order', taskConfig.order);
    task.setValue('assignment_group', taskConfig.group);
    task.setValue('planned_start_date', taskConfig.start);
    task.setValue('planned_end_date', taskConfig.end);
    return task.insert();
}

// Create implementation tasks
var tasks = [
    { description: 'Pre-implementation backup', order: 100, group: 'Database Team' },
    { description: 'Apply patches', order: 200, group: 'Server Team' },
    { description: 'Verify functionality', order: 300, group: 'QA Team' },
    { description: 'Update documentation', order: 400, group: 'Change Management' }
];

for (var i = 0; i < tasks.length; i++) {
    addChangeTask(changeSysId, tasks[i]);
}

Affected CIs

受影响的CI

Linking CIs to Change (ES5)

关联CI到变更(ES5)

javascript
// Add affected CIs
function addAffectedCI(changeSysId, ciSysId) {
    var task = new GlideRecord('task_ci');
    task.initialize();
    task.setValue('task', changeSysId);
    task.setValue('ci_item', ciSysId);
    return task.insert();
}

// Add all affected servers
var servers = ['server1_sys_id', 'server2_sys_id', 'db_sys_id'];
for (var i = 0; i < servers.length; i++) {
    addAffectedCI(changeSysId, servers[i]);
}
javascript
// Add affected CIs
function addAffectedCI(changeSysId, ciSysId) {
    var task = new GlideRecord('task_ci');
    task.initialize();
    task.setValue('task', changeSysId);
    task.setValue('ci_item', ciSysId);
    return task.insert();
}

// Add all affected servers
var servers = ['server1_sys_id', 'server2_sys_id', 'db_sys_id'];
for (var i = 0; i < servers.length; i++) {
    addAffectedCI(changeSysId, servers[i]);
}

Approvals

审批流程

Check Approval Status (ES5)

检查审批状态(ES5)

javascript
// Get approval status
function getApprovalStatus(changeSysId) {
    var approvals = [];

    var approval = new GlideRecord('sysapproval_approver');
    approval.addQuery('sysapproval', changeSysId);
    approval.query();

    while (approval.next()) {
        approvals.push({
            approver: approval.approver.getDisplayValue(),
            state: approval.state.getDisplayValue(),
            comments: approval.getValue('comments'),
            sys_updated_on: approval.getValue('sys_updated_on')
        });
    }

    return approvals;
}
javascript
// Get approval status
function getApprovalStatus(changeSysId) {
    var approvals = [];

    var approval = new GlideRecord('sysapproval_approver');
    approval.addQuery('sysapproval', changeSysId);
    approval.query();

    while (approval.next()) {
        approvals.push({
            approver: approval.approver.getDisplayValue(),
            state: approval.state.getDisplayValue(),
            comments: approval.getValue('comments'),
            sys_updated_on: approval.getValue('sys_updated_on')
        });
    }

    return approvals;
}

Request Approval (ES5)

请求审批(ES5)

javascript
// Add approval request
function requestApproval(changeSysId, approverSysId) {
    var approval = new GlideRecord('sysapproval_approver');
    approval.initialize();
    approval.setValue('sysapproval', changeSysId);
    approval.setValue('approver', approverSysId);
    approval.setValue('state', 'requested');
    return approval.insert();
}
javascript
// Add approval request
function requestApproval(changeSysId, approverSysId) {
    var approval = new GlideRecord('sysapproval_approver');
    approval.initialize();
    approval.setValue('sysapproval', changeSysId);
    approval.setValue('approver', approverSysId);
    approval.setValue('state', 'requested');
    return approval.insert();
}

Change Conflict Detection

变更冲突检测

Check for Conflicts (ES5)

检查冲突(ES5)

javascript
// Check for scheduling conflicts
function checkChangeConflicts(changeSysId) {
    var change = new GlideRecord('change_request');
    if (!change.get(changeSysId)) return [];

    var conflicts = [];
    var startDate = change.getValue('start_date');
    var endDate = change.getValue('end_date');

    // Find overlapping changes on same CIs
    var affected = new GlideAggregate('task_ci');
    affected.addQuery('task', changeSysId);
    affected.groupBy('ci_item');
    affected.query();

    while (affected.next()) {
        var ciSysId = affected.ci_item.toString();

        // Find other changes affecting this CI
        var otherChanges = new GlideRecord('change_request');
        otherChanges.addQuery('sys_id', '!=', changeSysId);
        otherChanges.addQuery('state', 'NOT IN', 'closed,cancelled');
        otherChanges.addQuery('start_date', '<=', endDate);
        otherChanges.addQuery('end_date', '>=', startDate);

        // Join to task_ci
        otherChanges.addJoinQuery('task_ci', 'sys_id', 'task')
            .addCondition('ci_item', ciSysId);

        otherChanges.query();

        while (otherChanges.next()) {
            conflicts.push({
                change: otherChanges.getValue('number'),
                ci: ciSysId,
                start: otherChanges.getValue('start_date'),
                end: otherChanges.getValue('end_date')
            });
        }
    }

    return conflicts;
}
javascript
// Check for scheduling conflicts
function checkChangeConflicts(changeSysId) {
    var change = new GlideRecord('change_request');
    if (!change.get(changeSysId)) return [];

    var conflicts = [];
    var startDate = change.getValue('start_date');
    var endDate = change.getValue('end_date');

    // Find overlapping changes on same CIs
    var affected = new GlideAggregate('task_ci');
    affected.addQuery('task', changeSysId);
    affected.groupBy('ci_item');
    affected.query();

    while (affected.next()) {
        var ciSysId = affected.ci_item.toString();

        // Find other changes affecting this CI
        var otherChanges = new GlideRecord('change_request');
        otherChanges.addQuery('sys_id', '!=', changeSysId);
        otherChanges.addQuery('state', 'NOT IN', 'closed,cancelled');
        otherChanges.addQuery('start_date', '<=', endDate);
        otherChanges.addQuery('end_date', '>=', startDate);

        // Join to task_ci
        otherChanges.addJoinQuery('task_ci', 'sys_id', 'task')
            .addCondition('ci_item', ciSysId);

        otherChanges.query();

        while (otherChanges.next()) {
            conflicts.push({
                change: otherChanges.getValue('number'),
                ci: ciSysId,
                start: otherChanges.getValue('start_date'),
                end: otherChanges.getValue('end_date')
            });
        }
    }

    return conflicts;
}

State Transitions

状态流转

Change States

变更状态

StateNext StatesConditions
NewAssessSubmitted
AssessAuthorize, CancelledAssessment complete
AuthorizeScheduled, CancelledApprovals complete
ScheduledImplement, CancelledWithin maintenance window
ImplementReview, CancelledTasks completed
ReviewClosedPIR complete
Closed-Final state
状态可跳转状态条件
新建评估中、已取消已提交
评估中待授权、已取消评估完成
待授权已排期、已取消审批完成
已排期实施中、已取消处于维护窗口内
实施中已评审、已取消任务完成
已评审已关闭事后评审完成
已关闭-最终状态

Transition Change (ES5)

变更状态流转(ES5)

javascript
// Move change to next state
function transitionChange(changeSysId, newState, notes) {
    var change = new GlideRecord('change_request');
    if (!change.get(changeSysId)) {
        gs.error('Change not found: ' + changeSysId);
        return false;
    }

    // Validate transition
    var currentState = change.getValue('state');
    var validTransitions = {
        '-5': ['-4', '4'],      // New -> Assess or Cancelled
        '-4': ['-3', '4'],      // Assess -> Authorize or Cancelled
        '-3': ['-2', '4'],      // Authorize -> Scheduled or Cancelled
        '-2': ['-1', '4'],      // Scheduled -> Implement or Cancelled
        '-1': ['0', '4'],       // Implement -> Review or Cancelled
        '0': ['3']              // Review -> Closed
    };

    if (!validTransitions[currentState] ||
        validTransitions[currentState].indexOf(newState) === -1) {
        gs.error('Invalid state transition: ' + currentState + ' -> ' + newState);
        return false;
    }

    change.setValue('state', newState);
    if (notes) {
        change.work_notes = notes;
    }
    change.update();

    return true;
}
javascript
// Move change to next state
function transitionChange(changeSysId, newState, notes) {
    var change = new GlideRecord('change_request');
    if (!change.get(changeSysId)) {
        gs.error('Change not found: ' + changeSysId);
        return false;
    }

    // Validate transition
    var currentState = change.getValue('state');
    var validTransitions = {
        '-5': ['-4', '4'],      // New -> Assess or Cancelled
        '-4': ['-3', '4'],      // Assess -> Authorize or Cancelled
        '-3': ['-2', '4'],      // Authorize -> Scheduled or Cancelled
        '-2': ['-1', '4'],      // Scheduled -> Implement or Cancelled
        '-1': ['0', '4'],       // Implement -> Review or Cancelled
        '0': ['3']              // Review -> Closed
    };

    if (!validTransitions[currentState] ||
        validTransitions[currentState].indexOf(newState) === -1) {
        gs.error('Invalid state transition: ' + currentState + ' -> ' + newState);
        return false;
    }

    change.setValue('state', newState);
    if (notes) {
        change.work_notes = notes;
    }
    change.update();

    return true;
}

MCP Tool Integration

MCP工具集成

Available Change Tools

可用变更工具

ToolPurpose
snow_create_change_request
Create change
snow_create_change_task
Add tasks
snow_get_change_request
Get details
snow_update_change_state
Transition state
snow_search_change_requests
Find changes
snow_schedule_cab_meeting
Schedule CAB
工具用途
snow_create_change_request
创建变更
snow_create_change_task
添加任务
snow_get_change_request
获取详情
snow_update_change_state
状态流转
snow_search_change_requests
查找变更
snow_schedule_cab_meeting
安排CAB会议

Example Workflow

示例工作流

javascript
// 1. Create change
var changeId = await snow_create_change_request({
    short_description: 'Database upgrade',
    type: 'normal',
    risk: 'moderate',
    start_date: '2024-03-20 22:00:00',
    end_date: '2024-03-21 02:00:00'
});

// 2. Add tasks
await snow_create_change_task({
    change: changeId,
    description: 'Backup database',
    order: 100
});

// 3. Check conflicts
var conflicts = await snow_check_change_conflicts({
    change: changeId
});

// 4. Submit for approval
await snow_update_change_state({
    change: changeId,
    state: 'assess'
});
javascript
// 1. Create change
var changeId = await snow_create_change_request({
    short_description: 'Database upgrade',
    type: 'normal',
    risk: 'moderate',
    start_date: '2024-03-20 22:00:00',
    end_date: '2024-03-21 02:00:00'
});

// 2. Add tasks
await snow_create_change_task({
    change: changeId,
    description: 'Backup database',
    order: 100
});

// 3. Check conflicts
var conflicts = await snow_check_change_conflicts({
    change: changeId
});

// 4. Submit for approval
await snow_update_change_state({
    change: changeId,
    state: 'assess'
});

Best Practices

最佳实践

  1. Complete Documentation - Implementation, backout, test plans
  2. Risk Assessment - Accurate risk and impact ratings
  3. CI Linking - All affected CIs attached
  4. Proper Scheduling - Within maintenance windows
  5. Task Breakdown - Clear implementation steps
  6. Approval Chain - All required approvals
  7. Conflict Check - Verify no overlapping changes
  8. PIR - Post-implementation review for lessons learned
  1. 完整文档 - 包含实施、回滚、测试计划
  2. 风险评估 - 准确的风险与影响等级
  3. CI关联 - 关联所有受影响的CI
  4. 合理排期 - 安排在维护窗口内
  5. 任务拆分 - 清晰的实施步骤
  6. 审批链 - 获取所有必要的审批
  7. 冲突检查 - 确认无重叠变更
  8. 事后评审 - 执行实施后评审,总结经验教训