Comparing AX 2012 hotfix model lists

When Microsoft started releasing hotfixes for the Dynamics AX 2012 R3 release they made our lives a little harder. If you had just one or two hotfixes load it wasn’t too bad but as eventually you find yourself loading a hotfix that has hundreds of dependant hotfixes and suddenly your model store has a list of models a mile long in it. So, when you’re promoting code from your Development system through to Test and Production you need to be sure that you have all the right hotfixes loaded and with a long list of models in each model store, you can easily make a mistake and miss something.

Wouldn’t it be nice if you could just run some code that would compare two model stores and let you know if the hotfix list in both model stores is the same? I reached the conclusion that it definitely would make my life easier if I could do just that after staring at a list of models two miles long a few weeks back and I very quickly decided to build something to save my eyes.

PowerShell to the rescue

As it turns out, this is a relatively simple problem to solve with PowerShell. Here’s the code I came up with…

Param(
	[Parameter(Mandatory=$true)]
	[string]$SQLServer1,
	[Parameter(Mandatory=$true)]
	[string]$ModelStoreDB1,
	[string]$SQLServer2,
	[Parameter(Mandatory=$true)]
	[string]$ModelStoreDB2
)
 
If ( -not $SQLServer2 )
{
	$SQLServer2=$SQLServer1
}
 
# Validate the hotfix lists
write-Host		
write-host "Comparing hotfix lists for $SQLServer1/$ModelStoreDB1 & $SQLServer2/$ModelStoreDB2"
$DevHotfixes=@(axmodel -Server $SQLServer1 -Database $ModelStoreDB1 | where { $_.Name -match "Hotfix-KB" } | sort Name | select -ExpandProperty Name)
$BuildHotfixes=@(axmodel -Server $SQLServer2 -Database $ModelStoreDB2 | where { $_.Name -match "Hotfix-KB" } | sort Name | select -ExpandProperty Name)
$HotfixListMatches= -not  @($DevHotfixes | where {$BuildHotfixes -notcontains $_} | select -first 1).count
if ( $HotfixListMatches )
{
	# Check the other way around
	$HotfixListMatches= -not  @($BuildHotfixes | where {$DevHotfixes -notcontains $_} | select -first 1).count
}
 
If ( -not $HotfixListMatches )
{
    write-Host		
    write-Warning "The hotfixes loaded to to the systems do not match."
    write-Host		
    write-host
    write-Output "SideIndicator <= in $SQLServer1/$ModelStoreDB1 but not in $SQLServer2/$ModelStoreDB2"
    write-Output "              => in $SQLServer2/$ModelStoreDB2 but not in $SQLServer1/$ModelStoreDB1"
    write-host
    compare-object -referenceobject $devhotfixes -differenceobject $buildhotfixes
}
else
{
	write-Host		
	Write-Host "Hotfix lists match"
}

I’ve saved the code as “hotfixCompare.ps1” in my C:\Scripts directory. It’s got basic help features built in so it’ll help you run it if you forget the syntax. You call it from the AX management shell (it uses the AX model store utilities) like this…

To get the help info…

C:/Scripts/hotfixCompare.ps1 -?

Which returns…

hotfixCompare.ps1 [-SQLServer1] <string> [-ModelStoreDB1] <string> [[-SQLServer2] <string>] [-ModelStoreDB2] <string>

Note that the SQLServer2 parameter is optional if both model stores are on the same server. E.g.

CD C:/Scripts
./hotfixCompare.ps1 -SQLServer1 "AX1-k3SQL" -ModelStoreDB1 "AX1QA_model" -ModelStoreDB2 "AX1Dev_model"

Here’s the output from the example command run against two mismatched model stores (in fact the list of mismatches is much longer than this but I trimmed it here for ease of consumption.

WARNING: The hotfixes loaded to the systems do not match.


SideIndicator <= in AX1-k3SQL/AX1QA_model but not in AX1-k3SQL/AX1Dev_model
              => in AX1-k3SQL/AX1Dev_model but not in AX1-k3SQL/AX1QA_model


InputObject                             SideIndicator
-----------                             -------------
Hotfix-KB2949874-4552966-Foundation     =>
Hotfix-KB3003898-4558747-Foundation     =>
Hotfix-KB3012879-4548572-Foundation     =>
Hotfix-KB3012879-4548573-Foundation     =>
Hotfix-KB3015369-4547409-Foundation     =>
Hotfix-KB3017977-4548449-Foundation     =>
Hotfix-KB3018327-4548494-Foundation     =>

Hopefully that’ll save you some eyestrain some time.

This entry was posted in Technical (AX) and tagged , by Malcolm Burtt. Bookmark the permalink.

About Malcolm Burtt

Malcolm is a propeller head who has embraced the Dynamics AX platform for more than 16 years. Malcolm loves pushing the platform to its limits; finding the right solution and maximising its performance. When not messing about in AX, Malcolm loves sailing and reading...but his two boys generally have other ideas about what he should be doing with his time which is okay given that both boys are fun to be with.

Leave a Reply

Your email address will not be published. Required fields are marked *