New-NavVersionList – A Useful Improvement

Finally, at Van Dijk, we started to get our NAV (Dynamics everyone here
is calling it) installation upgraded to the latest version. So finally I can really
get into things like PowerShell, and not in the least the merge utilities. One of
first things I definitely wanted to get going with.

And surely, as many, I could profit from the various resources on the Internet.
Using the scripts from the product DVD, and both Bas Graaf post on the NAV team
blog and waldo’s post, I created the PowerShelll script, that allowed me to upgrade
our code to NAV 2016. Coming from NAV 2009 R2, this is quite a step, but indeed
the merge utilities do a pretty usable job. I really like the way conflicting code
is handled. I also ran into some issues where properties are not handled right,
but altogether I am really positive.

One other thing I ran into was the handling of the Version List. It’s
no secret that this was not properly implemented in the
Merge-NAVApplicationObject
cmdlet. However, Microsoft provided us some examples by means of a
How do I video
and a

blog post
both by Bas Graaf. And also

waldo
gave a helping hand. I tried both and decided to use Bas Graaf’s solution,
called New-NavVersionList.
Simply because I got it working somewhat easier and liked it better as it contains
lesser lines of code.

But … I found it had one relevant issue: it did not handle the deletion
of an version list part. More specifically: between NAV 2009 R2 and NAV 2016 some
standard objects, localized for NL, were reverted to w1. Therefor the Version List
should, after the merge and post processing with Bas’ script, not have a NAVNL part
in the Version List. And as you might have guessed, this went wrong.

To get a clear view on the result of the script I setup the following cases:

  • Cases 1 to 6 concerns updated w1 objects existing
    in NAV 2009 R2 (pure w1, or w1 localized and/or customized)
  • Case 7 a new w1 object
  • Cases 8 and 9 updated local objects (of which
    one is localized)
  • Case 10 a pure custom object

Guess I covered all options with this.

W1

Local

#

Object


Object Type


Updated


New


Updated


Removed


Custom

1

COD3

W1


X

2

COD11

W1


X


X

3

COD2

W1


X


X


X

4

COD74

W1


X


X

5

COD12

W1


X


X

6

COD1

W1


X


X


X

7

COD19

W1


X

8

COD11401

Local


X

9

COD11400

Local


X


X

10

COD50000

Custom


X

Running the Merge-NAVApplicationObject
cmdlet and post processing it with the original

New-NavVersionList the
result was as follows:

#

Object


Status

Original

Modified

Target

Result

Expected Result

1

COD3

OK

NAVW14.00

NAVW19.00

NAVW14.00

NAVW19.00

NAVW19.00

2

COD11

OK

NAVW16.00.01, NAVNL5.00

NAVW19.00, NAVNL9.00

NAVW16.00.01,NAVNL5.00

NAVW19.00,NAVNL9.00

NAVW19.00,NAVNL9.00

3

COD2

OK

NAVW16.00.01, NAVNL4.00.01

NAVW19.00, NAVNL9.00

NAVW16.00.01,NAVNL4.00.01,
CUSTOM6.00

NAVW19.00,NAVNL9.00, CUSTOM6.00

NAVW19.00,NAVNL9.00, CUSTOM6.00

4

COD74

OK

NAVW14.00.01

NAVW18.00

NAVW14.00.01,CUSTOM6.22

NAVW18.00,CUSTOM6.22

NAVW18.00,CUSTOM6.22

5

COD12

NOT
OK

NAVW16.00.10, NAVNL5.00

NAVW19.00

NAVW16.00.10,NAVNL5.00

NAVW19.00,NAVNL5.00

NAVW19.00

6

COD1

NOT
OK

NAVW16.00.10, NAVNL5.00

NAVW19.00

NAVW16.00.10,NAVNL5.00,
CUSTOM6.39

NAVW19.00,NAVNL5.00, CUSTOM6.39

NAVW19.00,CUSTOM6.39

7

COD19

OK

NAVW19.00

 

NAVW19.00

NAVW19.00

8

COD11401

OK

NAVNL6.00.01

NAVNL8.00

NAVNL6.00.01

NAVNL8.00

NAVNL8.00

9

COD11400

OK

NAVNL6.00

NAVNL8.00

NAVNL6.00,CUSTOM6.25

NAVNL8.00,CUSTOM6.25

NAVNL8.00,CUSTOM6.25

10

COD50000

OK

 

CUSTOM3.0

CUSTOM3.0

CUSTOM3.0

As you can see case 5 and 6 where not OK (have a look at the Result and
Expected Result), being the fact that the NAVNL should not end up in the
Result as the NL localization was removed from both COD 1 and COD12 (have
also a look at the Modified and Target).

For clarity this was the merge scenario:

ORIGINAL = NAV 2009 R2
MODIFIED =

NAV 2016

TARGET =

CUSTOM NAV 2009 R2

RESULT = CUSTOM NAV 2016

For completeness I also executed the other, valid scenario:

