Script to change ownership across all products
Asked by Baxter Johnson:

Hey everyone,

We migrated to a new domain controller resulting in everyone getting new user names. This means our new user names don't have ownership of our old items (pages, dashboards, filters, etc). As an admin, I can bulk change some fields in Jira, but others are done one at a time. Additionally, I can access anything that was shared and adjust them manually. I'm hoping to find a way to change those items (pages, dashboards, filters, etc) which are not shared. The title says script but it doesn't have to be that. I've already moved most of what we need but I'd like to catch everything else just in case something will be needed in a few months at the next milestone.

I've seen a few other posts similar to this but wanted to bring it up again in case someone has something new to add.

Thank you


Answers:
author: Craig Castle-Mead
body: [@Baxter Johnson](/t5/user/viewprofilepage/user-id/5013770)

It sounds like you have already cutover to the new DC / username format - and if so, the below process will not work, however doing a write up in case it's not too late, or for future reference for others. We've done this type of "shuffle" many times - and it's worked well.

YMMV / use at your own risk / please attempt in a non-production environment first. \</disclaimers\>

For the below examples, let's assume that:

* You're dealing with one/some/all possible current Atlassian on-prem apps (Crowd, Jira SW/JSM, Confluence, Bitbucket, Bamboo)
* We're moving from a DC using samAccountName as the Atlassian username (firstLast - source username) to a different DC using primarySMTP as the Atlassian username (first.last@example.org - target username). As it's a new DC, the objectGUID is different between the two environments (having a consistent objectGUID makes the process MUCH simpler)
* NONE of the applications have a user object using any of the target usernames - f you do, especially Jira, you will end up with #1 "conflict" users eg: first.last@company.com will be the already created user, and first.last@company.com#1 will be the new user object that is created when firstLast is renamed - the #1 user will be the one user object that owns all of the objects previously owned by firstLast, however when the user authenticates against the new DC, it will be as first.last@company.com

Steps:

