689 строки
32 KiB
PowerShell
689 строки
32 KiB
PowerShell
if (!(Test-Path function:AddToStatus)) {
|
|
function AddToStatus([string]$line, [string]$color = "Gray") {
|
|
("<font color=""$color"">" + [DateTime]::Now.ToString([System.Globalization.DateTimeFormatInfo]::CurrentInfo.ShortTimePattern.replace(":mm",":mm:ss")) + " $line</font>") | Add-Content -Path "c:\demo\status.txt" -Force -ErrorAction SilentlyContinue
|
|
Write-Host -ForegroundColor $color $line
|
|
}
|
|
}
|
|
|
|
if (Test-Path -Path "C:\demo\*\BcContainerHelper.psm1") {
|
|
$module = Get-Item -Path "C:\demo\*\BcContainerHelper.psm1"
|
|
Import-module $module.FullName -DisableNameChecking
|
|
} else {
|
|
Import-Module -name bccontainerhelper -DisableNameChecking
|
|
}
|
|
|
|
$settingsScript = Join-Path $PSScriptRoot "settings.ps1"
|
|
|
|
. "$settingsScript"
|
|
|
|
if ($artifactUrl) {
|
|
|
|
if ($artifactUrl -notlike "https://*") {
|
|
$segments = "$artifactUrl/////".Split('/')
|
|
$params = @{
|
|
"storageAccount" = $segments[0]
|
|
"type" = $segments[1]
|
|
"version" = $segments[2]
|
|
"country" = $segments[3]
|
|
"select" = $segments[4]
|
|
"sasToken" = $segments[5]
|
|
}
|
|
if ($AcceptInsiderEula -eq "Yes") {
|
|
$params += @{ "accept_insiderEula" = $true }
|
|
}
|
|
$artifactUrl = Get-BCArtifactUrl @Params | Select-Object -First 1
|
|
}
|
|
|
|
$artifactPaths = Download-Artifacts -artifactUrl $artifactUrl -includePlatform
|
|
$appArtifactPath = $artifactPaths[0]
|
|
$platformArtifactPath = $artifactPaths[1]
|
|
|
|
$appManifestPath = Join-Path $appArtifactPath "manifest.json"
|
|
$appManifest = Get-Content $appManifestPath | ConvertFrom-Json
|
|
|
|
$nav = ""
|
|
if ($appManifest.PSObject.Properties.name -eq "Nav") {
|
|
$nav = $appManifest.Nav
|
|
}
|
|
|
|
$cu = ""
|
|
if ($appManifest.PSObject.Properties.name -eq "Cu") {
|
|
$cu =$appManifest.Cu
|
|
}
|
|
|
|
$navVersion = $appmanifest.Version
|
|
$country = $appManifest.Country.ToLowerInvariant()
|
|
$locale = Get-LocaleFromCountry $country
|
|
|
|
$Params = @{
|
|
"artifactUrl" = $artifactUrl
|
|
}
|
|
}
|
|
elseif ($navDockerImage) {
|
|
$imageName = Get-BestNavContainerImageName -imageName ($navDockerImage.Split(',')[0])
|
|
docker ps --filter name=$containerName -a -q | % {
|
|
AddToStatus "Removing container $containerName"
|
|
docker rm $_ -f | Out-Null
|
|
}
|
|
|
|
$exist = $false
|
|
docker images -q --no-trunc | ForEach-Object {
|
|
$inspect = docker inspect $_ | ConvertFrom-Json
|
|
if ($inspect | % { $_.RepoTags | Where-Object { "$_" -eq "$imageName" -or "$_" -eq "${imageName}:latest"} } ) { $exist = $true }
|
|
}
|
|
if (!$exist) {
|
|
AddToStatus "Pulling $imageName (this might take ~30 minutes)"
|
|
docker pull $imageName
|
|
}
|
|
|
|
$inspect = docker inspect $imageName | ConvertFrom-Json
|
|
$country = $inspect.Config.Labels.country
|
|
$navVersion = $inspect.Config.Labels.version
|
|
$nav = $inspect.Config.Labels.nav
|
|
$cu = $inspect.Config.Labels.cu
|
|
$locale = Get-LocaleFromCountry $country
|
|
|
|
$Params = @{ "imageName" = $imageName }
|
|
}
|
|
else {
|
|
# no artifact, no container - exit
|
|
exit
|
|
}
|
|
|
|
if ($AcceptInsiderEula -eq "Yes") {
|
|
$params += @{ "accept_insiderEula" = $true }
|
|
}
|
|
|
|
if ($Office365Password -eq "" -or (!$Office365UserName.contains('@'))) {
|
|
$auth = "NavUserPassword"
|
|
if (Test-Path "c:\myfolder\SetupConfiguration.ps1") {
|
|
Remove-Item -Path "c:\myfolder\SetupConfiguration.ps1" -Force
|
|
}
|
|
}
|
|
else {
|
|
$auth = "AAD"
|
|
|
|
$secureOffice365Password = ConvertTo-SecureString -String $Office365Password -Key $passwordKey
|
|
$Office365Credential = New-Object System.Management.Automation.PSCredential($Office365UserName, $secureOffice365Password)
|
|
$aadDomain = $Office365UserName.split('@')[1]
|
|
$appIdUri = "https://$($publicDnsName.Split('.')[0]).$($publicDnsName.Split('.')[1]).$aadDomain/BC"
|
|
|
|
if (Test-Path "c:\myfolder\SetupConfiguration.ps1") {
|
|
AddToStatus "Reusing existing Aad Apps for Office 365 integration"
|
|
|
|
$params += @{
|
|
"AadTenant" = $aadTenantId
|
|
"AadAppId" = $SsoAdAppId
|
|
"AadAppIdUri" = $appIdUri
|
|
}
|
|
}
|
|
else {
|
|
AddToStatus "Creating Aad Apps for Office 365 integration"
|
|
if (([System.Version]$navVersion).Major -ge 15) {
|
|
if ($AddTraefik -eq "Yes") {
|
|
$publicWebBaseUrl = "https://$publicDnsName/$("$containerName".ToUpperInvariant())/"
|
|
}
|
|
else {
|
|
$publicWebBaseUrl = "https://$publicDnsName/BC/"
|
|
}
|
|
}
|
|
else {
|
|
$publicWebBaseUrl = "https://$publicDnsName/NAV/"
|
|
}
|
|
|
|
@"
|
|
`$appIdUri = '$appIdUri'
|
|
. 'c:\run\SetupConfiguration.ps1'
|
|
"@ | Set-Content "c:\myfolder\SetupConfiguration.ps1"
|
|
|
|
try {
|
|
$authContext = New-BcAuthContext -tenantID $aadDomain -credential $Office365Credential -scopes "https://graph.microsoft.com/.default"
|
|
if (-not $authContext) {
|
|
$authContext = New-BcAuthContext -includeDeviceLogin -scopes "https://graph.microsoft.com/.default" -deviceLoginTimeout ([TimeSpan]::FromSeconds(0))
|
|
AddToStatus $authContext.message
|
|
$authContext = New-BcAuthContext -deviceCode $authContext.deviceCode -deviceLoginTimeout ([TimeSpan]::FromMinutes(30))
|
|
if (-not $authContext) {
|
|
throw "Failed to authenticate with Office 365"
|
|
}
|
|
}
|
|
$AdProperties = New-AadAppsForBC `
|
|
-bcAuthContext $authContext `
|
|
-appIdUri $appIdUri `
|
|
-publicWebBaseUrl $publicWebBaseUrl `
|
|
-IncludeExcelAadApp `
|
|
-IncludeApiAccess `
|
|
-IncludeOtherServicesAadApp `
|
|
-preAuthorizePowerShell
|
|
|
|
$aadTenantId = $authContext.tenantID
|
|
$SsoAdAppId = $AdProperties.SsoAdAppId
|
|
$SsoAdAppKeyValue = $AdProperties.SsoAdAppKeyValue
|
|
$ExcelAdAppId = $AdProperties.ExcelAdAppId
|
|
$ExcelAdAppKeyValue = $AdProperties.ExcelAdAppKeyValue
|
|
$OtherServicesAdAppId = $AdProperties.OtherServicesAdAppId
|
|
$OtherServicesAdAppKeyValue = $AdProperties.OtherServicesAdAppKeyValue
|
|
$ApiAdAppId = $AdProperties.ApiAdAppId
|
|
$ApiAdAppKeyValue = $AdProperties.ApiAdAppKeyValue
|
|
|
|
@"
|
|
Set-NAVServerConfiguration -ServerInstance `$serverInstance -KeyName 'ExcelAddInAzureActiveDirectoryClientId' -KeyValue '$ExcelAdAppId' -WarningAction Ignore
|
|
"@ | Add-Content "c:\myfolder\SetupConfiguration.ps1"
|
|
|
|
$settings = Get-Content -path $settingsScript | Where-Object {
|
|
$_ -notlike '$SsoAdAppId = *' -and
|
|
$_ -notlike '$SsoAdAppKeyValue = *' -and
|
|
$_ -notlike '$ExcelAdAppId = *' -and
|
|
$_ -notlike '$ExcelAdAppKeyValue = *' -and
|
|
$_ -notlike '$ApiAdAppId = *' -and
|
|
$_ -notlike '$ApiAdAppKeyValue = *' -and
|
|
$_ -notlike '$OtherServicesAdAppId = *' -and
|
|
$_ -notlike '$OtherServicesAdAppKeyValue = *' -and
|
|
$_ -notlike '$aadTenantId = *' }
|
|
|
|
$settings += "`$aadTenantId = '$aadTenantId'"
|
|
$settings += "`$SsoAdAppId = '$SsoAdAppId'"
|
|
$settings += "`$SsoAdAppKeyValue = '$SsoAdAppKeyValue'"
|
|
$settings += "`$ExcelAdAppId = '$ExcelAdAppId'"
|
|
$settings += "`$ExcelAdAppKeyValue = '$ExcelAdAppKeyValue'"
|
|
$settings += "`$OtherServicesAdAppId = '$OtherServicesAdAppId'"
|
|
$settings += "`$OtherServicesAdAppKeyValue = '$OtherServicesAdAppKeyValue'"
|
|
$settings += "`$ApiAdAppId = '$ApiAdAppId'"
|
|
$settings += "`$ApiAdAppKeyValue = '$ApiAdAppKeyValue'"
|
|
|
|
Set-Content -Path $settingsScript -Value $settings
|
|
|
|
$params += @{
|
|
"AadTenant" = $aadTenantId
|
|
"AadAppId" = $SsoAdAppId
|
|
"AadAppIdUri" = $appIdUri
|
|
}
|
|
|
|
} catch {
|
|
AddToStatus -color Red $_.Exception.Message
|
|
AddToStatus -color Red "Reverting to NavUserPassword authentication"
|
|
$auth = "NavUserPassword"
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($nav -eq "2016" -or $nav -eq "2017" -or $nav -eq "2018") {
|
|
$title = "Dynamics NAV $nav Demonstration Environment"
|
|
} elseif ($nav -eq "main") {
|
|
$title = "Dynamics 365 Business Central Preview Environment"
|
|
} else {
|
|
$title = "Dynamics 365 Business Central Sandbox Environment"
|
|
}
|
|
|
|
if ($artifactUrl) {
|
|
AddToStatus "Using artifactUrl $($artifactUrl.Split('?')[0])"
|
|
}
|
|
else {
|
|
AddToStatus "Using image $imageName"
|
|
}
|
|
AddToStatus "Country $country"
|
|
AddToStatus "Version $navVersion"
|
|
AddToStatus "Locale $locale"
|
|
|
|
$securePassword = ConvertTo-SecureString -String $adminPassword -Key $passwordKey
|
|
$credential = New-Object System.Management.Automation.PSCredential($navAdminUsername, $securePassword)
|
|
$azureSqlCredential = New-Object System.Management.Automation.PSCredential($azureSqlAdminUsername, $securePassword)
|
|
$params += @{
|
|
"licensefile" = "$licensefileuri"
|
|
"publicDnsName" = $publicDnsName
|
|
"imageName" = "mybc:$navVersion-$country".ToLowerInvariant()
|
|
}
|
|
|
|
if ($AddTraefik -eq "Yes") {
|
|
$params += @{ "useTraefik" = $true }
|
|
}
|
|
else {
|
|
$params.Add("publishPorts", @(8080,443,7046,7047,7048,7049))
|
|
}
|
|
|
|
$additionalParameters = @("--env RemovePasswordKeyFile=N",
|
|
"--storage-opt size=100GB")
|
|
|
|
if ("$appBacpacUri" -ne "") {
|
|
if ("$sqlServerType" -eq "SQLExpress") {
|
|
$additionalParameters += @("--env appbacpac=$appBacpacUri",
|
|
"--env tenantbacpac=$tenantBacpacUri")
|
|
$params += @{ "timeout" = 7200 }
|
|
}
|
|
elseif ("$sqlServerType" -eq "SQLDeveloper") {
|
|
throw "bacpacs not yet supported with SQLDeveloper"
|
|
}
|
|
else {
|
|
AddToStatus "using $azureSqlServer as database server"
|
|
$params += @{ "databaseServer" = "$azureSqlServer"
|
|
"databaseInstance" = ""
|
|
"databaseName" = "App"
|
|
"databaseCredential" = $azureSqlCredential }
|
|
if ($tenantBacpacUri -ne "") {
|
|
$multitenant = "Yes"
|
|
}
|
|
}
|
|
}
|
|
elseif ("$sqlServerType" -eq "SQLDeveloper") {
|
|
|
|
$DatabaseFolder = "c:\databases"
|
|
$DatabaseName = $containerName
|
|
$dbcredentials = New-Object PSCredential -ArgumentList 'sa', $securePassword
|
|
|
|
if (!(Test-Path $DatabaseFolder)) {
|
|
New-Item $DatabaseFolder -ItemType Directory | Out-Null
|
|
}
|
|
|
|
if (Test-Path (Join-Path $DatabaseFolder "$($DatabaseName).*")) {
|
|
|
|
Remove-BCContainer $containerName
|
|
|
|
AddToStatus "Dropping database $DatabaseName from host SQL Server"
|
|
Invoke-SqlCmd -Query "ALTER DATABASE [$DatabaseName] SET OFFLINE WITH ROLLBACK IMMEDIATE"
|
|
Invoke-Sqlcmd -Query "DROP DATABASE [$DatabaseName]"
|
|
|
|
AddToStatus "Removing Database files $($databaseFolder)\$($DatabaseName).*"
|
|
Remove-Item -Path (Join-Path $DatabaseFolder "$($DatabaseName).*") -Force
|
|
}
|
|
|
|
if ($databaseBakUri) {
|
|
$dbPath = Join-Path "C:\DEMO" "$([Guid]::NewGuid().ToString()).bak"
|
|
Download-File -sourceUrl $databaseBakUri -destinationFile $dbpath
|
|
Restore-SqlDatabase -ServerInstance "localhost" -Database $DatabaseName -BackupFile $dbpath -SqlCredential $dbcredentials -AutoRelocateFile
|
|
Remove-Item $dbPath
|
|
}
|
|
else {
|
|
if ($artifactUrl) {
|
|
if (($appManifest.PSObject.Properties.name -eq 'database') -and ($appManifest.database -ne "")) {
|
|
$dbPath = Join-Path $appArtifactPath $appManifest.database
|
|
Restore-SqlDatabase -ServerInstance "localhost" -Database $DatabaseName -BackupFile $dbpath -SqlCredential $dbcredentials -AutoRelocateFile
|
|
}
|
|
else {
|
|
AddToStatus "WARNING: Application Artifact doesn't contain a database. You need to make sure that the database is restored."
|
|
}
|
|
}
|
|
else {
|
|
$imageName = Get-BestBCContainerImageName -imageName $imageName
|
|
docker pull $imageName
|
|
|
|
$dbPath = Join-Path $env:TEMP ([Guid]::NewGuid().ToString())
|
|
Extract-FilesFromBCContainerImage -imageName $imageName -extract database -path $dbPath -force
|
|
|
|
$files = @()
|
|
Get-ChildItem -Path (Join-Path $dbPath "databases") | % {
|
|
$DestinationFile = "{0}\{1}{2}" -f $databaseFolder, $DatabaseName, $_.Extension
|
|
Copy-Item -Path $_.FullName -Destination $DestinationFile -Force
|
|
$files += @("(FILENAME = N'$DestinationFile')")
|
|
}
|
|
|
|
Remove-Item -Path $dbpath -Recurse -Force
|
|
|
|
AddToStatus "Attaching files as new Database $DatabaseName on host SQL Server"
|
|
AddToStatus "CREATE DATABASE [$DatabaseName] ON $([string]::Join(", ",$Files)) FOR ATTACH"
|
|
Invoke-SqlCmd -Query "CREATE DATABASE [$DatabaseName] ON $([string]::Join(", ",$Files)) FOR ATTACH"
|
|
}
|
|
}
|
|
|
|
AddToStatus "using host as database server"
|
|
$params += @{
|
|
"databaseServer" = "host.containerhelper.internal"
|
|
"databaseInstance" = ""
|
|
"databaseName" = $databaseName
|
|
"databaseCredential" = $dbcredentials
|
|
}
|
|
}
|
|
elseif ($databaseBakUri) {
|
|
$params += @{ "bakFile" = $databaseBakUri }
|
|
}
|
|
|
|
if ("$clickonce" -eq "Yes") {
|
|
$params += @{"clickonce" = $true}
|
|
}
|
|
|
|
if ("$enableTaskScheduler" -eq "Yes") {
|
|
$additionalParameters += @("--env CustomNavSettings=EnableTaskScheduler=true")
|
|
} elseif ("$enableTaskScheduler" -eq "No") {
|
|
$additionalParameters += @("--env CustomNavSettings=EnableTaskScheduler=false")
|
|
}
|
|
|
|
if ($enableSymbolLoading -eq "Yes") {
|
|
$params += @{ "enableSymbolLoading" = $true }
|
|
}
|
|
|
|
if ($includeCSIDE -eq "Yes") {
|
|
$params += @{
|
|
"includeCSIDE" = $true
|
|
}
|
|
}
|
|
|
|
if ($includeAL -eq "Yes") {
|
|
$params += @{
|
|
"includeAL" = $true
|
|
}
|
|
}
|
|
|
|
if ($isolation -eq "Process" -or $isolation -eq "Hyperv") {
|
|
$params += @{
|
|
"isolation" = $isolation
|
|
}
|
|
}
|
|
else {
|
|
$params += @{
|
|
"useBestContainerOS" = $true
|
|
}
|
|
}
|
|
|
|
if ($includeCSIDE -eq "Yes" -or $includeAL -eq "Yes") {
|
|
$params += @{
|
|
"doNotExportObjectsToText" = $true
|
|
}
|
|
}
|
|
|
|
if ($multitenant -eq "Yes") {
|
|
$params += @{ "multitenant" = $true }
|
|
}
|
|
|
|
if ($testToolkit -ne "No") {
|
|
$params += @{ "includeTestToolkit" = $true }
|
|
if ($testToolkit -eq "Framework") {
|
|
$params += @{ "includeTestFrameworkOnly" = $true }
|
|
}
|
|
elseif ($testToolkit -eq "Libraries") {
|
|
$params += @{ "includeTestLibrariesOnly" = $true }
|
|
}
|
|
}
|
|
|
|
if ($assignPremiumPlan -eq "Yes") {
|
|
$params += @{ "assignPremiumPlan" = $true }
|
|
}
|
|
|
|
$myScripts = @()
|
|
Get-ChildItem -Path "c:\myfolder" | % { $myscripts += $_.FullName }
|
|
|
|
try {
|
|
AddToStatus "Running container (this might take some time)"
|
|
New-NavContainer -accept_eula -accept_outdated @Params `
|
|
-containerName $containerName `
|
|
-useSSL `
|
|
-updateHosts `
|
|
-auth $Auth `
|
|
-authenticationEMail $Office365UserName `
|
|
-credential $credential `
|
|
-additionalParameters $additionalParameters `
|
|
-myScripts $myscripts
|
|
|
|
} catch {
|
|
AddToStatus -color Red "Container output"
|
|
docker logs $containerName | % { AddToStatus $_ }
|
|
throw
|
|
}
|
|
|
|
if ("$sqlServerType" -eq "SQLDeveloper") {
|
|
if ($artifactUrl) {
|
|
if ($licenseFileUri) {
|
|
$licenseFilePath = "c:\demo\license.flf"
|
|
Download-File -sourceUrl $licensefileuri -destinationFile $licenseFilePath
|
|
Import-NavContainerLicense -containerName $containerName -licenseFile $licenseFilePath
|
|
}
|
|
elseif (($appManifest.PSObject.Properties.name -eq 'licenseFile') -and ($appManifest.licenseFile -ne "")) {
|
|
$licenseFilePath = Join-Path $appArtifactPath $appManifest.licenseFile
|
|
Import-NavContainerLicense -containerName $containerName -licenseFile $licenseFilePath
|
|
}
|
|
}
|
|
New-NavContainerNavUser -containerName $containerName -Credential $credential -ChangePasswordAtNextLogOn:$false -PermissionSetId SUPER
|
|
}
|
|
|
|
if ($auth -eq "AAD") {
|
|
if (([System.Version]$navVersion).Major -lt 15) {
|
|
throw "AAD authentication no longer supported for this version"
|
|
}
|
|
else {
|
|
if (([System.Version]$navVersion) -ge ([System.Version]"25.0.0.0")) {
|
|
$sourceUrl = "https://github.com/BusinessCentralApps/AzureAdAppSetup/releases/download/25.0.0/AzureAdAppSetup-main-Apps-25.0.33.0.zip"
|
|
}
|
|
elseif (([System.Version]$navVersion) -ge ([System.Version]"18.0.0.0")) {
|
|
$sourceUrl = "https://github.com/BusinessCentralApps/AzureAdAppSetup/releases/download/18.0.12/AzureAdAppSetup-Apps-18.0.12.0.zip"
|
|
}
|
|
elseif (([System.Version]$navVersion) -ge ([System.Version]"17.1.0.0")) {
|
|
$sourceUrl = "https://github.com/BusinessCentralApps/AzureAdAppSetup/releases/download/17.1.11/AzureAdAppSetup-Apps-17.1.11.0.zip"
|
|
}
|
|
elseif (([System.Version]$navVersion) -ge ([System.Version]"15.9.0.0")) {
|
|
$sourceUrl = "https://github.com/BusinessCentralApps/AzureAdAppSetup/releases/download/15.9.10/AzureAdAppSetup-Apps-15.9.10.0.zip"
|
|
}
|
|
else {
|
|
$sourceUrl = "https://github.com/BusinessCentralApps/AzureAdAppSetup/releases/download/15.0.7/AzureAdAppSetup-Apps-15.0.7.0.zip"
|
|
}
|
|
|
|
$appfile = Join-Path $env:TEMP ([System.IO.Path]::GetFileName($sourceUrl))
|
|
Download-File -sourceUrl $sourceUrl -destinationFile $appfile
|
|
Publish-NavContainerApp -containerName $containerName -appFile $appFile -skipVerification -install -sync
|
|
|
|
$companyId = Get-NavContainerApiCompanyId -containerName $containerName -tenant "default" -credential $credential
|
|
|
|
$parameters = @{
|
|
"name" = "SetupAzureAdApp"
|
|
"value" = "$OtherServicesAdAppId,$OtherServicesAdAppKeyValue"
|
|
}
|
|
Invoke-NavContainerApi -containerName $containerName -tenant "default" -credential $credential -APIPublisher "Microsoft" -APIGroup "Setup" -APIVersion "beta" -CompanyId $companyId -Method "POST" -Query "aadApps" -body $parameters | Out-Null
|
|
|
|
if (([System.Version]$navVersion) -ge ([System.Version]"18.0.0.0")) {
|
|
$parameters = @{
|
|
"name" = "SetupAadApplication"
|
|
"value" = "$ApiAdAppId,API,D365 ADMINISTRATOR:D365 FULL ACCESS"
|
|
}
|
|
Invoke-NavContainerApi -containerName $containerName -tenant "default" -credential $credential -APIPublisher "Microsoft" -APIGroup "Setup" -APIVersion "beta" -CompanyId $companyId -Method "POST" -Query "aadApps" -body $parameters | Out-Null
|
|
}
|
|
|
|
if (([System.Version]$navVersion) -ge ([System.Version]"17.1.0.0")) {
|
|
$parameters = @{
|
|
"name" = "SetupEMailAdApp"
|
|
"value" = "$OtherServicesAdAppId,$OtherServicesAdAppKeyValue,$Office365UserName"
|
|
}
|
|
Invoke-NavContainerApi -containerName $containerName -tenant "default" -credential $credential -APIPublisher "Microsoft" -APIGroup "Setup" -APIVersion "beta" -CompanyId $companyId -Method "POST" -Query "aadApps" -body $parameters | Out-Null
|
|
|
|
if ($sqlServerType -eq "SQLExpress") {
|
|
Invoke-ScriptInBCContainer -containerName $containerName -scriptblock {
|
|
$config = Get-NAVServerConfiguration -serverinstance $serverinstance -asxml
|
|
if ($config.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value -eq 'True') {
|
|
$databaseName = "default"
|
|
}
|
|
else {
|
|
$databaseName = $config.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
|
|
}
|
|
Invoke-Sqlcmd -Database $databaseName -Query "INSERT INTO [dbo].[NAV App Setting] ([App ID],[Allow HttpClient Requests]) VALUES ('e6328152-bb29-4664-9dae-3bc7eaae1fd8', 1)"
|
|
Invoke-Sqlcmd -Database $databaseName -Query "UPDATE [dbo].[Isolated Storage] SET [App Id] = 'e6328152-bb29-4664-9dae-3bc7eaae1fd8' WHERE [App Id] = '4C06EAFF-C198-4764-94A4-B695861CE379'"
|
|
}
|
|
}
|
|
else {
|
|
if ($sqlserverType -eq "SQLDeveloper") {
|
|
$databaseServerInstance = "localhost"
|
|
}
|
|
else {
|
|
$databaseServerInstance = $params.databaseServer
|
|
}
|
|
if ($params.databaseInstance) {
|
|
$databaseServerInstance += "\$($params.databaseInstance)"
|
|
}
|
|
Invoke-Sqlcmd -ServerInstance $databaseServerInstance -Database $params.databaseName -Credential $params.databaseCredential -Query "INSERT INTO [dbo].[NAV App Setting] ([App ID],[Allow HttpClient Requests]) VALUES ('e6328152-bb29-4664-9dae-3bc7eaae1fd8', 1)"
|
|
Invoke-Sqlcmd -ServerInstance $databaseServerInstance -Database $params.databaseName -Credential $params.databaseCredential -Query "UPDATE [dbo].[Isolated Storage] SET [App Id] = 'e6328152-bb29-4664-9dae-3bc7eaae1fd8' WHERE [App Id] = '4C06EAFF-C198-4764-94A4-B695861CE379'"
|
|
}
|
|
}
|
|
|
|
UnPublish-NavContainerApp -containerName $containerName -appName AzureAdAppSetup -unInstall -doNotSaveData
|
|
}
|
|
}
|
|
|
|
if ($CreateTestUsers -eq "Yes") {
|
|
if ($licenseFileUri -eq "") {
|
|
AddToStatus "Skipping creation of Test Users, as no licensefile has been specified"
|
|
}
|
|
else {
|
|
Setup-NavContainerTestUsers -containerName $containerName -tenant "default" -password $credential.Password -credential $credential
|
|
}
|
|
}
|
|
|
|
if ($CreateAadUsers -eq "Yes" -and $Office365UserName -ne "" -and $Office365Password -ne "") {
|
|
AddToStatus "Creating Aad Users"
|
|
$secureOffice365Password = ConvertTo-SecureString -String $Office365Password -Key $passwordKey
|
|
$Office365Credential = New-Object System.Management.Automation.PSCredential($Office365UserName, $secureOffice365Password)
|
|
Create-AadUsersInNavContainer -containerName $containerName -tenant "default" -AadAdminCredential $Office365Credential -permissionSetId SUPER -securePassword $securePassword
|
|
}
|
|
|
|
if ($sqlServerType -eq "AzureSQL") {
|
|
if (Test-Path "c:\demo\objects.fob" -PathType Leaf) {
|
|
AddToStatus "Importing c:\demo\objects.fob to container"
|
|
Import-ObjectsToNavContainer -containerName $containerName -objectsFile "c:\demo\objects.fob" -sqlCredential $azureSqlCredential
|
|
}
|
|
# Check for Multitenant & Included "-ErrorAction Continue" to prevent an exit
|
|
if ($multitenant -eq "Yes") {
|
|
New-NavContainerTenant -containerName $containerName -tenantId "default" -sqlCredential $azureSqlCredential -ErrorAction Continue
|
|
}
|
|
# Included "-ErrorAction Continue" to prevent an exit
|
|
New-NavContainerNavUser -containerName $containerName -tenant "default" -Credential $credential -AuthenticationEmail $Office365UserName -ChangePasswordAtNextLogOn:$false -PermissionSetId "SUPER" -ErrorAction Continue
|
|
} else {
|
|
if (Test-Path "c:\demo\objects.fob" -PathType Leaf) {
|
|
AddToStatus "Importing c:\demo\objects.fob to container"
|
|
$sqlCredential = New-Object System.Management.Automation.PSCredential ( "sa", $credential.Password )
|
|
Import-ObjectsToNavContainer -containerName $containerName -objectsFile "c:\demo\objects.fob" -sqlCredential $sqlCredential
|
|
}
|
|
}
|
|
|
|
if ("$includeappUris".Trim() -ne "") {
|
|
foreach($includeApp in "$includeAppUris".Split(',;')) {
|
|
Publish-NavContainerApp -containerName $containerName -appFile $includeApp -sync -install -skipVerification
|
|
}
|
|
}
|
|
|
|
if ("$bingmapskey" -ne "") {
|
|
|
|
$codeunitId = 0
|
|
$apiMethod = ""
|
|
switch (([System.Version]$navVersion).Major) {
|
|
9 { $appFile = "" }
|
|
10 { $appFile = "" }
|
|
11 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/11.0.0/freddyk_BingMaps_11.0.0.0.zip"; $codeunitId = 50103 }
|
|
12 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/12.0.0/freddyk_BingMaps_12.0.0.0.zip"; $codeunitId = 50103 }
|
|
13 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/12.0.0/freddyk_BingMaps_12.0.0.0.zip"; $codeunitId = 50103 }
|
|
14 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/12.0.0/freddyk_BingMaps_12.0.0.0.zip"; $codeunitId = 50103 }
|
|
15 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/15.0.0/Freddy.Kristiansen_BingMaps_15.0.zip"; $codeunitId = 70103 }
|
|
16 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/16.0.0/Freddy.Kristiansen_BingMaps_16.0.zip"; $apiMethod = "Settings" }
|
|
17 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/16.0.0/Freddy.Kristiansen_BingMaps_16.0.zip"; $apiMethod = "Settings" }
|
|
18 { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/16.0.0/Freddy.Kristiansen_BingMaps_16.0.zip"; $apiMethod = "Settings" }
|
|
default { $appFile = "https://github.com/microsoft/bcsamples-bingmaps.pte/releases/download/19.0.0/bcsamples-bingmaps.pte-main-Apps-19.0.168.0.zip"; $apiMethod = "Settings" }
|
|
}
|
|
|
|
if ($appFile -eq "") {
|
|
AddToStatus "BingMaps app is not supported for this version of NAV"
|
|
}
|
|
else {
|
|
AddToStatus "Create Web Services Key for admin user"
|
|
$webServicesKey = (Get-NavContainerNavUser -containerName $containerName -tenant "default" | Where-Object { $_.Username -eq $navAdminUsername }).WebServicesKey
|
|
if ("$webServicesKey" -eq "") {
|
|
$session = Get-NavContainerSession -containerName $containerName
|
|
Invoke-Command -Session $session -ScriptBlock { Param($navAdminUsername)
|
|
Set-NAVServerUser -ServerInstance $serverInstance -Tenant "default" -UserName $navAdminUsername -CreateWebServicesKey
|
|
} -ArgumentList $navAdminUsername
|
|
$webServicesKey = (Get-NavContainerNavUser -containerName $containerName -tenant "default" | Where-Object { $_.Username -eq $navAdminUsername }).WebServicesKey
|
|
}
|
|
|
|
AddToStatus "Installing BingMaps app from $appFile"
|
|
Publish-NavContainerApp -containerName $containerName `
|
|
-tenant "default" `
|
|
-packageType Extension `
|
|
-appFile $appFile `
|
|
-skipVerification `
|
|
-sync `
|
|
-install
|
|
|
|
if ($codeunitId) {
|
|
AddToStatus "Geocode customers, by invoking codeunit $codeunitId"
|
|
Get-CompanyInNavContainer -containerName $containerName | % {
|
|
Invoke-NavContainerCodeunit -containerName $containerName `
|
|
-tenant "default" `
|
|
-CompanyName $_.CompanyName `
|
|
-Codeunitid $codeunitId `
|
|
-MethodName "SetBingMapsSettings" `
|
|
-Argument ('{ "BingMapsKey":"' + $bingMapsKey + '","WebServicesUsername": "' + $navAdminUsername + '","WebServicesKey": "' + $webServicesKey + '"}')
|
|
}
|
|
}
|
|
elseif ($apiMethod) {
|
|
AddToStatus "Geocode customers, by invoking api method $apiMethod"
|
|
|
|
if ($sqlServerType -eq "SQLExpress") {
|
|
Invoke-ScriptInBCContainer -containerName $containerName -scriptblock {
|
|
$config = Get-NAVServerConfiguration -serverinstance $serverinstance -asxml
|
|
if ($config.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value -eq 'True') {
|
|
$databaseName = "default"
|
|
}
|
|
else {
|
|
$databaseName = $config.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
|
|
}
|
|
Invoke-Sqlcmd -Database $databaseName -Query "INSERT INTO [dbo].[NAV App Setting] ([App ID],[Allow HttpClient Requests]) VALUES ('a949d4bf-5f3c-49d8-b4be-5359d609683b', 1)"
|
|
}
|
|
}
|
|
else {
|
|
if ($sqlserverType -eq "SQLDeveloper") {
|
|
$databaseServerInstance = "localhost"
|
|
}
|
|
else {
|
|
$databaseServerInstance = $params.databaseServer
|
|
}
|
|
if ($params.databaseInstance) {
|
|
$databaseServerInstance += "\$($params.databaseInstance)"
|
|
}
|
|
Invoke-Sqlcmd -ServerInstance $databaseServerInstance -Database $params.databaseName -Credential $params.databaseCredential -Query "INSERT INTO [dbo].[NAV App Setting] ([App ID],[Allow HttpClient Requests]) VALUES ('a949d4bf-5f3c-49d8-b4be-5359d609683b', 1)"
|
|
}
|
|
|
|
$tenant = "default"
|
|
$companyId = Get-NavContainerApiCompanyId -containerName $containerName -tenant $tenant -credential $credential
|
|
|
|
$parameters = @{
|
|
"name" = "BingMapsKey"
|
|
"value" = $bingMapsKey
|
|
}
|
|
Invoke-NavContainerApi `
|
|
-containerName $containerName `
|
|
-tenant $tenant `
|
|
-credential $credential `
|
|
-APIPublisher "Microsoft" `
|
|
-APIGroup "BingMaps" `
|
|
-APIVersion "v1.0" `
|
|
-CompanyId $companyId `
|
|
-Method "POST" `
|
|
-Query $apiMethod `
|
|
-body $parameters | Out-Null
|
|
}
|
|
}
|
|
}
|
|
|
|
# Copy .vsix and Certificate to container folder
|
|
$containerFolder = "C:\ProgramData\bccontainerhelper\Extensions\$containerName"
|
|
AddToStatus "Copying .vsix and Certificate to $containerFolder"
|
|
docker exec $containerName powershell "copy-item -Path 'C:\Run\*.vsix' -Destination '$containerFolder' -force
|
|
copy-item -Path 'C:\Run\*.cer' -Destination '$containerFolder' -force
|
|
copy-item -Path 'C:\Program Files\Microsoft Dynamics NAV\*\Service\CustomSettings.config' -Destination '$containerFolder' -force
|
|
if (Test-Path 'c:\inetpub\wwwroot\http\NAV' -PathType Container) {
|
|
[System.IO.File]::WriteAllText('$containerFolder\clickonce.txt','http://${publicDnsName}:8080/NAV')
|
|
}"
|
|
[System.IO.File]::WriteAllText("$containerFolder\Version.txt",$navVersion)
|
|
[System.IO.File]::WriteAllText("$containerFolder\Cu.txt",$cu)
|
|
[System.IO.File]::WriteAllText("$containerFolder\Country.txt", $country)
|
|
[System.IO.File]::WriteAllText("$containerFolder\Title.txt",$title)
|
|
|
|
# Install Certificate on host
|
|
$certFile = Get-Item "$containerFolder\*.cer"
|
|
if ($certFile) {
|
|
$certFileName = $certFile.FullName
|
|
AddToStatus "Importing $certFileName to trusted root"
|
|
$pfx = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
|
|
$pfx.import($certFileName)
|
|
$store = new-object System.Security.Cryptography.X509Certificates.X509Store([System.Security.Cryptography.X509Certificates.StoreName]::Root,"localmachine")
|
|
$store.open("MaxAllowed")
|
|
$store.add($pfx)
|
|
$store.close()
|
|
}
|
|
|
|
AddToStatus -color Green "Container output"
|
|
docker logs $containerName | % { AddToStatus $_ }
|
|
|
|
AddToStatus -color Green "Container setup complete!"
|