
This blog post is about an unsupported exercise to create a monster with pieces of different bodies, like Mary Shelley’s Frankenstein.
IMPORTANT DISCLAIMER
What will follow is not supported and discouraged by Microsoft officially.
You can read the official documentation post here
Exporting Databases in the Admin Center - Business Central | Microsoft Docs
And underlined in bold by the following blog post
Tattoo well in mind that the operations of building such monster will always end in having some pieces missing or not perfectly fitting.
A couple of examples: AppSource apps and 1st party app versioning. But there are more.
AppSource apps. These are embedded in the application database and not part of the restore environment. AppSource app data in SQL Server will be restored, of course, but you cannot use that nor surfacing through the UI since you do not have the AppSource app deployed on-prem. Unless you have access to AppSource apps (you are the owner) or runtime packages from these.
1st party app versioning. Despite of you might think that SaaS and On-Premises are branched with exactly same version number, SaaS is evolving with hotfix/patching strategy in the application and platform between each minor update. In other words, Base Application and other 1st party app most probably will differ in, at least, revision number comparing what is deployed in SaaS and its equivalent On-Premises Cumulative Update (CU).
Building the Monster
$serverInstance = 'BC180'
$serviceAccount = 'EUROPE\DTACCONI'
$sqlDbServer = 'HEISEMBERG'
$sqlInstance = 'SQL2019'
$demoDatabase = 'Demo18'
$appDatabase = 'AppDatabase'
$tenantDatabase = 'ProdSaaS'
Import-Module 'C:\Program Files\Microsoft Dynamics 365 Business Central\180\Service\navadmintool.ps1'
$appCollection = Get-item 'C:\TEMP\RESTORE\PTE\*.app'
$appCollection
foreach ($appItem in $appCollection)
{
Publish-NAVApp -ServerInstance $serverInstance -PackageType Extension -Path $appItem.FullName -SkipVerification -Force
}
Get-NAVAppInfo $serverInstance | ForEach-Object {Sync-NAVApp -ServerInstance $serverInstance -Name $_.Name -Force }
Get-NAVAppInfo $serverInstance | ForEach-Object {Install-NAVApp -ServerInstance $serverInstance -Name $_.Name -Force }
Sync-NAVTenant $serverInstance -Force
Get-NAVAppInfo -ServerInstance $serverInstance -TenantSpecificProperties -Tenant default | Format-List
Export-NAVApplication -DatabaseServer $sqlDbServer -DatabaseInstance $sqlInstance -DatabaseName $demoDatabase -DestinationDatabaseName $appDatabase -ServiceAccount $serviceAccount
Export-NAVApplication -DatabaseServer $sqlDbServer -DatabaseInstance $sqlInstance -DatabaseName $appDatabase -DestinationDatabaseName $tenantDatabase -ServiceAccount $serviceAccount
Set-NAVServerConfiguration $serverInstance -KeyName Multitenant -KeyValue False
Set-NAVServerConfiguration $serverInstance -KeyName DatabaseName -KeyValue $tenantDatabase
Set-NAVServerConfiguration $serverInstance -KeyName EnableTaskScheduler -KeyValue False
Restart-NAVServerInstance $serverInstance -Force
NOTE: below the typical error in Event Viewer Application log when Nav App Installed App table records has not been appropriately hacked:
The runtime package ID '00000000-0000-0000-0000-000000000000' with package ID 'xxxx-xxxx…' for the tenant 'default' does not correspond to an installed app.
Sync-NAVTenant $serverInstance -Tenant default -Mode ForceSync -Force
Get-NAVTenant $serverInstance
Get-NAVAppInfo $serverInstance -Tenant Default -TenantSpecificProperties
New-NAVServerUser $serverInstance -WindowsAccount $serviceAccount -FullName DTACCONI
New-NAVServerUserPermissionSet $serverInstance -UserName $serviceAccount -PermissionSetId SUPER
And now you have your own Frankenstein single tenant (legacy mode) environment on-premises.
Once again, be aware that these kinds of hacking are prone to changes by Microsoft, errors and data loss. This is just an exercise to understand the reason why it is not a supported task by Microsoft.