User mapping while migrating Confluence spaces (export / import) - how?
Asked by Daniel:

Hi community,

I hope you can help me.

I need to migrate several Confluence Spaces from Confluence Server 6.10.1 to another Confluence Server instance (version unknown yet, but not older than 6.10.1).

The usernames (and certainly also the user IDs) will be different between source and target side.

What is the best way to migrate the spaces and map the users correctly? We thought about soing search-and-replace in the exported XML before importing, but there are users referenced in a mixed way sometimes with their email addresses (which are the usernames on source instance) and sime kind of ID or hash.

```
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key"><![CDATA[ff80818169286c7e016a11f1d2f5000a]]></id>
<property name="name"><![CDATA[john.doe@example.com]]></property>
<property name="lowerName"><![CDATA[john.doe@example.com]]></property>
</object>
```

Do I have to evaluate these objects like the above one, in order to find out the mapping between username and key, so I can replace all the keys accordingly in objects like the below one, where only keys are used?

```

<object class="User2ContentRelationEntity" package="com.atlassian.confluence.internal.relations.dao">
<id name="id">1345102</id>
<property name="targetContent" class="Page" package="com.atlassian.confluence.pages"><id name="id">984062</id>
</property>
<property name="sourceContent" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
<property name="targetType" enum-class="RelatableEntityTypeEnum" package="com.atlassian.confluence.internal.relations">PAGE</property>
<property name="relationName"><![CDATA[collaborator]]></property>
<property name="creationDate">2018-09-24 10:39:18.000</property>
<property name="lastModificationDate">2018-09-24 10:39:18.000</property>
<property name="creator" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
<property name="lastModifier" class="ConfluenceUserImpl" package="com.atlassian.confluence.user"><id name="key"><![CDATA[ff80818164dabce30164eebfbe150004]]></id>
</property>
</object>
```

If that's the case, is there any tool that can help with this task?

Thank you!

Daniel


Answers:
author: Erik Anderson
body: Fast-forward a year and a bit. :)

