Wednesday, February 20, 2013

Deploy Modelstore with less downtime

Introduction
Everyone working with deployment of code in AX2012 should by now be familiar with the concept of a modelstore, and the importance of making sure you move the complete modelstore from your source to your target environment.

Now the time it takes to export and import a modelstore can be several minutes. Content is being read from disk and injected into model database on the SQL Server. We also know the AOS needs to be down while the AOT is getting its modelstore updated with new content, otherwise bad and unforeseen issues will eventually happen.

In order to reduce downtime while establishing an updated application, Microsoft offers tools for us to inject the modelstore into a temporary database Schema, and when all the content has been read of the disk and injected into the SQL Server database, the last operation of moving it from the temporary Schema to "dbo" can be done in just a matter of seconds. Essentially, you can get away with just the time it takes to synchronize the Data Dictionary after the new modelstore is applied to the environment.

The steps involved are already fairly well documented on MSDN, but perhaps this little Powershell script is enough to get you going.

The Code

import-module "C:\Program Files\Microsoft Dynamics AX\60\ManagementUtilities\Microsoft.Dynamics.ManagementUtilities.ps1"

#region Variables

$sourceserver = "sql2012\test"
$targetserver = "sql2012\prod"
$sourcedb = "AX2012_Test_model"
$targetdb = "AX2012_Prod_model"
$modelstorepath = "c:\Modelstores\"

#endregion

#region Work

$dte = get-date -format s
$dte = $dte.tostring() -replace "[:\s/]", ""
$backFileName = "$modelstorepath" + $dte + ".axmodelstore"

Export-AXModelStore -Server $sourceserver -Database $sourcedb -File $backFileName
Initialize-AXModelStore –Server $targetserver -Database $targetdb –SchemaName Temp
Import-AXModelStore -Server $targetserver -Database $targetdb -SchemaName Temp -File $backFileName -NoPrompt
# Only works in Console
if (!$psISE)
{
 Write-Host "Press any key to when you have stopped the AOS to continue the Import..."
 $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
 Write-Host ""
}
Import-AXModelStore -Server $targetserver -Database $targetdb -Apply Temp  -NoPrompt
Initialize-AXModelStore -Server $targetserver -Database $targetdb –Drop Temp -NoPrompt

"Completed!"

#endregion

Now all you need to do to run this code is to change the variables at the top, and save it as a ps1 file somewhere, and finally run it. I have added a "press any key"-pause just before the modelstore gets applied, so you can head over to Services and Stop the AOS before it gets applied. Finally the temporary Schema gets dropped and the only thing you need to do is to start the AOS, open a developer workspace and make sure the Data Dictionary gets synchronized.