Bacpac/Backup-NavContainerDatabases.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
<#
 .Synopsis
  Backup databases in a NAV/BC Container as .bak files
 .Description
  If the Container is multi-tenant, this command will create an app.bak and a number of tenant .bak files
  If the Container is single-tenant, this command will create one .bak file called database.bak.
 .Parameter containerName
  Name of the container in which you want to backup databases
 .Parameter bakFolder
  The folder to which the .bak files are exported (needs to be shared with the container)
 .Parameter tenant
  The tenant database(s) to export, only applies to multi-tenant containers. Omit to export all tenants.
 .Example
  Backup-NavContainerDatabases -containerName test
 .Example
  Backup-NavContainerDatabases -containerName test -bakfolder "c:\programdata\navcontainerhelper\extensions\test"
 .Example
  Backup-NavContainerDatabases -containerName test -tenant @("default")
#>

function Backup-NavContainerDatabases {
    Param (
        [string] $containerName = "navserver", 
        [string] $bakFolder = "",
        [string[]] $tenant
    )

    $containerFolder = Join-Path $ExtensionsFolder $containerName
    if ("$bakFolder" -eq "") {
        $bakFolder = $containerFolder
    }
    elseif (!$bakFolder.Contains('\')) {
        $navversion = Get-NavContainerNavversion -containerOrImageName $containerName
        if ((Invoke-ScriptInNavContainer -containerName $containerName -scriptblock { $env:IsBcSandbox }) -eq "Y") {
            $folderPrefix = "sandbox"
        }
        else {
            $folderPrefix = "onprem"
        }
        $bakFolder = Join-Path $containerHelperFolder "$folderPrefix-$NavVersion-bakFolders\$bakFolder"
    }
    $containerBakFolder = Get-NavContainerPath -containerName $containerName -path $bakFolder -throw

    Invoke-ScriptInNavContainer -containerName $containerName -ScriptBlock { Param($bakFolder, $tenant)
       
        function Backup {
            Param (
                [string] $serverInstance,
                [string] $database,
                [string] $bakFolder,
                [string] $bakName
            )
            $bakFile = Join-Path $bakFolder "$bakName.bak"
            if (Test-Path $bakFile) {
                Remove-Item -Path $bakFile -Force
            }
            Write-Host "Backing up $database to $bakFile"
            Backup-SqlDatabase -ServerInstance $serverInstance -database $database -BackupFile $bakFile
        }

        $customConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config"
        [xml]$customConfig = [System.IO.File]::ReadAllText($customConfigFile)
        $multitenant = ($customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value -eq "true")
        $databaseServer = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value
        $databaseInstance = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value
        $databaseName = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
        
        $databaseServerInstance = $databaseServer
        if ("$databaseInstance" -ne "") {
            $databaseServerInstance = "$databaseServer\$databaseInstance"
        }

        if (!(Test-Path $bakFolder)) {
            New-Item $bakFolder -ItemType Directory | Out-Null
        }

        if ($multitenant) {
            if (!($tenant)) {
                $tenant = @(get-navtenant $serverInstance | % { $_.Id }) + "tenant"
            }
            Backup -ServerInstance $databaseServerInstance -database $DatabaseName -bakFolder $bakFolder -bakName "app"
            $tenant | ForEach-Object {
                Backup -ServerInstance $databaseServerInstance -database $_ -bakFolder $bakFolder -bakName $_
            }
        } else {
            Backup -ServerInstance $databaseServerInstance -database $DatabaseName -bakFolder $bakFolder -bakName "database"
        }
    } -ArgumentList $containerbakFolder, $tenant
}
Set-Alias -Name Backup-BCContainerDatabases -Value Backup-NavContainerDatabases
Export-ModuleMember -Function Backup-NavContainerDatabases -Alias Backup-BCContainerDatabases