Scenario: {#toc-hId--526988585}
-------------------------------

* Server A and Server B both run Confluence, but have different user accounts. Users at Subsidiary A running Server A have accounts at Subsidiary B running Server B, but the credentials are different: Server A username "USERNAME@www.example.com" is implemented on Server B as "prefix_USERNAME".

Steps: {#toc-hId-1960524248}
----------------------------

* Export space ABC from Server A to XML.
* Import XML file into Server B.
* Subsidiary A user logs into Server B using Server B credentials. Edits a page that they had previously edited on Server A.
* Export space ABC from Server B to XML.
* Examine the XML content.

Poking around in the export file, you should be able to find XML structures like the following. These are, unfortunately, scattered throughout the file, so you might have to do some digging. Also, they probably won't be paired up nicely like this, so you'll have to use Search features.

```
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
  <id name="key">8af2e18d78f3a4630179448450f0002c</id>
  <property name="name">USERNAME@www.example.com</property>
  <property name="lowerName">USERNAME@www.example.com</property>
  <property name="email"/>
</object>
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
  <id name="key">8af281d954c032310149f548eb6c000e</id>
  <property name="name">prefix_USERNAME</property>
  <property name="lowerName">prefix_USERNAME</property>
  <property name="email">USERNAME@www.example.com</property>
</object>
```

Once you can find all of the **ConfluenceUserImpl** objects and correlate them based on **USERNAME** (or whatever key your company might have implemented), you can then go through and replace the GUID value for the old one (in the example above, the one for **USERNAME@www.example.com** ) with the GUID for the new one (the one for **prefix_USERNAME**) in the XML file, and then import that back into Server B.

Alternatively, it looks like it's possible for Confluence admins to fix this with moderate difficulty by tweaking the database, as described in [How to change the creator of a page \| Confluence \| Atlassian Documentation](https://confluence.atlassian.com/confkb/how-to-change-the-creator-of-a-page-720830744.html), running queries like the following:

```
update content set creator = (select user_key from user_mapping where lower_username = 'prefix_USERNAME')
where creator = (select user_key from user_mapping where lower_username = 'USERNAME@www.example.com');
```

I hope this helps someone work through this, until such time as Atlassian gives us a better way forward.


author: Michael Mohr
body: Had you finally made progress on your space migration and mapping of users? Because we are now facing the same issue with a company the we purchased and for what we now want to consolidate their own Confluence spaces in our central confluence installation. But even that physically the users stay the same from the purchased company, their accounts are different in bot systems as the purchased company had attached their Confluence to their AD.


author: Diego
body: Hello there, [@Daniel](/t5/user/viewprofilepage/user-id/3095342) ! Migrating users can be a tough procedure to complete, but it can be done.

First, there are a few things we need to clarify before. Here we go:
> * *Space XML exports do not contain users, at all*
> * *The full site export to XML does contain the users*
> * *Restoring a full site XML will overwrite the entire destination instance*
> * *You could recreate all the users from the original instance into your destination via SQL. We strongly advise against this.*

Crowd does ++*have enough power*++ to import and export users at will. Here is our documentation on this for Crowd:
> * [**++\[Crowd Server\] Importing Users from CSV Files++**](https://confluence.atlassian.com/crowd/importing-users-from-csv-files-64454760.html)
> * [++**\[Crowd Server\] How do I generate a CSV Export of Users, and Memberships From a Specific Directory in Crowd?**++](https://confluence.atlassian.com/crowdkb/how-do-i-generate-a-csv-export-of-users-and-memberships-from-a-specific-directory-in-crowd-442271568.html)

Confluence ++*does not have this functionality*++ (export user data as CSV). But we do have a database workaround that might help:
> * **++[\[Confluence Server\] How to Export User Data to CSV in Confluence](https://confluence.atlassian.com/confkb/how-to-export-user-data-to-csv-in-confluence-306350957.html)++**

You could also make use of a ++*third-party addon*++ that does export users to CSV. Here, take a look, Daniel:
> * [++**\[Atlassian Marketplace\] Confluence User Export**++](https://marketplace.atlassian.com/apps/1221278/confluence-user-export?hosting=server&tab=overview)

However, if your aim is to simply ++*migrate content (pages, spaces, and users) from one instance into another*++ , you can use the full site XML export. This, however, ++*will erase all content that already exists in the destination Confluence.*++

Here is how we do it:
> 1. *Go to the original instance*
> 2. *Click the Cog icon at the top right corner*
> 3. *Select General Configuration*
> 4. *Search for Backup \& Restore at the left side menu bar*
> 5. *Under ++Export this site++ click the Export button ![BackupRestoreUsers.jpg](https://community.atlassian.com/t5/image/serverpage/image-id/72935i9A792AAC95767885/image-dimensions/364x61?v=v2 "BackupRestoreUsers.jpg")*
> 6. *Now, go to your* ++Home Diretory++
> 7. *Go into the* ++backups++ *folder*
> 8. *Grab the XML file from there*
> 9. *Go to the destination Confluence*
> 10. *Click the Cog icon at the top right corner*
> 11. *Select General Configuration*
> 12. *Search for Backup \& Restore at the left side menu bar*
> 13. *Now we can select between uploading a file or restoring the XML from the Home Directory*
> 14. *Select to restore from home directory if your XML exceeds 1GB*
> 15. *Import the XML*

To ++*find your home folder,*++ you can do the following:
> 1. Click the Cog Icon at the top right corner
> 2. Select General Configuration
> 3. Search for ++*System Information*++ in the left side menu bar
> 4. Search for ++Confluence Home++
> 5. You will see the path to your home folder there

The process above ++*will restore all the content from the original instance*++ into the destination instance. However, ++*everything in the destination will be erased and replaced*++ with the XML data.

Here is the warning from within Confluence:

![Anota??o 2019-11-14 164503.jpg](https://community.atlassian.com/t5/image/serverpage/image-id/72937i09E63CED30B457F4/image-dimensions/587x27?v=v2 "Anota??o 2019-11-14 164503.jpg")

Also, here is our documentation on content import and export for Confluence:
> * ++**[\[Confluence Server\] Import Content Into Confluence](https://confluence.atlassian.com/doc/import-content-into-confluence-191141.html)**++
> * [++**\[Confluence Server\] Export Content to Word, PDF, HTML and XML**++](https://confluence.atlassian.com/doc/export-content-to-word-pdf-html-and-xml-139475.html)

I hope this shine some light at your situation, Daniel. Looking forward to your reply!

comments: author: Daniel
body: Thank you [@Diego](/t5/user/viewprofilepage/user-id/1188952) for the eloquent answer.

Users will be migrated on another level (from Crowd to an Active Directory), but user names will be modified in that step (currently we have email addresses as user names, they will be changed to cryptic strings). Maybe we even need to rename the users before migrating them into the new instance. Let's use this as the most probably scenario:

My questions only concerns the mapping of user names inside Confluence content (and also Jira content in another step).

Only users mentioned in the Confluence backup XML (or Jira backup XML) need to be mapped in this step. Not all user names in our system. So it doesn't matter that not all user data is contained in the backup XMLs of Confluence and Jira.

**Okay, let's assume, we have current user john.doe@example.com, who will be named "ABC123" in the target environment.**

Do you think, we'll be safe going the following route?:

1. Rename the user in current Crowd from john.doe@example.com to ABC123

2. Sync all directories

3. Backup Confluence space.

4. Migrate users to target environment (Crowd \> AD)

5. Sync all directories on target environment

6. Import Confluence space XML on target environment

Will the users be mapped correctly then? On the target environment, there already exist other users, so user keys (those which are internally used) will not be the same on source and target environment. So mathing can only be done via user name. Will this work?

**In case it won't work as described above:**

Is it correct, that in the Confluence XML I need to parse all the objects like this:

```
<object class="ConfluenceUserImpl" package="com.atlassian.confluence.user">
<id name="key"><![CDATA[ff80818169286c7e016a11f1d2f5000a]]></id>
<property name="name"><![CDATA[ABC123]]></property>
<property name="lowerName"><![CDATA[ABC123]]></property>
</object>
```

...to create a table with users name / key mappings like this:

**User name \| source env. user key**

**ABC123 \| ff80818169286c7e016a11f1d2f5000a**

Then, on target side, after XML import, we generate a similar table that will have different keys for each user name and then we merge the tables like this:

**User name \| source env. user key \| target env. user key**

**ABC123 \| ff80818169286c7e016a11f1d2f5000a \| DIFFERENTKEYhisadhoiasudh982**

And then, we can do a search-and-replace in the Space XML, replacing the old key with the new one, then re-import the XML.

**And: Is it the same with Jira?**

Thank you,

Daniel


author: Jeramy S
body: [@Daniel](/t5/user/viewprofilepage/user-id/3095342) - Were you able to figure out how to map the users? If you did, did you use a special program for the find and replace or did you script something internally?


author: Erik Anderson
body: I have the same problem.

We have two Confluence servers (for various reasons I won't go into).

Users on Server A also have accounts on Server B.

We must sometimes migrate content (**not** the *users* , the **content** -- the Confluence spaces) from Server A to Server B.

* If content on Server A has page-level restrictions so that only certain users can edit, we can migrate that space to Server B -- but then the restricted page isn't editable by *anyone*, since the restrictions are based on users who are not defined on Server B. Someone must manually remove the page-level restrictions, page-by-page, within Confluence on Server B. This is tedious, time-consuming, and error-prone.

What we need is one of two things.

1. Ideally, Atlassian would implement a means of mapping users from Server A to Server B. This might be a dialog that pops up on import, prompting us to correlate each Server A user mentioned in the XML import with a user on Server B.
2. Alternatively, and more simply, Atlassian would document the XML export format to explain where page-level restrictions are defined, how users are identified in the XML (some sort of GUID, presumably?), and some way of correlating those user identifiers with the user names in the UI, so that we could create our own script to alter the XML to suit our purposes.
   * I have combed through the XML export, and I cannot find either how page-level restrictions are defined, nor how users are identified. Googling hasn't helped either.


Tags: confluence-server

export

import

map

migration

server

user

xml