Managing username changes in Service Manager
Let's say someone in your organisation changes their name for some reason. Let's also say that the same person is in your Service Manager CMDB. If that persons Active Directory username changes, then might not quite work as you'd expect – this is correct at the time of writing in System Center 2012 – Service Manager SP1 with Update Rollup 2.
In Contoso, we set AD usernames as FIRSTNAME.LASTNAME, so when somebody changes their name, we'll also alter their AD username to match.
Let's look at an example, Libby Owens. We can see her here in the Service Manager CMDB, as an AD User:
Opening up the user form, we can see her details, which were pulled from the Active Directory Connector, including the username, which is read-only.
Most importantly, we can see the relationships the user object has – relationships to work items like Incidents or Service Requests. We've also got relationships to Configuration items the user owns.
Now, our user goes ahead & changes her last name – as a result, we'll change her username in Active Directory:
Now, after the Active Directory Connector runs in Service Manager, we'll have two objects in the CMDB for Libby – one with her old name and another with her new.
So – why do we have two objects in Service Manager? They're still the same single object, with the same SID in Active Directory. This is because the user object in Service Manager has a key attribute of Domain + Username. Therefore, if the AD Username changes, we're going to have a different key and as a result, be a different Service Manager object. This is because user objects may be created from other sources, aside from AD.
So, going back to Service Manager, we can see the new user does not have any of the relationships – they're still on the 'old' object, before the name change:
This can also cause some confusing if you're searching for the user to add them on a new Incident:
We want to make sure that we get rid of the 'old' user object for Libby, so we use her new name from this point. However, if we simply delete the old User object from Service Manager, we'll lose all the relationship information – for example, if there are open Incidents, where the old user object is the affected user, that will be lost.
Therefore, what we want to do is move the relationships from the older user object to the new one, then delete the old object. There are a number of ways of doing this – manually through the console, Orchestrator, SDK, PowerShell, etc. In this blog, we're going to look at a PowerShell example. You may choose to trigger this manually, when somebody changes their username, or automate it through Orchestrator.
In this example, this PowerShell script will delete relationships from one user, and recreate them on the new one. The following relationship types are 'copied':
- Affected User
- Incident Closed by
- Work Item created by
- Work Item assigned to
- Work Item resolved
- Configuration Item Owned by
If you want to add, or remove other relationship types, you can easily edit the example script. This was intended to cover the most common relationships, which you see on the 'Related Items' tab.
After running the script successfully, you'll see the new user with the same related items as the old one:
The PowerShell script example is pasted below or downloadable from this blog. You can simply run it, supplying in the AD Usernames of the users to alter:
- oldADUser is the old username you want to copy the relationships from
- newADUser is the username where the relationships will be copied to
.\Move-Relationships.ps1 –oldADUser "Libby.Owens" –newADUser "Libby.Atkins"
After copying across these successfully, you can go ahead & delete the old user.
Note: You may have to change the directory, after the Import-Module command, depending on where Service Manager is installed.
if (!(Get-module System.Center.Service.Manager))
#TODO: You may need to alter the location of the PowerShell Module:
import-module 'C:\Program Files\Microsoft System Center 2012\Service Manager\PowerShell\System.Center.Service.Manager.psd1';
#Get the old and new user objects from the CMDB
$oldName = Get-SCClassInstance -Class (Get-SCClass -Name "System.Domain.User") -Filter "UserName -eq $oldADUser";
$newName = Get-SCClassInstance -Class (Get-SCClass -Name "System.Domain.User") -Filter "UserName -eq $newADUser";
#Get relationships targeted at the old user object
$relatedItems = Get-SCRelationshipInstance -TargetInstance $oldName;
foreach ($item in $relatedItems)
#Figure out the type of each of those relationships & check against the list
$relType = Get-SCRelationship -Id ($item.RelationshipId);
if ($relType.Name -eq "System.WorkItem.TroubleTicketClosedByUser" -or
$relType.Name -eq "System.WorkItemAffectedUser" -or
$relType.Name -eq "System.WorkItemCreatedByUser" -or
$relType.Name -eq "System.WorkItemAssignedToUser" -or
$relType.Name -eq "System.WorkItem.TroubleTicketResolvedByUser" -or
$relType.Name -eq "System.ConfigItemOwnedByUser")
#delete the old relationships & recreate them with the new user object
Remove-SCSMRelationshipInstance -Instance $item;
New-SCRelationshipInstance -RelationshipClass (Get-SCRelationship -Name $relType.Name) -Source $item.SourceObject -Target $newName;
DISCLAIMER: THIS PROGRAM SOURCE CODE IS PROVIDED "AS IS" WITHOUT WARRANTY REPRESENTATION OR CONDITION OF ANY KIND EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO CONDITIONS OR OTHER TERMS OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. THE USER ASSUMES THE ENTIRE RISK AS TO THE ACCURACY AND THE USE OF THIS PROGRAM CODE OR RESULTING EXECUTABLE CODE