Merging NAV Versionlists to NAV 2017 – Updated PowerShell functions!

Soon will 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: http://www.uncommonsense.nl/zen/

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.

Solution

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 (
        [String]$OriginalVersionList,
        [String]$ModifiedVersionList,
        [String]$TargetVersionList, 
        [String[]]$Versionprefix
    )

    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"
    $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 (
        [String]$VersionList1,
        [String]$VersionList2,
        [String]$Prefix
    )
   
    if ([string]::IsNullOrEmpty($Versionlist1)){return $VersionList2}
    if ([string]::IsNullOrEmpty($Versionlist2)){return $VersionList1}
    if ($VersionList1 -eq $VersionList2) {
        return $VersionList1
    }
    try{        
        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
        try{
            [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.

Enjoy!

5.00 avg. rating (98% score) - 2 votes

Permanent link to this article: https://www.waldo.be/2016/10/24/merging-nav-versionlists-to-nav-2017-updated-powershell-functions/

7 comments

2 pings

Skip to comment form

    • Kristof on January 18, 2017 at 9:59 am
    • Reply

    Oh no, not my Again 🙂

    Hi Waldo, I think i found a small bug in the loop here:
    I’m Merging W1 with CH NAV. [Better don’t ask why]. The problem i’m facing right now is the follow:
    COD1:
    W1 : NAVW110.0.00.14199 vs. CH: NAVW110.00.00.14199 [2 x 00]

    this leads to an empty HighestVersionList in return. Why? Well: you compare the string in the top which is not equal:
    if ($VersionList1 -eq $VersionList2)

    due to that you run into the Integercasting this will flatten the 00s to 0. like this the code within the loop for ($i=0;$i -lt $Count;$i++){…} will never detect a difference and the return value will be empty.

    • Mike on March 9, 2017 at 8:22 am
    • Reply

    It doesn’t run properly. It has got a syntax error. After correct it, the result was:
    NAVW110.00,NAVBE7.10.00.37563,NAVBE7.10.00.37563,I7.4,M22344,M65877,I8.0,NAVBE10.00

    It creates all version lists concatenated!

      • Mike on March 9, 2017 at 8:36 am

      Sorry, if a prefix doesn’t set in MyVersionPrefix returns all version list, It’s Ok. Thank you. It runs properly

      • waldo on March 9, 2017 at 8:58 am
        Author

      Cool :-). thanks for getting back 😉

    • Stefan on October 25, 2017 at 10:45 am
    • Reply

    Hi Waldo,

    first thanks for this useful functions. I had the same problem as Kristof, in my case it was from W1 to DE or DACH.
    W1: NAVW110.0 vs. DE: NAVW110.00

    To solve it, I added at the end of the function Get-NAVHighestVersionList this IF statement to get back the previous Highest Version List, if the new one is empty:

    if (($HighestVersionList -eq ”) -and ($VersionList1 -ne ”)){
    return $VersionList1
    }

    It may not be the smartest solution, but I’m not an expert with powershell and it works for me.

    Kind regards
    Stefan

    • Imran on October 16, 2019 at 5:22 pm
    • Reply

    Hello , how to use this with Merge-NAVApplicationObject please?

      • waldo on October 17, 2019 at 11:17 am
        Author

      The “MergeNavapplicationObject” simply uses this.
      Please check out this script, and follow it down: https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/blob/master/PSScripts/NAV%20Upgrades/UpgradeDatabase.ps1

      it has a “Merge-NAVUpgradeObjects”, which gets the prefixes for the versionlists… .

  1. […] Continued on Source: Merging NAV Versionlists to NAV 2017 – Updated PowerShell functions! » waldo's blog […]

  2. […] Bron : Waldo’s Blog Lees meer… […]

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.