[AX2012 UTILS] It's all about scripting ... AX Model Deployment

Deploying an ax model via a PowerShell script ... A to Z
 Steps to be taken :
 1. Script must be run on the machine running the AOS (you will need to restart it - best practice); rights must be granted on the user that is running the script on the machine (service administration and on the ax database);
 2. Determine the configuration of the AOS - if you have multiple AOS's you must determine the name of the AOS you want to deploy to; that is open the AX Server Configuration utility and remember the AOS Intance name (like: 01-(MicrosoftDynamicsAX) - the MicrosoftDynamicsAX is what you are looking for); and also you will need the port;
3. I am doing a cleanup of the instance first; I do not have other models that could conflict - you have to see if this is the case for you;
 4. The steps in the script:

 - Load AX Management scripts
 - Stop the AOS
 - Clean up (delete layers)
 - Import new ax model
 - Start AOS
 - Do a sync
 - Do a compile
 - Do a CIL generation
 - You can not test your code

 The Script:

param(
    [string] $MODELPATH = $(throw "Model path required"),
    [string] $AXCONFIGPATH = $(throw "AX configuration file required"),
    [string] $MODELTODEPLOY = "PCGModel",
    [string] $DOAXSYNC = "y",
    [string] $DOAXCOMPILE = "y",
    [string] $LAYERSTOCLEAN = "",
    [long] $AXIMPORTTIMEOUT = 300000,
    [long] $AXSYNCTIMEOUT = 1800000,
    [long] $AXCOMPILETIMEOUT = 10800000
    )

& 'C:\Program Files\Microsoft Dynamics AX\60\ManagementUtilities\Microsoft.Dynamics.ManagementUtilities.ps1'

if(!(Test-Path $MODELPATH))
{
    Throw ("Error: Source path " + $MODELPATH + "does not exist")
}
if(!(Test-Path $AXCONFIGPATH))
{
    Throw ("Error: Could not find configuration file " + $AXCONFIGPATH)
}

$computername = gc env:computername

# Get the client bin directory from the config file
$axClientPath = [string] (type $AXCONFIGPATH | Select-String "bindir")
$axClientPath = ($axClientPath.split(","))[2]

# Get the server name from the config file
$aosServer = [string] (type $AXCONFIGPATH | Select-String "aos2")
$aosServer = ($aosServer.split(","))[2]
$aosInstance = ($aosServer.split("@"))[0]
$aosServer = ($aosServer.split("@"))[1]
if ($aosServer -eq $null)
{
    Throw "Error: The config file is incorrect (does not contain the AOS Instance name)"
}
$aosServer = ($aosServer.split(":"))[0]


# Make sure we're on the right server
if ($aosServer -ne (gc env:computername))
{
    Throw "Error: Script must be run on the AOS server the config file points to"
}

# Get the layer and layercode from the configuration
$buildlayer = [string] (type $AXCONFIGPATH | Select-String "aol,")
$buildlayer = ($buildlayer.split(","))[2]
$buildlayerCode = [string] (type $AXCONFIGPATH | Select-String "aolcode,")
$buildlayerCode = ($buildlayerCode.split(","))[2]

if($buildLayerCode -eq $null) # -and $buildLayerCode -ne "usr") -or $buildLayerCode -eq ""))
{
    Throw ("No layer specified for build layer " + $buildlayer)
}

# Get the log path
$logPath = [string] (type $AXCONFIGPATH | Select-String "logDir")
$logPath = ($logPath.split(","))[2]
$logPath = $env:UserProfile + '\Microsoft\Dynamics Ax\Log\'

# Get the AOS port from the configuration (aos name is ignored when connecting, so port is the only valid identifier)
$aosPort = [string] (type $AXCONFIGPATH | Select-String "aos2")
$aosPort = ($aosPort.split(","))[2]
$aosPort = ($aosPort.split(":"))[1]

# Open the list of servers running on this machine
$aosRegistryPath = "hklm:`\SYSTEM`\CurrentControlSet`\services`\Dynamics Server`\6.0"
$aosServers = Get-Item $aosRegistryPath
$aosServers = $aosServers.GetSubKeyNames()
$aosService = ""
for ($i=0; $i -le ($aosServers.Length - 1); $i++)
{
# Get the server properties, to find the current active config
    $serverProperties = Get-ItemProperty ($aosRegistryPath + "`\" + $aosServers[$i])
# Get the configuration
    $serverConfiguration = Get-ItemProperty ($aosRegistryPath + "`\" + $aosServers[$i] + "`\" + $serverProperties.Current)
# If this is our AOS port, get out of the loop
    if ($serverConfiguration.port -eq $aosPort)
    {
        $aosService = "AOS60`$" + $aosServers[$i]
        break
    }
    $aosService = ""
}

# If we didn't find it, throw an error
if ($aosService -eq "")
{
    Throw "Error: Could not find configuration for server running on port " + $aosPort
}

# Query the service for status
$aosServiceObj = Get-Service $aosService
if ($aosServiceObj.Status -eq "Running")
{
# If it's running, stop the service
    Stop-Service -WarningAction:SilentlyContinue ($aosService)
}
# Refresh our object
$aosServiceObj.Refresh()
if ($aosServiceObj.Status -eq "Running")
{
# If it's still running, something's wrong!
    Throw "Error: AOS service still running"
}


# Function to clear out layer artifacts
Function CleanLayer([string] $layer)
{
    Uninstall-AXModel -Layer $layer -Config $aosInstance -NoPrompt

}

CleanLayer "usr"
CleanLayer $buildLayer


Install-AXModel -File $MODELPATH -NoPrompt -Config $aosInstance


Set-AXModelStore -Config $aosInstance -NoInstallMode



# Start the AOS service
Start-Service -WarningAction:SilentlyContinue ($aosService)

# Refresh our object
$aosServiceObj.Refresh()
if ($aosServiceObj.Status -ne "Running")
{
# If it's not running, something's wrong!
    Throw "Error: AOS service could not be started"
}


$params = "`"" + $AXCONFIGPATH + "`" -lazyclassloading -lazytableloading -model=" + ($MODELTODEPLOY)
   
if ($DOAXSYNC -eq "y")
{
    $date = Get-Date


    $axProcess = Start-Process -PassThru ($axClientPath + "`\Ax32.exe") -ArgumentList ($params + " -StartupCmd=Synchronize")
    if ($axProcess.WaitForExit($AXSYNCTIMEOUT) -eq $false)
    {
        Throw ("Error: Synchronize did not complete within " + $AXSYNCTIMEOUT / 60000 + " minutes")
    }
}

if ($DOAXCOMPILE -eq "y")
{
    $date = Get-Date
    Write-Host "[AX CHECK] Compiling application ... takes a long time; Task started: " $date

    $axProcess = Start-Process -PassThru ($axClientPath + "`\Ax32.exe") -ArgumentList ($params + " -StartupCmd=CompileAll")
    if ($axProcess.WaitForExit($AXCOMPILETIMEOUT) -eq $false)
    {
        Throw ("Error: Compile did not complete within " + $AXCOMPILETIMEOUT / 60000 + " minutes")
    }
}

No comments:

Post a Comment