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