Merging NAV Versionlists to NAV 2017 – Updated PowerShell functions!

Today should be the release of NAV 2017. And I assume you are going to want to upgrade to it. :-).  Let me save you from one upgrade-caveat ..

A while ago, I blogged about merging VersionLists with PowerShell. It shows a solution on how to handle (merge) version lists with PowerShell.

Judging from the amount of reads, it has been “used” quite a lot. I use it not daily, but at least every month .. to apply the Cumulative Update. You have been able to find the scripts on my github.

Some time ago, a great developer from the Netherlands called “Jan Hoek” created an issue on my github, telling me the function contains a bug. One I wasn’t aware of .. but he was very right.  Thanks for this! :-).  By the way, Jan has got a blog which you should check out!  Here it is:

The function is going to compare strings, like NAVW19.00 is greater than NAVW17.10 . This has worked, but only …

… until NAV 2017

Because NAV 2017 is version 10. Which means in the version list it’s NAVW110.00. If you do a text comparison with this, you will see that NAVW19.00 is greater than NAVW110.00. This is an issue, because merging version lists to NAV 2017 was all of a sudden not possible anymore.


There is a solution, and it’s already on my github. I changed one function, and added another one. Basically, I needed to be able to compare integers instead of strings. These are the two functions I’m talking about:

I changed “Merge-NAVVersionList” to loop the versionlists, compare them with the next one, and “bubble up” the one that I want.. .

function Merge-NAVVersionList
    param (

    Write-Verbose "Merging $OriginalVersionList, $ModifiedVersionList, $TargetVersionList"
    $allVersions = @() + $OriginalVersionList.Split(',')
    $allversions += $ModifiedVersionList.Split(',')
    $allversions += $TargetVersionList.Split(',')

    $mergedversions = @()
    foreach ($prefix in $Versionprefix)
        #add the "highest" version that starts with the prefix
        $PrefixVersionLists = $allVersions | where { $_.StartsWith($prefix) }
        $CurrentHighestPrefixVersionList = ''
        foreach ($PrefixVersionList in $PrefixVersionLists){
            $CurrentHighestPrefixVersionList = Get-NAVHighestVersionList -VersionList1 $CurrentHighestPrefixVersionList -VersionList2 $PrefixVersionList -Prefix $prefix

        $mergedversions += $CurrentHighestPrefixVersionList

        # remove all prefixed versions
        $allversions = $allVersions.Where({ !$_.StartsWith($prefix) })

    # return a ,-delimited string consiting of the "hightest" prefixed versions and any other non-prefixed versions
    $mergedversions += $allVersions
    $mergedversions = $mergedversions | ? {$_} #Remove empty
    $Result = $mergedVersions -join ','
    write-verbose "Result $Result"

And I added “Get-NAVHighestVersionList” to figure out which one is the highest versionlist of two, based on a prefix you provide:

function Get-NAVHighestVersionList
    param (
    if ([string]::IsNullOrEmpty($Versionlist1)){return $VersionList2}
    if ([string]::IsNullOrEmpty($Versionlist2)){return $VersionList1}
    if ($VersionList1 -eq $VersionList2) {
        return $VersionList1
        if ([String]::IsNullOrEmpty($Prefix)) {
            [int[]] $SplitVersionlist1 = $VersionList1.split('.')
            [int[]] $SplitVersionlist2 = $VersionList2.split('.')
        } else {
            [int[]] $SplitVersionlist1 = $VersionList1.Replace($Prefix,'').split('.')
            [int[]] $SplitVersionlist2 = $VersionList2.Replace($Prefix,'').split('.')
    } catch {
        $ReturnVersionList = $VersionList2
            [int[]] $SplitVersionlist2 = $VersionList2.Replace($Prefix,'').split('.')    
        } Catch {
            $ReturnVersionList = $VersionList1

        $WarningMessage = "`r`nVersionlists are probaly too unstructured to compare."
        $WarningMessage += "`r`n    VersionList1  : $VersionList1"
        $WarningMessage += "`r`n    VersionList2  : $VersionList2"
        $WarningMessage += "`r`n    Prefix        : $Prefix"        
        $WarningMessage += "`r`n    Returned value: $ReturnVersionList"
        $WarningMessage += "`r`nNo further action required is this is OK."

        Write-Warning -Message $WarningMessage
        return $ReturnVersionList

    $Count = $SplitVersionlist1.Count
    if ($SplitVersionlist2.count -gt $count){
        $Count = $SplitVersionlist2.Count

    $HighestVersionList = ''
    for ($i=0;$i -lt $Count;$i++){
        if ($SplitVersionlist1[$i] -gt $SplitVersionlist2[$i]){
            $HighestVersionList = $VersionList1
        if ($SplitVersionlist2[$i] -gt $SplitVersionlist1[$i]){
            $HighestVersionList = $VersionList2
        if ($HighestVersionList -ne ''){
            $i = $Count

    return $HighestVersionList


(Thanks to kfuglsang for contributing to this, and already providing a bugfix – I love the community :-) )

Probably, there are better ways to do this.  I’m always open for suggestions.  But for now, I hope this works for you :-).

You can test both functions with code like this.

$OrigVersionlist = 'NAVW17.10.00.37563,NAVBE7.10.00.37563'
$ModVersionList = 'NAVW17.10.00.37563,NAVBE7.10.00.37563,I7.4,M22344,M65877,I8.0'
$TgtVersionList = 'NAVW110.00,NAVBE10.00'
$MyVersionprefix = 'NAVW1', 'NAVBE', 'I'

Merge-NAVVersionList `
  -OriginalVersionList $OrigVersionlist `
  -ModifiedVersionList $ModVersionList `
  -TargetVersionList $TgtVersionList `
  -Versionprefix $MyVersionprefix

And the other one like:

Get-NAVHighestVersionList `
  -VersionList1 'NAVW110.00' `
  -VersionList2 'NAVW17.10.00.37563' `
  -Prefix 'NAVW1'

Your upgrade code can still stay the same – the signature of the main function “Merge-NAVVersionList” hasn’t changed, so you should not have to change any scripts – only these functions.