ORIGINAL = NAV 2009 R2
MODIFIED =

CUSTOM NAV 2009 R2

TARGET =

NAV 2016

RESULT = CUSTOM NAV 2016

Resulting in:

#

Object


Status

Original

Modified

Target

Result

Expected Result

11

COD3

OK

NAVW14.00

NAVW14.00

NAVW19.00

NAVW19.00

NAVW19.00

12

COD11

OK

NAVW16.00.01, NAVNL5.00

NAVW16.00.01,NAVNL5.00

NAVW19.00, NAVNL9.00

NAVW19.00,NAVNL9.00

NAVW19.00,NAVNL9.00

13

COD2

OK

NAVW16.00.01, NAVNL4.00.01

NAVW16.00.01,NAVNL4.00.01,
CUSTOM6.00

NAVW19.00, NAVNL9.00

NAVW19.00,NAVNL9.00, CUSTOM6.00

NAVW19.00,NAVNL9.00, CUSTOM6.00

14

COD74

OK

NAVW14.00.01

NAVW14.00.01,CUSTOM6.22

NAVW18.00

NAVW18.00,CUSTOM6.22

NAVW18.00,CUSTOM6.22

15

COD12

OK

NAVW16.00.10, NAVNL5.00

NAVW16.00.10,NAVNL5.00

NAVW19.00

NAVW19.00

NAVW19.00

16

COD1

NOT
OK

NAVW16.00.10, NAVNL5.00

NAVW16.00.10,NAVNL5.00,
CUSTOM6.39

NAVW19.00

NAVW19.00,NAVNL5.00, CUSTOM6.39

NAVW19.00,CUSTOM6.39

17

COD19

OK

 

NAVW19.00

NAVW19.00

NAVW19.00

18

COD11401

OK

NAVNL6.00.01

NAVNL6.00.01

NAVNL8.00

NAVNL8.00

NAVNL8.00

19

COD11400

OK

NAVNL6.00

NAVNL6.00,CUSTOM6.25

NAVNL8.00

NAVNL8.00,CUSTOM6.25

NAVNL8.00,CUSTOM6.25

20

COD50000

OK

CUSTOM3.0

 

CUSTOM3.0

CUSTOM3.0

Being still an amateur PowerShell user I tried to tweak the script to get the
desired result, but, honestly, I totally failed, and asked Bas for help, who quite
quickly answered with an improved version. Well … a changed version that yielded
the same results. But his second improvement was a hit.

Original Script

function
New-NavVersionList($MergeInfo,
[string[]]$ProductCode
= (“NAVW1”,“NAVNL”,“CUSTOM”))
{
  
$allVersions
= @() +
$MergeInfo.modified.versionlist
-split ‘,’
   $allVersions
+= $mergeInfo.target.versionlist
-split ‘,’

   $mergedVersions
= @()

   foreach
($code in
$ProductCode)
   {
      # keep
the “highest” version tag for $code

      $mergedVersions
+= $allVersions
| where {
$_ -like
$code*”
} | sort
| select
-last 1

     
# remove all
$code version tags

      $allVersions
= $allVersions
| where {
$_ -notlike
$code*”
}
   }
   # return a ,-delimited string consisting
of the “highest” versions for each $ProductCode and any other tags

   $mergedVersions
+= $allVersions
   $mergedVersions
-join ‘,’
}

Improved Script

function
New-NavVersionList($MergeInfo,
[string[]]$ProductCode
= (“NAVW1”,“NAVNL”,“CUSTOM”))
{
  
$allVersions
= @() +
$MergeInfo.modified.versionlist
-split ‘,’
   $allVersions
+= $mergeInfo.target.versionlist
-split ‘,’

   $mergedVersions
= @()

   foreach
($code in
$ProductCode)
   {
      # add only to merged
version list if the product code was not removed

      if (($MergeInfo.original.versionlist
-notlike “*$code*”
-or ($allVersions
-like $code*”).Count
-ge 2))
      {
        # keep
the “highest” version tag for $code

        $mergedVersions
+= $allVersions
| where {
$_ -like
$code*”
} | sort
| select
-last 1
      }
     
# remove all
$code version tags

      $allVersions
= $allVersions
| where {
$_ -notlike
$code*”
}
   }
   # return a ,-delimited string consisting
of the “highest” versions for each $ProductCode and any other tags

   $mergedVersions
+= $allVersions
   $mergedVersions
-join ‘,’
}

The main part of the script was left unchanged, only an if-clause was added that
incorporates the code to select the “highest” version tag.

Facit

Now it work perfectly well in all cases I am working with. As you can see I did
not test it with more than three tags in the Version List. I leave that up to you.

A big thanx to Bas Graaf! [{]

One Comment

  1. Hi Maarten, just only today I saw your comment, because … I ran into the same now. Working on a fix. It was clearly a omission in the solution as it is sorting the Version Lists textually, so NAVW110.0 will be "lower" than NAVW19.00.

Leave a Reply

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