Introduction

Over the years, I have been involved in numerous migrations of TFS/Azure DevOps Server from on-premises servers to the cloud hosted Azure DevOps Services using the Microsoft Azure DevOps Data Migration Tool. As long as you carefully followed the instructions, the process was relatively straightforward.

I was recently involved in a cloud migration of a set of non-English Azure DevOps Servers i.e. the Azure DevOps Servers had been installed in French not English. Migrating these servers to Azure DevOps Services proved a challenge.

The Problem

The core of the problem with this type of migration is that the target system, Azure DevOps Services, is only available in English.

At this point it is important to explain what is meant by the previous statement. Azure DevOps Services allows you to set a language preference, which you set in your user profile, but the underlying database is always in English. This means that if you have a non-English Azure DevOps Server, where the database is non-English, the migration will have problems.

This problem becomes apparent when you perform the first step of using the Azure DevOps Data Migration Tool, the migrator validate command to validate your TPC (Team Project Collection) prior to migration.

Note Remember you migrate a TPC, not a whole Azure DevOps Server, which could have many TPCs

This command checks the source Azure DevOps Server TPC for issues that will block a migration. In the case of my Non-English server TPC the validation returned many issues.

The first was a warning about the database collation being French_CI_AS, so any migration could result in some characters not being migrated correctly e.g. Non-English characters like ‘é’ might become equivalent to the English ’e’ after migration. However, this was just a warning, and not an error, so can be ignored for now and reviewed as part of the planned dry-run of the migration.

The bigger problem was the many errors in the form

VS403443: In order to migrate successfully, you must rename field 'System.Title' to 'Title'. Given name for 'System.Title' is 'Titre'

When you do these migrations there are often VSxxxxxx or TFxxxxxx errors, especially on TPCs that have been upgraded through various versions of TFS and Azure DevOps over the years. These are usually fixable by editing the process template as discussed in the migration documentation.

However, when I tried to fix these issues I saw two completely separate sets of problems, depending on whether the TPC was using the older XML Process Templates or the newer Inherited Process Templates.

When the TPC is using XML Process Templates

When the migration was for a TPC using the older XML Process templates, I found that once I had fixed the VS403443 errors using commands like

witadmin.exe changefield /collection:http://server:8080/tfs/defaultcollection, /n:System.Title /name:"Title" /noprompt

When I reran the migrator validate command, I got a new set of errors, but they were the same errors as before, just with the field names reversed e.g..

VS403443: In order to migrate successfully, you must rename field 'System.Title' to 'Titre'. Given name for 'System.Title' is 'Title'

I was in an endless loop of errors.

When the TPC is using Inherited Process Templates

When the migration was for a TPC using the newer Inherited Process Templates, the problem was that I could not use the witadmin tool. There is in fact no supported way to update the display name for built-in work item types fields.

This is because the Inherited Process Templates are stored in the database, and not as XML files.

The Solutions

We have to consider the solutions to these problems separately.

XML Process Templates

After much unsuccessful experimentation, I reached out to the community to see if anyone had a solution to the problem and a fellow DevOps MVP, Neno Loje suggested he had had success in the past migrating TPCs originally setup in German, but the process he used came with some constraints.

The process I ended up with, based on his suggestions, was based around migrating the Non-English Team Project Collection (TPC) to an temporary English Azure DevOps Server:

  1. Build a new Azure DevOps Server, making sure you pick the default language English
  2. Detach the TPC to be migrated on the Non-English Azure DevOps Server and make a SQL Backup of the detached TPC Database on the Non-English Azure DevOps Server

    Note Once the backup is done, you will usually reattach the TPC on the source Non-English server so users can continue to work while you do the dryrun migration

  3. Restore the TPC SQL backup on the new English Azure DevOps Server and attach the exported Non-English TPC to the new English Azure DevOps Server
  4. On the new English Azure DevOps Server run the migrator validate command to check for errors, and fix them. This should be possible without getting into the error loops
    • Update all WIT fields causing the VS403443 errors, rename display names to the English names as discussed above using the witadmin command)

      Note I wrote this PowerShell script to automate the process of generating the commands to do the renaming of fields in a process template based on the migration error log.

    • Fixing any remaining errors in the migration should be possible with further XML template file edits which are published using the witadmin command as discussed in the migration documentation

      Note Watch out for any for=[group] and not=[group] attributes in the WITD XML files, used to conditionally set field constraints e.g. make a field readonly for all users except those in a specific group. These constraints are not supported in Azure DevOps Services, but are not always picked up by migrator validate. If they are not removed, they will cause the import to fail. An import failure email message will be recieved via email in form

      Step : ProcessValidation - Failure Type - Validation failed : Invalid process template: WorkItem Tracking\TypeDefinitions\Bug.xml:: Object reference not set to an instance of an object.

    • You can also look at using the ConformProject.ps1 script to help with this process. ConformProject will take a defined process template that is on your local machine and apply it, in full, to a specified project. This is a good way to get rid of all the errors, but you will lose all your customisations, so use with care.

  5. Once all the errors are fixed, the validation should pass, and hence the rest of the migration process should be possible

