ContainerHandling/Extract-FilesFromStoppedNavContainer.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<#
 .Synopsis
  Extract Files From stopped NAV/BC Container
 .Description
  Extract all files from a Container Image necessary to start a generic container with these files
 .Parameter containerName
  Name of the Container from which you want to extract the files
 .Parameter path
  Location where you want the files to be placed
 .Parameter extract
  Determine what you need to extract (default is all)
 .Parameter force
  Specify -force if you want to automatically stop the container if running and remove the destination folder if it exists
 .Example
  Extract-FilesFromStoppedNavContainer -ContainerName temp -Path "c:\programdata\navcontainerhelper\extensions\acontainer\afolder"
#>

function Extract-FilesFromStoppedNavContainer {
    [CmdletBinding()]
    Param (
        [string] $containerName,
        [string] $path,
        [ValidateSet('all','vsix','database')]
        [string] $extract = "all",
        [switch] $force
    )

    $startContainer = $false
    if ((docker inspect -f '{{.State.Running}}' $containerName) -eq "true") {
        if (!$force) {
            throw "Container is running. Cannot extract files from a running container"
        }
        $startContainer = $true
        Stop-NavContainer $containerName | Out-Null
    }

    if (Test-Path -Path $path) {
        if (!$force) { 
            throw "Destination folder '$path' already exists"
        }
        Remove-Item -Path "$path\*" -Recurse -Force
    }
    else {
        New-Item -Path $path -ItemType Directory -Force | Out-Null
    }

    $ErrorActionPreference = 'Continue'

    if ($extract -eq "all") {

        $inspect = docker inspect $containerName | ConvertFrom-Json
        if ($inspect.Config.Labels.psobject.Properties.Match('platform').Count -ne 0) {
            Set-Content -Path "$path\platform.txt" -value "$($inspect.Config.Labels.platform)"
        }
        $country = $inspect.Config.Labels.Country
        Set-Content -Path "$path\country.txt" -value "$country"
        Set-Content -Path "$path\version.txt" -value "$($inspect.Config.Labels.Version)"

        New-Item "$path\ServiceTier\System64Folder" -ItemType Directory | Out-Null
        New-Item "$path\ServiceTier\Program Files" -ItemType Directory | Out-Null
        New-Item "$path\WebClient\Microsoft Dynamics NAV" -ItemType Directory | Out-Null
        New-Item "$path\RoleTailoredClient\systemFolder" -ItemType Directory | Out-Null
        New-Item "$path\RoleTailoredClient\Program Files" -ItemType Directory | Out-Null
        New-Item "$path\ClickOnceInstallerTools\Program Files\Microsoft Dynamics NAV" -ItemType Directory | Out-Null
        New-Item "$path\WindowsPowerShellScripts\Cloud" -ItemType Directory | Out-Null
        New-Item "$path\RoleTailoredClient\CommonAppData\Microsoft\Microsoft Dynamics NAV\VER" -ItemType Directory | Out-Null
        
        Write-Host "Extracting Service Tier and WebClient Files"
        docker cp "$($containerName):\Windows\System32\NavSip.dll" "$path\ServiceTier\System64Folder"
        docker cp "$($containerName):\Program Files\Microsoft Dynamics NAV" "$path\ServiceTier\program files\Microsoft Dynamics NAV"
        Write-Host "Extracting Windows Client Files"
        docker cp "$($containerName):\Windows\SysWow64\NavSip.dll" "$path\RoleTailoredClient\systemFolder" 2>$null
        docker cp "$($containerName):\Program Files (x86)\Microsoft Dynamics NAV" "$path\RoleTailoredClient\Program Files"
        Write-Host "Extracting Configuration packages"
        docker cp "$($containerName):\ConfigurationPackages" "$path" 2>$null
        Write-Host "Extracting Test Assemblies"
        docker cp "$($containerName):\Test Assemblies" "$path" 2>$null
        Write-Host "Extracting Test Toolkit"
        docker cp "$($containerName):\TestToolKit" "$path" 2>$null
        Write-Host "Extracting Upgrade Toolkit"
        docker cp "$($containerName):\UpgradeToolKit" "$path" 2>$null
        Write-Host "Extracting Extensions"
        docker cp "$($containerName):\Extensions" "$path" 2>$null
        Write-Host "Extracting Applications"
        docker cp "$($containerName):\Applications" "$path" 2>$null
        Write-Host "Extracting Applications.$country"
        docker cp "$($containerName):\Applications.$country" "$path" 2>$null

        $sourceFolder = (Get-Item "$path\ServiceTier\Program Files\Microsoft Dynamics NAV\*\Web Client").FullName
        $destFolder = $sourceFolder.Replace('\Web Client','').Replace('ServiceTier\Program Files','WebClient')
        New-Item -Path $destFolder -ItemType Directory | Out-Null
        Move-Item -Path $sourceFolder -Destination $destFolder

        $sourceItem = Get-Item "$path\ServiceTier\Program Files\Microsoft Dynamics NAV\*\AL Development Environment"
        if ($sourceItem) {
            $sourceFolder = $SourceItem.FullName
            $destFolder = $sourceFolder.Replace('\AL Development Environment','').Replace('ServiceTier\','ModernDev\')
            New-Item -Path $destFolder -ItemType Directory | Out-Null
            Move-Item -Path $sourceFolder -Destination $destFolder
        }
        
        $sourceItem = Get-Item "$path\RoleTailoredClient\Program Files\Microsoft Dynamics NAV\*\ClickOnce Installer Tools"
        if ($sourceItem) {
            $sourceFolder = $SourceItem.FullName
            $destFolder = $sourceFolder.Replace('\ClickOnce Installer Tools','').Replace('\RoleTailoredClient\','\ClickOnceInstallerTools\')
            New-Item -Path $destFolder -ItemType Directory | Out-Null
            Move-Item -Path $sourceFolder -Destination $destFolder
        }
    }
    if ($extract -eq "all" -or $extract -eq "vsix") {
        Write-Host "Extracting Files from Run folder"
        docker cp "$($containerName):\Run" "$path"
    }
    if ($extract -eq "all" -or $extract -eq "database") {
        Write-Host "Extracting Database Files"
        docker cp "$($containerName):\databases" "$path" 2>$null
    }

    if ($extract -eq "all") {
        Write-Host "Downloading prerequisites"
        $ver = [int]((get-childitem "$path\ServiceTier\Program Files\Microsoft Dynamics NAV").Name)
        Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/C/9/E/C9E8180D-4E51-40A6-A9BF-776990D8BCA9/rewrite_amd64.msi" -destinationFile "$path\Prerequisite Components\IIS URL Rewrite Module\rewrite_2.0_rtw_x64.msi"
        Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/5/5/3/553C731E-9333-40FB-ADE3-E02DC9643B31/OpenXMLSDKV25.msi" -destinationFile "$path\Prerequisite Components\Open XML SDK 2.5 for Microsoft Office\OpenXMLSDKv25.msi" 
        if ($ver -eq 90) {
            Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/1/3/0/13089488-91FC-4E22-AD68-5BE58BD5C014/ENU/x86/SQLSysClrTypes.msi" -destinationFile "$path\Prerequisite Components\Microsoft Report Viewer 2015\SQLSysClrTypes.msi"
            Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/A/1/2/A129F694-233C-4C7C-860F-F73139CF2E01/ENU/x86/ReportViewer.msi" -destinationFile "$path\Prerequisite Components\Microsoft Report Viewer 2015\ReportViewer.msi"
        } elseif ($ver -eq 100) {
            Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/1/3/0/13089488-91FC-4E22-AD68-5BE58BD5C014/ENU/x86/SQLSysClrTypes.msi" -destinationFile "$path\Prerequisite Components\Microsoft Report Viewer\SQLSysClrTypes.msi"
            Download-File -dontOverwrite -sourceUrl "https://download.microsoft.com/download/A/1/2/A129F694-233C-4C7C-860F-F73139CF2E01/ENU/x86/ReportViewer.msi" -destinationFile "$path\Prerequisite Components\Microsoft Report Viewer\ReportViewer.msi" 
        } elseif ($ver -ge 110) {
            Download-File -dontOverwrite -sourceUrl "https://go.microsoft.com/fwlink/?LinkID=844461" -destinationFile "$path\Prerequisite Components\DotNetCore\DotNetCore.1.0.4_1.1.1-WindowsHosting.exe"
        }
    }
   
    Write-Host "Performing cleanup"
    if ($extract -eq "all" -or $extract -eq "database") {
        if (Test-Path "$path\databases\*.mdf") {
            Move-Item -Path (Get-Item "$path\databases\*.mdf").FullName -Destination "$path\databases\CRONUS.mdf"
            Move-Item -Path (Get-Item "$path\databases\*.ldf").FullName -Destination "$path\databases\CRONUS.ldf"
        } else {
            $folder = Get-ChildItem -Path "$path\databases" -Directory
            if ($folder) {
                $name = $folder.Name
                Move-Item -Path (Get-Item "$path\databases\$Name\*.mdf").FullName -Destination "$path\databases\$name.mdf"
                Move-Item -Path (Get-Item "$path\databases\$Name\*.ldf").FullName -Destination "$path\databases\$name.ldf"
                Remove-Item $folder.FullName -Recurse -Force
            } else {
                docker cp "$($containerName):\Program Files\Microsoft SQL Server\MSSQL13.SQLEXPRESS\MSSQL\DATA" "$path" 2>null
                docker cp "$($containerName):\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\DATA" "$path" 2>null
                $mdffile = Get-Item "$path\DATA\Financials*.mdf"
                if ($mdffile) {
                    $name = $mdffile.Name.SubString(0,$mdffile.Name.IndexOf('_'))
                    Move-Item -Path (Get-Item "$path\DATA\Financials*.mdf").FullName -Destination "$path\databases\$name.mdf"
                    Move-Item -Path (Get-Item "$path\DATA\Financials*.ldf").FullName -Destination "$path\databases\$name.ldf"
                    Remove-Item -path "$path\DATA" -Recurse -Force
                } else {
                    throw "Cannot locate database"
                }
            }
        }
        if (Test-Path "$path\Run\Collation.txt") {
            Move-Item -Path "$path\Run\Collation.txt" -Destination "$path\databases\Collation.txt"
        }
    }
    
    if ($extract -eq "all") {
        Copy-Item -Path "$path\Run\NAVAdministration" -Destination "$path\WindowsPowerShellScripts\Cloud" -Force -Recurse
        if (Test-Path "$path\Run\WebSearch") {
            Copy-Item -Path "$path\Run\WebSearch" -Destination "$path\WindowsPowerShellScripts\Cloud" -Force -Recurse
        }

        if ($ver -lt 150) {
            Copy-Item -Path "$path\Run\ClientUserSettings.config" -Destination "$path\RoleTailoredClient\CommonAppData\Microsoft\Microsoft Dynamics NAV\VER" -Force
        }
        If (Test-Path "$path\Run\inetpub") {
            Copy-Item -Path "$path\Run\inetpub" -Destination "$path\WebClient" -Force -Recurse
        }
    }
    if ($extract -eq "all" -or $extract -eq "vsix") {
        Copy-Item -Path "$path\Run\*.vsix" -Destination "$path" -Force
        Remove-Item -Path "$path\Run" -Recurse -Force
    }
    
    $ErrorActionPreference = 'Stop'

    if ($startContainer) {
        Start-NavContainer -containerName $containerName
    }
}
Set-Alias -Name Extract-FilesFromStoppedBCContainer -Value Extract-FilesFromStoppedNavContainer
Export-ModuleMember -Function Extract-FilesFromStoppedNavContainer -Alias Extract-FilesFromStoppedBCContainer