Automatic Company Initialization During Data Upgrade

Previously, when upgrading data from an older version of Microsoft Dynamics NAV to the latest version, you had to manually run codeunit 2 Company Initialization on each company in the database. When upgrading data to Microsoft Dynamics NAV 2016, this task is automatically performed for you by the upgrade process.

So I followed the link for more information. Unfortunately, there was no further information in this page. So I decided to just check the information by running a simple upgrade Codeunit. It was a very small upgrade Codeunit with only an upgrade function in it, no lines of code.

And this is the result of starting the upgrade:

As you can clearly see, Codeunit 2 has been executed automatically.

Now this is something that I really want to bring to your attention. This behavior can lead to unexpected problems after the upgrade.

For sure, you want to run Codeunit 2 when you upgrade to Dynamics NAV 2016. It will not only initialize some new set up tables, it also runs the Workflow initialization by calling InitWorkflow in Codeunit 1502 Workflow Setup. This process adds a lot of texts to the workflow tables. But… PowerShell cmdlets run by default in language en-US. So if any text is inserted into the database, it will be English and not the local language that you want to use! As a result, we recently ended up with a Dutch customer database that contains English workflow names and descriptions. We needed to cleanup a couple of tables and run workflow initialization again in the correct language. In all companies… (not a big problem, see below…)

The main problem with the Start-NAVDataUpgrade cmdlet is that it has no language parameter, like the Invoke-NAVCodeunit cmdlet does. It just runs in en-US language mode. I have tested if the Services Language setting in the NAV server settings would change this. Unfortunately that was not the case.

Is there any solution?

Actually there are several options.

One of the possibilities is to change the language in the very first line of Codeunit 2. But that adds another customization and we don’t like that. Hey, there is probably an event, one says. I’m sorry, didn’t found any. Could be an idea, however. Add an event OnBeforeCompanyInitialize and OnAfterCompanyInitialize to Codeunit 2 (Microsoft, are you there?).

Actually, the best option is to use the SkipCompanyInitialization switch on the Start-NAVDataUpgrade cmdlet.

This option is only available with PowerShell, you can’t set it when you start the data upgrade from the Development Environment.

After running the data upgrade, you can run Codeunit 2 manually in the correct language. If you need to run it after all, of course. To run this in all companies, you can easily use this PowerShell command:

But do we really need to run Codeunit 2 each time that we run a data upgrade? Well, certainly not. Up to CU5 this Codeunit didn’t change. And in previous versions there was never a need to run company initialize on every and each upgrade, e.g. after importing a fob file. So why did Microsoft add the option to automatically run company initialization at every data upgrade?

My best educated guess is because Codeunit 2 also calls the initialiation of workflow. This is of course a one time action, only needed when you import a fob that contains new workflow events or responses. So the train of thought is probably: when a fob contains new workflow elements, you just can run company initialize to update the workflow data. By the way, isn’t it strange that tables like 1520 Workflow Event and 1521 Workflow Response have Data per Company = Yes? But that’s another discussion…

Now the final question is, how can we initialize workflow without running company initialize? Well, the answer is easy. Use the same PowerShell cmdlet:

Finally, I would like to suggest to Microsoft that any PowerShell cmdlet that runs a Codeunit use a Language parameter. At least Sync-NAVTenant and Start-NAVDataUpgrade should have this option, so you can write upgrade codeunits with language independent code.

One more thing

There is one more thing that you should be aware of. In previous version of Dynamics NAV there were setup tables that were only accessible with the Extended Pack. In Codeunit 2 this was solved by this code:

I haven’t checked with NAV 2015, but at least in NAV 2016 this table is now in the Starter Pack. But ISV’s might have added initialization code to Codeunit 2 that does the same with their tables. So you want to run Codeunit 2 with the customer license, right? But what if you run the upgrade with your partner license because you have some upgrade Codeunits in the customization range? There your go, then Codeunit 2 will be executed with your partner license, which potentially leaves the database with records in tables that are not accessible with the customer license. I don’t have to explain what happens when the users start using the application, right?

I guess the customer will get an experience comparable with the one when opening a
standard Cronus database with a Starterpack and without Extended license pack ;).
Perhaps Microsoft can have a look at this too.

In NAV2015 there was an extra function [Invoke-CompanyInitialize] in the upgrade module. This function was used in the default upgrade proces [HowTo-UpgradeNAVDatabase]. The function [Invoke-CompanyInitialize] does not exist in the upgrade module of NAV2016. So instead of an extra upgrade function, it now is an extra parameter.

Company initialize should indeed run with customer license, upgrading NAV2015 to NAV2016 runs with developer license. So in the upgrade proces NAV2015-NAV2016 you can decide to swap license between these two steps with Import-NAVServerLicense. For upgrading within NAV2106 we only use objectbumbers in our addon, so these can run with customer license, without bothering license issues.

We had same problems with TimeZone settings. Running upgrade functions with windows client created a different DataTime (CREATEDATETIME) than running with the invoke CmdLets. They fixed these issues. Now the settings of the NAV Server are used. I do not understand why this was not fixed for Language as well. Probably we need to send a new request to MS.

This is a most unwanted feature. Especially, considering the license implications and the language issue. To work around this, I think you would need a definition of language code to use by company… essentially complicating this whole upgrade rigamarole. You can’t do without an upgrade codeunit because of schema changes, but doing the data upgrade dumps you into a sea of issues. Half-assed design again 🙁