Containers/New-Container.ps1

<#
 .Synopsis
  Creates a new NAV/BC container
 .Description
  Creates a new NAV/BC container
 .Parameter ContainerName
  Name of the container. Can be provided in the settings.json
 .Parameter ImageName
  Not used anymore. Kept for backwards capability
 .Parameter LicenseFile
  Path to license file. It can be an Uri and then the license will be downloaded
 .Parameter Credential
  Credentials to be used for login to the container. Can be provided in settings.json
 .Parameter Country
  Country version of the container. Can be provided in settings.json
 .Parameter alwaysPull
  Always pull latest version of the docker image
 .Parameter SetupTestUsers
  Creates test users in the container after it is created
 .Parameter SkipTestTool
  Add this switch if you do not want to install the test tool
  .Parameter includeCSide
  Include this switch if you want to have Windows Client and CSide development environment available on the host. This switch will also export all objects as txt for object handling functions unless doNotExportObjectsAsText is set.
  .Parameter skipBackup
  Add this switch if you do not want to use database backups from previous containers
  .Parameter useHyperVIsolation
  Add this switch if you want to force Hyper V isolation when creating the container
  .Parameter includeClickOnce
  Specify the clickonce switch if you want to have a clickonce version of the Windows Client created
  .Parameter enableTaskScheduler
  Include this switch if you want to do Enable the Task Scheduler
  .Parameter isLocal
  Specify this switch, if you want to use a larger memory limit
  .Example
  New-Container -SetupTestUsers
#>