1. Create a Crowd "Internal" directory
2. Create your Crowd directory for the new DC "Connector" type - set the User name attribute and User email attribute to the field with the users email address (by default for Windows DCs, I believe this is just 'mail')
3. Populate this directory with every single user from your current DC environment with the username as the source username format (eg: firstLast). You'll need to set a password as it's a required field, but just use a random string generator, the users will never authenticate with this object. I'd recommend creating a user object for any active, inactive or deleted users so you can change the username format to email for old users incase they return (especially important if you have contractors/etc who come and go), but at minimum, a Crowd Internal user object for each active user in your environment. We often put the users first/last/displayname in lower case in this internal directory as it makes it more apparent in the Applications which version of a user they're using
4. On each Atlassian Crowd Application (eg: <https://crowd.company.com/crowd/console/secure/application/browse.action> ) on the Directory mapping page:
   1. Add the new Crowd Internal directory - if you're using "Access-based synchronization" to just sync users in a specific group, either change to "All users and groups" until this process is complete, or when bulk-creating your Internal users, add each user to a group that has access to authenticate to each app
   2. Remove the DC that uses the source username format (eg: samAccountName) from the application directory mapping - this should leave JUST the Crowd Internal directory mapped to each application
5. For each Atlassian app:
   1. Go to each Atlassian application connected to your Crowd environment, then User Directories and Synchronise. In Jira (and possible the others), you may see the User Directory UI "deleting" all of your users, and then "creating" all of your users. Try not to panic! The user object in these apps is tied to a user object in Crowd on a per directory basis. It's "deleting" the user firstName from your old DC, then "creating" firstName from your Crowd Internal directory - as the username is the same (firstLast) - they're effectively the same user - all history/tickets/etc will be retained
   2. Sync the User Directories a few times until the UI shows no further changes - Jira often takes two syncs, one to "delete", one to "create"
6. You then need to rename all of the Crowd Internal user objects from the source username format (firstLast) to target username format (first.last@company.com) - depending on the number of users you're talking about - and your patience, this could be done via the UI manually, or, in bulk using the REST API. If you're using Crowd 4.4.0 or higher (from memory it's this version), you cannot change the username using the REST API and Application Authentication by default, you need to add the startup parameter "-Dcrowd.email.change.by.external.apps=true" and restart Crowd
7. As your Crowd Internal users have their usernames change in Crowd, the syncs to Jira/Conf/etc will start renaming the user objects in those applications (firstLast will become first.last@company.com) - again AS LONG AS there isn't already a user object first.last@company.com
8. Once you've renamed all of the Crowd Internal users, repeat the 5.2 step above - keep syncing each apps User Directory until you're not seeing any further changes. In the User browser for each application, if you used the lower case first/last/display name hint from Step 3 - you should see the lowercase version of your users throughout the applications, and their usernames should be the target username (first.last@company.com)
9. Once you're happy with the output of Step #8 - similar to Step #4 - Go to the Crowd Applications \> Directory mappings and add the **new** DC directory to each application, then remove the Crowd Internal directory
10. Sync to each of the Atlassian applications (same as Step 5) - the applications will now see the first.last@company.com users as coming from your new DC instead of the Crowd Internal directory

Hope that helps.

CCM

comments: author: Baxter Johnson
body: We have already cutover to the new DC, which has been in place for a few months with everyone using their new accounts. I have manually changed ownership for most objects, but there are some corner cases that I cannot reach.

Are y'all aware of any way to modify unshared objects?

Thank you


author: Craig Castle-Mead
body: Hey Baxter,

**Huge disclaimer on the below** - these are updates directly in the DB and are NOT supported or recommended by Atlassian, however we have used these a number of times with success to resolve issues where data "had" to be reassigned from old to new users. These queries only handle native Jira objects (eg: plugins will not be changed).

After you've run these queries, the caches are going to be out of sync, so restarting your Jira app nodes (one at a time if you're on DC) will get things up to date.

You need to run these for each user - \<new username\> will be your DC/email address, username, \<duplicate username\> will be the old DC/non-email username

`UPDATE userhistoryitem SET USERNAME =` `'<new username>'` `WHERE USERNAME =` `'<duplicate username>'``;`  
`UPDATE fileattachment SET AUTHOR =` `'<new username>'` `WHERE AUTHOR =` `'<duplicate username>'``;`  
`UPDATE jiraissue SET REPORTER =` `'<new username>'` `WHERE REPORTER =` `'<duplicate username>'``;`  
`UPDATE jiraissue SET ASSIGNEE =` `'<new username>'` `WHERE ASSIGNEE =` `'<duplicate username>'``;`  
`UPDATE jiraissue SET CREATOR =` `'<new username>'` `WHERE CREATOR =` `'<duplicate username>'``;`  
`UPDATE customfieldvalue SET STRINGVALUE =` `'<new username>'` `WHERE STRINGVALUE =` `'<duplicate username>'``;`  
`UPDATE jiraaction SET UPDATEAUTHOR =` `'<new username>'` `WHERE UPDATEAUTHOR =` `'<duplicate username>'``;`  
`UPDATE jiraaction SET AUTHOR =` `'<new username>'` `WHERE AUTHOR =` `'<duplicate username>'``;`  
`UPDATE changegroup SET AUTHOR =` `'<new username>'` `WHERE AUTHOR =` `'<duplicate username>'``;`  
`UPDATE worklog SET AUTHOR =` `'<new username>'``, UPDATEAUTHOR =` `'<new username>'` `WHERE AUTHOR =` `'<duplicate username>'``;`  
`Based on the table names, it should be relatively obvious what data you're changing. I always like to run a SELECT * with the same WHERE clause to sanity check the data before running the updates.`  
`Again, recommend you try this on a non-prod environment first.`  

`CCM`


Tags: confluence

jira