Containers/New-ContainerForNavxProduct.ps1

<#
 .Synopsis
  Creates a new NAV/BC container for a specific NAV-X Product
 .Description
  Creates a new NAV/BC container for a specific NAV-X Product
 .Parameter ContainerName
  Name of the container. Can be provided in the settings.json
 .Parameter Product
  The product that should be installed in the container
 .Parameter ProductVersion
  The version for the product that should be installed. If left empty, it will be the latest version
 .Parameter Version
  The NAV/BC version (NAV 2018 and higher). If it's BC, the version is defined in Major.Minor
 .Parameter ClientName
  The name of the client that should be used when creating a container for client development.
 .Parameter cu
  The cumulative update to be used, only when it's NAV 2018. If any cumulative update other than 6 is used, an object merge might be required as the products are developed on this cumulative udpate
 .Parameter Type
  OnPrem or Sandbox. Default is OnPrem
 .Parameter LicenseFile
  Path to license file. It can be an Uri and then the license will be downloaded. If left blank, the standard NAV-X license will be used
 .Parameter Credential
  Credentials to be used for login to the container. If blank, a standard login will be setup
 .Parameter Country
  Country version of the container. If left blank, "us" will be used
 .Parameter SetupTestUsers
  Creates test users in the container after it is created
 .Parameter useHyperVIsolation
  Add this switch if you want to force Hyper V isolation when creating the container
 .Parameter useDevEndpoint
  Defines that the extensions are going to be installed via the developer endpoint to allow development on the apps
 .Parameter disableHttps
  Defines whether to use SSL to connect to the client
 .Example
  New-ContainerForNavxProduct -Product CommissionManagement -Version 18.0
#>