function New-Container {
    [CmdletBinding(SupportsShouldProcess, ConfirmImpact="low")]
    Param(
        [Parameter(Mandatory = $false)]
        [string] $ContainerName,
        [Parameter(Mandatory = $false)]
        [string] $ImageName,
        [Parameter(Mandatory = $false)]
        [string] $LicenseFile,
        [Parameter(Mandatory = $false)]
        [pscredential] $Credential,
        [Parameter(Mandatory = $false)]
        [string] $Country = "",
        [switch] $alwaysPull,
        [switch] $SetupTestUsers,
        [switch] $SkipTestTool,
        [switch] $includeCSide,
        [switch] $skipBackup,
        [switch] $useHyperVIsolation,
        [switch] $includeClickOnce,
        [switch] $enableTaskScheduler,
        [switch] $isLocal
    )

    if ($PSCmdlet.ShouldProcess("Container", "This will create a new ")) {
        if ($null -eq $ContainerName -or $ContainerName -eq "") {
            $ContainerName = (Get-EnvironmentKeyValue -KeyName 'name')
        }

        if ($null -eq $Credential) {
            $NewCredential = Get-CredentialFromEnvironmentJson
            if ($NewCredential -eq $false) {
                $Password = (ConvertTo-SecureString "Password" -AsPlainText -Force)
                $Credential = [PSCredential]::new('admin', $Password)
            }
            else {
                $Credential = $NewCredential
                $Password = (ConvertTo-SecureString (Get-EnvironmentKeyValue -KeyName "password") -AsPlainText -Force)
            }
        }
        else {
            $Password = $Credential.Password
        }

        $ImageName = Get-EnvironmentKeyValue -KeyName "version"

        $target = Get-AppKeyValue -KeyName "Target"
        if ($target -eq "Cloud" -or $target -eq "Extension") {
            $EnvironmentType = "Sandbox"
        }
        else {
            $EnvironmentType = "OnPrem"
        }

        if ($Country -eq "") {
            $Country = Get-EnvironmentKeyValue -KeyName "locale"
        }
        $dockerImageName = "navx"
        if ($ImageName -in @("2016","2017","2018")) {
            $cu = Get-EnvironmentKeyValue -KeyName "cu"
            $artifactUrl = Get-NavArtifactUrl -nav $imageName -cu $cu -select Latest -country $Country
            $dockerImageName = "${dockerImageName}:$imageName-$cu-$country"
            Write-Output "Using Version $ImageName Cumulative Update $cu Country $Country"
        }
        else {
            $artifactUrl = Get-BCArtifactUrl -version $ImageName -select Latest -country $Country -Type $EnvironmentType
            $dockerImageName = "${dockerImageName}:$ImageName-$country-$EnvironmentType"
            Write-Output "Using Version $ImageName Country $Country"
        }
        Write-Output "Using Artifact Url $artifactUrl"
        Write-Output "Using Image $dockerImageName"

        [version]$platform = Get-AppKeyValue -KeyName "platform"
        if ($platform.Major -lt 15) {
            $skipBackup = $true
        }
        #disable using backup, since this is currently possibly causing issues as well
        $skipBackup = $true

        if (!$skipBackup.IsPresent) {
            if (!(Test-Path "C:\.backups")) {
                New-Item -Path "C:\.backups" -ItemType Directory | Out-Null
            }

            if ($Country -eq "") {
                $Country = Get-EnvironmentKeyValue -KeyName "locale"
            }

            $bakFolder = (Join-Path "C:\.backups" $platform)
            $bakFolder = (Join-Path $bakFolder $Country)

            if (Test-Path (Join-Path $bakFolder "*")) {
                Write-Output "Using backups to create container"
            }
        }
        else {
            Write-Output "Not using backups to create container"
        }

        $startParameters = @{
            containerName = $ContainerName
            Credential    = $Credential
            artifactUrl   = $artifactUrl
            imageName     = $dockerImageName
            licenseFile   = $LicenseFile
        }

        if ($useHyperVIsolation.IsPresent) {
            $startParameters.Add('isolation', 'HyperV')
        }

        if (Get-EnvironmentKeyValue -KeyName "usePremium") {
            $startParameters.Add('assignPremiumPlan', $true)
        }
        if ($platform.Major -gt 13) {
            $startParameters.Add('includeAL', $true)
        }
        if (!($SkipTestTool.IsPresent)) {
            if ($platform.Major -gt 11) {
                $startParameters.Add('includeTestToolkit', $true)
            }
        }

        if ($isLocal.IsPresent) {
            $startParameters.Add('memoryLimit', '16GB')
        }
        else {
            $startParameters.Add('memoryLimit', '8GB')
        }

        if ($platform.Major -le 14) {
            $startParameters.Add('shortcuts', 'DesktopFolder')
        }
        else {
            $startParameters.Add('shortcuts', 'None')
            $startParameters.Add('enableSymbolLoading', $false)
        }
        if ($platform.Major -eq 11)
        {
            $startParameters.Add('enableSymbolLoading', $true)
        }

        if ($alwaysPull.IsPresent) {
            $startParameters.Add('alwaysPull', $true)
        }

        if ($includeCSide.IsPresent -or $includeClickOnce.IsPresent) {
            $startParameters.Add('includeCSide', $true)
            $startParameters.Add('clickonce', $true)
        }

        if (!$skipBackup.IsPresent) {
            $startParameters.Add('bakFolder', $bakFolder)
            $startParameters.Add('additionalParameters', @("-v C:\.backups:C:\.backups"))
        }

        if ($enableTaskScheduler.IsPresent) {
            $startParameters.Add('enableTaskScheduler', $true)
        }
        else {
            $startParameters.Add('enableTaskScheduler', $false)
        }

        Flush-ContainerHelperCache -cache bcartifacts -keepDays 7

        if ($SetupTestUsers.IsPresent) {
            New-NavContainer -accept_eula -accept_outdated -auth NavUserPassword -updateHosts -useBestContainerOS -doNotExportObjectsToText `
                -finalizeDatabasesScriptBlock {
                Setup-NavContainerTestUsers -containerName $ContainerName -password $Password -credential $Credential
            } `
                @startParameters
        }
        else {
            New-NavContainer -accept_eula -accept_outdated -auth NavUserPassword -updateHosts -useBestContainerOS -doNotExportObjectsToText @startParameters
        }

        $customLicenseFile = Get-FileFromStorage -fileName $LicenseFile
        Write-Output "Importing Custom License"
        Import-NavContainerLicense -containerName $ContainerName -licenseFile $customLicenseFile -restart

        if ($platform.Major -le 11) {
            Write-Output "Updating Add-Ins for RoleTailored Client"
            $session = Get-NavContainerSession -containerName $ContainerName
            Invoke-Command -ScriptBlock {
                $sharedPath = "C:\navpfiles\" + $args[0] + "0\RoleTailored Client\"
                $programPath = "C:\Program Files (x86)\Microsoft Dynamics NAV\" + $args[0] + "0\RoleTailored Client\"

                Write-Output "Copying add-in files to shared files"
                Copy-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service\Add-Ins\" $sharedPath -recurse -Force
                Write-Output "Copying add-in files to program files"
                Copy-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service\Add-Ins\" $programPath -Recurse -Force
            } -Session $session -ArgumentList $platform.Major
        }

        if (!($SkipTestTool.IsPresent))
        {
            if ($platform.Major -eq 11)
            {
                Import-Testing -containerName $ContainerName
            }
        }
    }
}
Export-ModuleMember New-Container