However, the fact your migration completed might not be the end of your issues. There is of course the potential issue of the collation of the database, but arguably this is a minor issue. The more important point is something Neno had mentioned. He commented that this process is good for a read-only migration to Azure DevOps Services, but if you wish to continue using the migrated work items more work is required.

The reason for this is not the migration of the process template, it’s the actual work item data. The imported work items are still using strings for state and other fields in the non-English language and need to be “converted” to values that match the constraints of the ‘fixed’ english process template.

To fix this means edits are required for all active work items. This of course could be done one-by-one as Work Items are edited, or via scripts to make the changes at scale, but more the work will be required to make the work item data usable in Azure DevOps Services.

Inherited Process Templates

—— DANGER ZONE ——

The following section describes a process that is not supported by Microsoft and could lead to serious issues with your Azure DevOps Server.

The process should only be used on a copy of a system, not on a live system itself.

I accept no responsibility for any issues that arise from following this process, you follow it at your own risk.

When the migration was for a TPC using Inherited Process Templates, the solution is very different, and can only be described as a massive hack.

There are two reasons for the need for a different process

  • With inherited process templates the built-in work item types are by design read only. Your customisations are additions to the built-in work item types. You cannot change the built-in work item types, you can only hide or add new fields to them. There is no equivalent of the witadmin command to change the display names of fields in the Inherited Process Templates, all changes are done via the Azure DevOps UI or REST API.
  • The other reason for the different process is that it is not possible to attach a Non-English Inherited Process TPC to an English Azure DevOps Server. Any ‘fixing’ process must be done on a Non-English server.

So, the process I ended up with is as follows:

  1. IMPORTANT Create a duplicate of your Non-English Azure DevOps Server, this is the one you will use for the migration process. This step is very important, as you will be making SQL edits to the database which is very unsupported.
  2. On the duplicate Non-English Azure DevOps Server load SQL Server Management Studio (SSMS) and connect to the TPC database.
  3. For each VS403443 error run the following SQL command to update the display name of the field in the database:
    UPDATE [dbo].[WorkItemTypeField]
    SET [Name] = 'Title',
        [ReportingName] = 'Title'
    WHERE [ReferenceName] = 'System.Title'
    

    Note Again I wrote a PowerShell script to automate the process of generating the SQL commands to do the renaming of fields in a process template based on the migration error log.

  4. Rerun the migrator validate command to check for any remaining errors, and fix them.
  5. Once all the errors are fixed, the validation should pass, and hence the rest of the migration process should be possible

Again the fact your migration completed is not the end of your issues, in fact the issues are much worse than with the XML Process Templates.

The reason for this is that the Non-English inherited process template tries to match all your work items to the built-in work item types based on the string of the work item type name. So for example, it will try to match the work item type ‘Bogue’ in your French team project to the built-in work item type ‘Bug’, which will of course fail.

This is a serious problem, as it means much of the Azure Boards and Azure Test Plans UI will fail to load any work items, if they even load at all. The work item data is there, you can see it via the REST API e.g. https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}, but the UI will not work as the work item type names are not what the English based Azure DevOps Services instance is expecting.

In theory there must be a way to fix this, but it will require a lot of SQL edits prior to migration to Azure. Far more work than I have the appetite to do.

So in summary, you have to consider this process for migrating Non-English inherited process based TPCs to only be acceptable if your key goal is to migrate your TFVC repositories with no data loss to Azure DevOps Services, and that you are prepared to accept that the work item data will not be usable.

Your only real option if you need the work item data from a Non-English on-premises Inherited process TPC in Azure DevOps Services is to look at using Martin Hinshelwood Azure DevOps Migration Tools to migrate the on-premises work items to a new Azure DevOps Services project on the migrated Azure DevOps Service instance, one that is setup using an English based inherited process template. Given the need to address translation issues during this migration this will also be a not insignificant undertaking.

Conclusion

Migrating a non-English Azure DevOps Server to Azure DevOps Services is possible, but it is not officially supported and requires some extra steps, some of them very ‘hacky’.

If you are considering either of the migration paths in this post, I would recommend in the strongest terms that you perform your migrations on a duplicate of your Azure DevOps Server and not on your live system.

I cannot stress enough, please DO NOT make SQL edits of your live Azure DevOps Server database, as this is not supported and could lead to serious issues with your live system.