function New-ContainerForNavxProduct {
    [CmdletBinding(SupportsShouldProcess,
        ConfirmImpact="low",
        DefaultParameterSetName = "Product")]
    Param(
        [Parameter(Mandatory = $false)]
        [string] $ContainerName,
        [Parameter(Mandatory = $true,
            ParameterSetName = "Product")]
        [ValidateSet('Allocations','Base','CommissionManagement','CreditCard','CreditManagement','NationalAccounts','PayAssist','Search')]
        [string] $Product,
        [Parameter(Mandatory = $false,
            ParameterSetName = "Product")]
        [string] $productVersion = "latest",
        [Parameter(Mandatory = $false,
            ParameterSetName = "Product")]
        [string] $Version = "latest",
        [Parameter(Mandatory = $true,
            ParameterSetName = "Client")]
        [string] $ClientName,
        [Parameter(Mandatory = $false)]
        [string] $cu = "",
        [Parameter(Mandatory = $false)]
        [ValidateSet('OnPrem','Sandbox')]
        [string] $Type = "Sandbox",
        [Parameter(Mandatory = $false)]
        [string] $LicenseFile = "",
        [Parameter(Mandatory = $false)]
        [pscredential] $Credential,
        [Parameter(Mandatory = $false)]
        [string] $Country = "",
        [switch] $SetupTestUsers,
        [switch] $useHyperVIsolation,
        [switch] $useDevEndpoint,
        [switch] $disableHttps
    )

    Write-Output @'
     ____ ____ _
    | _ \ _ __ ___ _ __ __ _ _ __ ___ | _ \ __ _ _ __ __ _ _ __ ___ ___| |_ ___ _ __ ___
    | |_) | '__/ _ \ '_ \ / _` | '__/ _ \ | |_) / _` | '__/ _` | '_ ` _ \ / _ \ __/ _ \ '__/ __|
    | __/| | | __/ |_) | (_| | | | __/ | __/ (_| | | | (_| | | | | | | __/ || __/ | \__ \
    |_| |_| \___| .__/ \__,_|_| \___| |_| \__,_|_| \__,_|_| |_| |_|\___|\__\___|_| |___/
                   |_|

'@


    $os = (Get-CimInstance Win32_OperatingSystem)
    $isServerHost = $os.ProductType -eq 3
    $useSSL = !$disableHttps.IsPresent

    if (!$useHyperVIsolation.IsPresent -and !$isServerHost -and $os.BuildNumber -eq 22621 -and $useSSL) {
        Write-Output "Disabling SSL due to a bug in Windows 11"
        $useSSL = $false
    }

    if ($ClientName -ne "") {
        if ($ContainerName -eq "") {
            if ($ClientName.Length -gt 13) {
                $ContainerName = $ClientName.Substring(0,13) + "bc"
            }
            else {
                $ContainerName = $ClientName + "bc"
            }
        }
        $devOpsArtifact = $ClientName.ToLower()
    }
    else {
        $ContainerName = Get-ContainerFromProduct -Product $Product
        $devOpsArtifact = Get-RepoFromProduct -Product $Product
    }

    if ($null -eq $Credential) {
        $Credential = New-Object System.Management.Automation.PSCredential('admin', (ConvertTo-SecureString 'Cfbs!#00' -AsPlainText -Force))
    }

    $artifactUrl = ""
    $imageName = ""
    Write-Output "Getting the right version"
    $ArtifactUrl = Get-ProperArtifactUrl -Version ([ref]$Version) -Cu $CU -Country ([ref]$country) -ArtifactUrl $ArtifactUrl -target ([ref]$Type) -imageName ([ref]$imageName)

    if ($artifactUrl -eq "") {
        throw "Could not find the proper version to install"
    }

    $versionInt = 0
    try {
        $versionInt = [decimal]("{0}.{1}" -f ([version]$version).Major, ([version]$Version).Minor)
    }
    catch {
        $versionInt = 0
    }

    if ($productVersion -eq "") {
        $productVersion = "latest"
    }

    if ($LicenseFile -eq "") {
        switch ($Product) {
            'PayAssist' {
                $LicenseFile = Get-LicenseFile -Publisher "DTX" -Version $versionInt
                break
            }
            default {
                $LicenseFile = Get-LicenseFile -Publisher "NAV-X" -Version $versionInt
                break
            }
        }
    }

    Write-Output "Container: $ContainerName"
    Write-Output "Image: $imagename"

    if ($null -ne $Product) {
        Write-Output "Product: $Product"
        Write-Output "Product Version: $productVersion"
    }
    if ($null -ne $ClientName) {
        Write-Output "Client Name: $ClientName"
    }

    Write-Output "Version: $Version"
    if ($versionInt -eq 2018) {
        Write-Output "Cumulative Update: $cu"
    }
    Write-Output "Country: $Country"
    if ($versionInt -ne 2018) {
        Write-Output "Type: $Type"
    }
    Write-Output "username: $($Credential.UserName)"
    Write-Output "password: $($Credential.GetNetworkCredential().Password)"

    $startParameters = @{}
    $startParameters.Add('imageName', $imagename)
    $startParameters.Add('artifactUrl', $artifactUrl)
    if ($LicenseFile -ne "") {
        $startParameters.Add('licenseFile', $LicenseFile)
    }
    if ($useHyperVIsolation.IsPresent) {
        $startParameters.Add('isolation', 'hyperv')
    }
    if ($versionInt -eq 14 -or $versionInt -eq 2018) {
        $startParameters.Add('shortcuts', 'DesktopFolder')
        $startParameters.Add('includeCSide', $true)
        $startParameters.Add('enableSymbolLoading', $true)
        $startParameters.Add('doNotExportObjectsToText', $true)
        $startParameters.Add('clickonce', $true)
    }
    else {
        $startParameters.Add('enableTaskScheduler', $true)
    }
    $startParameters.Add('updateHosts', $true)
    $startParameters.Add('alwaysPull', $true)
    $startParameters.Add('useBestContainerOS', $true)
    $startParameters.Add('auth', 'NavUserPassword')
    $startParameters.Add('dns', '8.8.8.8')
    $startParameters.Add('accept_eula', $true)
    $startParameters.Add('accept_outdated', $true)
    $startParameters.Add('containerName', $ContainerName)
    $startParameters.Add('Credential', $Credential)

    if ($useSSL) {
        $startParameters.Add("useSSL", $true)
    }

    # defines that it's a local container, so the memory will be set to a higher amount for performance reasons
    if ($PSCmdlet.ShouldProcess("Container", "This will create a new ")) {
        Write-Output @'

         ____ _ _ ____ _ _
        / ___|_ __ ___ __ _| |_(_)_ __ __ _ / ___|___ _ __ | |_ __ _(_)_ __ ___ _ __
       | | | '__/ _ \/ _` | __| | '_ \ / _` | | | / _ \| '_ \| __/ _` | | '_ \ / _ \ '__|
       | |___| | | __/ (_| | |_| | | | | (_| | | |__| (_) | | | | || (_| | | | | | __/ |
        \____|_| \___|\__,_|\__|_|_| |_|\__, | \____\___/|_| |_|\__\__,_|_|_| |_|\___|_|
                                         |___/
'@

        @($startParameters.Keys) | ForEach-Object {
            if ($_ -ne "Credential") {
                Write-Output "$($_): $($startParameters[$_])"
            }
        }

        New-BcContainer @startParameters
    }

    # waiting for container to be operational
    Wait-ForTenantReady -containerName $ContainerName -Tenant default

    if ($SetupTestUsers.IsPresent) {
        Setup-BcContainerTestUsers -containerName $ContainerName -tenant default -Password (ConvertTo-SecureString ($Credential.GetNetworkCredential().Password) -credential $Credential)
    }

    if ($versionInt -ge 2018) {
        Write-Output "Installing objects for Dynamics NAV versions of the products is not supported anymore as the objects are not available in GitHub."
        Write-Output "Please gather the objects manually and install them using the Import-ObjectsToNavContainer function."
    }
    else {
        $appsDirectory = New-TempDirectory
        if ($null -ne $Product) {
            Get-AndInstallApp -Repository $devOpsArtifact -Version $productVersion -useDevEndpoint:$useDevEndpoint -Credential $credential -appFolder $appsDirectory -isClientRepo:($ClientName -ne "")
        }
        else {
            Get-AndInstallApp -Repository $devOpsArtifact -useDevEndpoint:$useDevEndpoint -Credential $credential -appFolder $appsDirectory -isClientRepo:($ClientName -ne "")
        }

        Remove-Item -Path $appsDirectory -Recurse -Force
    }

    Write-Output @'
    ____
    | _ \ ___ _ __ ___
    | | | |/ _ \| '_ \ / _ \
    | |_| | (_) | | | | __/
    |____/ \___/|_| |_|\___|

'@

}
Export-ModuleMember New-ContainerForNavxProduct