NAVObjectMgt/Merge-NCHNAVApplicationObjects.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
function Merge-NCHNAVApplicationObjects {
    <#
    .SYNOPSIS
    Merge objects using a NAV Container on a remote Docker Host.
     
    .DESCRIPTION
    It is using the default merge commandlets coming from Microsoft, and the Cloud.Ready.Software.NAV module from waldo to merge objects.
    Things it considers/executes:
    - Merge the objects
    - Languages (avoid language conflicts by exporting and removing languages)
    - Merges version lists
    - Lists failed objects
    - Shows mergeresult
    - Saves mergeresult
        
    .PARAMETER ContainerName
    The Container used to merge
     
    .PARAMETER UpgradeSettings
    The is a dictionary - so a collection of settings. See examples to see what settings there are, and how to create that dictionary.
     
    .EXAMPLE
    Creating the "UpgradeSettings" dictionary:
        #In one Dictionary, to be able to easily pass it to remote servers
        $UpgradeSettings = @{}
 
        #General
        $UpgradeSettings.UpgradeName = 'CustomerX'
 
        $UpgradeSettings.OriginalVersion = 'Distri81'
        $UpgradeSettings.ModifiedVersion = 'CustomerX'
        $UpgradeSettings.TargetVersion = 'Distri110'
 
        $UpgradeSettings.LocalOriginalFile = "$env:USERPROFILE\Dropbox\Dynamics NAV\ObjectLibrary\$($UpgradeSettings.OriginalVersion).zip"
        $UpgradeSettings.LocalModifiedFile = "$env:USERPROFILE\Dropbox\Dynamics NAV\ObjectLibrary\$($UpgradeSettings.ModifiedVersion).zip"
        $UpgradeSettings.LocalTargetFile = "$env:USERPROFILE\Dropbox\Dynamics NAV\ObjectLibrary\$($UpgradeSettings.TargetVersion).zip"
 
        $UpgradeSettings.VersionListPrefixes = 'NAVW1', 'NAVBE', 'I'
        $UpgradeSettings.AvoidConflictsForLanguages = 'NLB','FRB','ENU','ESP'
 
        #Semi-fixed settings (scope within container)
        $UpgradeSettings.UpgradeFolder = 'C:\ProgramData\NavContainerHelper\Upgrades' #locally in the container
        $UpgradeSettings.ObjectLibrary = Join-Path $UpgradeSettings.UpgradeFolder '_ObjectLibrary'
        $UpgradeSettings.ResultFolder = Join-Path $UpgradeSettings.UpgradeFolder "$($UpgradeSettings.UpgradeName)_Result"
 
        $UpgradeSettings.OriginalObjects = Join-Path -Path $UpgradeSettings.ObjectLibrary -ChildPath "$($UpgradeSettings.OriginalVersion).txt"
        $UpgradeSettings.ModifiedObjects = Join-Path -Path $UpgradeSettings.ObjectLibrary -ChildPath "$($UpgradeSettings.ModifiedVersion).txt"
        $UpgradeSettings.TargetObjects = Join-Path -Path $UpgradeSettings.ObjectLibrary -ChildPath "$($UpgradeSettings.TargetVersion).txt"
     
    .EXAMPLE
    Perform upgrade:
        Merge-NCHNAVApplicationObjects `
            -ContainerName $ContainerName `
            -UpgradeSettings $UpgradeSettings
 
    .EXAMPLE
    A full example with collection of scripts for one upgrade can be found on my github:
    https://github.com/waldo1001/Cloud.Ready.Software.PowerShell/tree/master/PSScripts/NAV%20Docker/RemoteDocker
     
    .NOTES
    This function is dependent from the Cloud.Ready.Software.* modules from waldo. Use the Install-NCHDependentModules to install the necessary modules on the remote servers/containers.
     
    #>


    param(
        [Parameter(Mandatory = $true)]
        [String] $ContainerName,
        [Parameter(Mandatory = $true)]
        [Object] $UpgradeSettings
    )

    Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) on $env:COMPUTERNAME"

    $Session = Get-NavContainerSession -containerName $ContainerName
    Invoke-Command -Session $Session -ScriptBlock {
        param(
            $UpgradeSettings
        )
        $StartedDateTime = Get-Date

        if (Test-Path $UpgradeSettings.ResultFolder) {
            Remove-Item -Path $UpgradeSettings.ResultFolder -Recurse -ErrorAction Stop -Confirm
        }

        Write-Host -ForegroundColor Green "Starting upgrade with following parameters:"
        write-host -ForegroundColor Gray -Object (ConvertTo-Json $UpgradeSettings)

        $MergeResult = Merge-NAVUpgradeObjects `
            -OriginalObjects $UpgradeSettings.OriginalObjects `
            -ModifiedObjects $UpgradeSettings.ModifiedObjects `
            -TargetObjects $UpgradeSettings.TargetObjects `
            -WorkingFolder $UpgradeSettings.ResultFolder `
            -CreateDeltas `
            -VersionListPrefixes $UpgradeSettings.VersionListPrefixes `
            -Force `
            -DoNotOpenMergeResultFolder `
            -AvoidConflictsForLanguages $UpgradeSettings.AvoidConflictsForLanguages
        
        $FilteredMergeResultFolder = Copy-NAVChangedMergedResultFiles -MergeResultObjects $MergeResult.MergeResult
        
        #Save Result
        $MergeResult | ConvertTo-Json | Set-Content -Path (Join-Path $UpgradeSettings.ResultFolder 'Mergeresult.json')
        $MergeResult | Export-Clixml -Path (Join-Path $UpgradeSettings.ResultFolder 'Mergeresult.xml')
        
        #Save Used Settings
        $UpgradeSettings | ConvertTo-Json | Set-Content -Path (Join-Path $UpgradeSettings.ResultFolder 'UpgradeSettings.json')

        #List Conflicts
        $NumberOfConflicts = ($MergeResult.Mergeresult | Where-Object {$_.MergeResult -eq 'Conflict'}).Count
        Write-host -foregroundcolor Magenta -Object "There are $NumberOfConflicts conflicts."                
        if ($NumberOfConflicts -ge 1) {
            $MergeresultSummary = $MergeResult.Mergeresult | Where-Object {$_.MergeResult -eq 'Conflict'} | Group-Object {$_.ObjectType} 
            foreach ($Item in $MergeresultSummary) {
                Write-Host " $($Item.Count) $($Item.Name) Conflicts" -ForeGroundColor Gray
            }
        }

        #List Failed
        $NumberOfFails = ($MergeResult.Mergeresult | Where-Object {$_.MergeResult -eq 'Failed'}).Count
        Write-host -foregroundcolor Magenta -Object "There are $NumberOfFails failed objects"
        if ($NumberOfFails -ge 1) {
            Foreach ($item in ($MergeResult.Mergeresult | Where-Object {$_.MergeResult -eq 'Failed'})) {
                Write-Host " $($Item.ObjectType) - $($Item.Id): $($Item.Error)" -ForeGroundColor Gray
            }
        }


        $StoppedDateTime = Get-Date
        Write-Host 'Total Duration' ([Math]::Round(($StoppedDateTime - $StartedDateTime).TotalSeconds)) 'seconds' -ForegroundColor Yellow

    } -ArgumentList $UpgradeSettings

}