├── .dockerignore ├── .github └── workflows │ ├── BuildMissingImages.yaml │ └── MarkStale.yaml ├── .gitignore ├── CODEOWNERS ├── HOWTO.md ├── LICENSE ├── NAV Docker Image.docx ├── NAV on Docker E2E.docx ├── NAV on Docker E2E.pdf ├── NAV on Docker HOL.docx ├── NAV on Docker HOL.pdf ├── NEWGENERIC.md ├── README.md ├── SECURITY.md ├── generic ├── DOCKERFILE ├── DOCKERFILE-filesonly ├── Run │ ├── 70 │ │ ├── CheckHealth.ps1 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupNavUsers.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 71 │ │ ├── CheckHealth.ps1 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 80 │ │ ├── CheckHealth.ps1 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 90 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 100 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 110 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 130 │ │ ├── Deployment_web.config │ │ ├── NAVClientInstallation.html │ │ ├── ServiceSettings.ps1 │ │ ├── SetupClickOnce.ps1 │ │ ├── SetupClickOnceDirectory.ps1 │ │ ├── SetupWebClient.ps1 │ │ ├── navinstall.ps1 │ │ └── root_web.config │ ├── 150 │ │ ├── ServiceSettings.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 210 │ │ ├── ServiceSettings.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 240 │ │ ├── ServiceSettings.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 260 │ │ ├── ServiceSettings.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 270 │ │ ├── ServiceSettings.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 150-new │ │ ├── ServiceSettings.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── 210-new │ │ ├── ServiceSettings.ps1 │ │ ├── SetupConfiguration.ps1 │ │ ├── SetupWebClient.ps1 │ │ └── navinstall.ps1 │ ├── AdditionalOutput.ps1 │ ├── AdditionalSetup.ps1 │ ├── CheckHealth.ps1 │ ├── GetDvdArtifactPaths.ps1 │ ├── Healthcheck.ps1 │ ├── HelperFunctions.ps1 │ ├── MainLoop.ps1 │ ├── New-SelfSignedCertificateEx.ps1 │ ├── Prompt.ps1 │ ├── SQLConf.ini │ ├── SetupAddIns.ps1 │ ├── SetupCertificate.ps1 │ ├── SetupConfiguration.ps1 │ ├── SetupDatabase.ps1 │ ├── SetupFileShare.ps1 │ ├── SetupGeneric1.ps1 │ ├── SetupGeneric2.ps1 │ ├── SetupLicense.ps1 │ ├── SetupNavUsers.ps1 │ ├── SetupSqlUsers.ps1 │ ├── SetupTenant.ps1 │ ├── SetupUrls.ps1 │ ├── SetupVariables.ps1 │ ├── SetupWebConfiguration.ps1 │ ├── SetupWindowsUsers.ps1 │ ├── UpdatePowerShellExeConfig.ps1 │ ├── buildimage.ps1 │ ├── navstart.ps1 │ ├── powershell.exe.config │ ├── pscoreoverrides.ps1 │ ├── start.ps1 │ └── web.config ├── build.ps1 ├── cleanup.ps1 └── tag.txt └── override ├── SelfSignedCertificateEx └── SetupCertificate.ps1 ├── aci └── AdditionalSetup.ps1 ├── attachdb └── SetupDatabase.ps1 ├── issue2434 ├── HelperFunctions.ps1 ├── NAVWebClientManagement.psm1 ├── SetupDatabase.ps1 ├── SetupWebClient.ps1 ├── navinstall.ps1 ├── navstart.ps1 └── start.ps1 ├── issue512 └── start.ps1 ├── issue7100 └── setupWebConfiguration.ps1 └── selfsignedcertificate └── SetupCertificate.ps1 /.dockerignore: -------------------------------------------------------------------------------- 1 | *.md 2 | .git 3 | *.docx 4 | *.pdf 5 | LICENSE 6 | .gitignore 7 | build.ps1 8 | NULL 9 | -------------------------------------------------------------------------------- /.github/workflows/MarkStale.yaml: -------------------------------------------------------------------------------- 1 | name: Mark Images Stale 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | SHAsToMarkStale: 7 | description: Enter SHAs to mark stale (comma separated) 8 | type: string 9 | 10 | permissions: 11 | contents: read 12 | id-token: write 13 | 14 | defaults: 15 | run: 16 | shell: PowerShell 17 | 18 | jobs: 19 | MarkmagesStale: 20 | runs-on: [ Windows-Latest ] 21 | if: github.ref == 'refs/heads/main' 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | 26 | - name: 'Az CLI login' 27 | uses: azure/login@v2 28 | with: 29 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 30 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 31 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 32 | enable-AzPSSession: true 33 | 34 | - name: MarkStale 35 | env: 36 | digests: ${{ inputs.SHAsToMarkStale }} 37 | shell: pwsh 38 | run: | 39 | $erroractionpreference = "STOP" 40 | $digests = "$env:digests".Split(",").Trim() | Select-Object -Unique 41 | $version = "1.2.0" 42 | $filename = Join-Path $env:TEMP "oras_$($version)_windows_amd64.zip" 43 | Invoke-RestMethod -Method GET -UseBasicParsing -Uri "https://github.com/oras-project/oras/releases/download/v$($version)/oras_$($version)_windows_amd64.zip" -OutFile $filename 44 | Expand-Archive -Path $filename -DestinationPath temp 45 | $pushRegistry = "mcrbusinesscentral.azurecr.io" 46 | $staleDate = [System.DateTime]::Today.AddDays(-1).ToString('yyyy-MM-dd') 47 | az acr login --name $pushRegistry 48 | $digests | ForEach-Object { 49 | $image = "$pushRegistry/public/businesscentral@$_" 50 | Write-Host "Stale $image on $staleDate" 51 | ./temp/oras.exe attach --artifact-type application/vnd.microsoft.artifact.lifecycle --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$staleDate" $image 52 | } 53 | 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.msi 2 | *.dll 3 | *.exe 4 | **/Run/Install/* 5 | NULL -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # These owners will be the default owners for everything in the repo. 2 | * @microsoft/d365-bc-engineering-systems 3 | 4 | # Build system files 5 | /.github @microsoft/d365-bc-engineering-systems 6 | /CODEOWNERS @microsoft/d365-bc-engineering-systems 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /NAV Docker Image.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/nav-docker/2461512757925b6f90c75971155aa1eb0093f617/NAV Docker Image.docx -------------------------------------------------------------------------------- /NAV on Docker E2E.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/nav-docker/2461512757925b6f90c75971155aa1eb0093f617/NAV on Docker E2E.docx -------------------------------------------------------------------------------- /NAV on Docker E2E.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/nav-docker/2461512757925b6f90c75971155aa1eb0093f617/NAV on Docker E2E.pdf -------------------------------------------------------------------------------- /NAV on Docker HOL.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/nav-docker/2461512757925b6f90c75971155aa1eb0093f617/NAV on Docker HOL.docx -------------------------------------------------------------------------------- /NAV on Docker HOL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/nav-docker/2461512757925b6f90c75971155aa1eb0093f617/NAV on Docker HOL.pdf -------------------------------------------------------------------------------- /NEWGENERIC.md: -------------------------------------------------------------------------------- 1 | # Monthly generic update workflow 2 | 3 | ## Check latest updates of packages 4 | 5 | Update DOCKERFILE AND DOCKERFILE-filesonly 6 | 7 | SQL Server 8 | https://learn.microsoft.com/en-us/troubleshoot/sql/releases/sqlserver-2019/build-versions 9 | 10 | dotnet 8 11 | https://dotnet.microsoft.com/en-us/download/dotnet/8.0 - grab the direct link behind ASP.NET Core Runtime Windows -> Hosting Bundle 12 | 13 | dotnet 6 14 | https://dotnet.microsoft.com/en-us/download/dotnet/6.0 - grab the direct link behind ASP.NET Core Runtime Windows -> Hosting Bundle 15 | 16 | PowerShell 7 17 | https://github.com/PowerShell/PowerShell/releases - grab the latest PowerShell-7.4.x-win-x64.msi link 18 | 19 | Remember filesonly="yes" at the end of DOCKERFILE-filesonly 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Dynamics NAV in Docker 2 | 3 | This GitHub repository aims to provide a centralized location for community engagement. In here you will find documentation, Dockerfiles and additional developer resources. 4 | 5 | Dynamics NAV in Docker is based on a generic image, which can run any version of NAV (NAV 2016 and up). 6 | Specific images with a specific version of NAV can be built using the generic image and a NAV DVD. 7 | 8 | Visit the [Microsoft Docker Hub](https://hub.docker.com/r/microsoft/dynamics-nav/) for information about specific images 9 | 10 | ## Issues 11 | 12 | For any issues, please file under this GitHub project on the [Issues section](https://github.com/Microsoft/nav-docker/issues). 13 | 14 | ## Troubleshooting & Frequently Asked Questions 15 | 16 | - Licensing for Microsoft Dynamics NAV: Regardless of where you run it - VM, Docker, physical, cloud, on prem - the licensing model is the same. 17 | 18 | ## License 19 | 20 | The Docker resource files for Microsoft Dynamics NAV are licensed under the MIT license. See the [LICENSE file](LICENSE) for more details. 21 | 22 | ## Contributing 23 | 24 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 25 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /generic/DOCKERFILE: -------------------------------------------------------------------------------- 1 | ARG baseimage 2 | 3 | FROM $baseimage 4 | 5 | ARG created \ 6 | tag \ 7 | osversion \ 8 | filesonly \ 9 | only24 10 | 11 | ENV only24=$only24 \ 12 | filesonly=$filesonly 13 | 14 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] 15 | 16 | COPY Run /Run/ 17 | 18 | RUN . .\Run\SetupGeneric1.ps1 19 | 20 | RUN . .\Run\SetupGeneric2.ps1 21 | 22 | HEALTHCHECK --interval=30s --timeout=10s CMD [ "powershell", ".\\Run\\HealthCheck.ps1" ] 23 | 24 | EXPOSE 1433 80 8080 443 7045-7049 7083 25 | 26 | CMD .\Run\start.ps1 27 | 28 | LABEL maintainer="Dynamics SMB" \ 29 | eula="https://go.microsoft.com/fwlink/?linkid=861843" \ 30 | tag="$tag" \ 31 | created="$created" \ 32 | osversion="$osversion" 33 | -------------------------------------------------------------------------------- /generic/DOCKERFILE-filesonly: -------------------------------------------------------------------------------- 1 | ARG baseimage 2 | 3 | FROM $baseimage 4 | 5 | ARG created \ 6 | tag \ 7 | osversion \ 8 | filesonly \ 9 | only24 10 | 11 | ENV only24=$only24 \ 12 | filesonly=$filesonly 13 | 14 | SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] 15 | 16 | COPY Run /Run/ 17 | 18 | RUN . .\Run\SetupGeneric1.ps1 19 | 20 | RUN . .\Run\SetupGeneric2.ps1 21 | 22 | HEALTHCHECK --interval=30s --timeout=10s CMD [ "powershell", ".\\Run\\HealthCheck.ps1" ] 23 | 24 | EXPOSE 1433 80 8080 443 7045-7049 7083 25 | 26 | CMD .\Run\start.ps1 27 | 28 | LABEL maintainer="Dynamics SMB" \ 29 | eula="https://go.microsoft.com/fwlink/?linkid=861843" \ 30 | tag="$tag" \ 31 | created="$created" \ 32 | osversion="$osversion" \ 33 | filesonly="yes" 34 | -------------------------------------------------------------------------------- /generic/Run/100/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/100/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/100/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/110/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/110/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/110/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 8 | } 9 | 10 | Write-Host "Registering event sources" 11 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 12 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 13 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 14 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 15 | } 16 | } 17 | 18 | Write-Host "Creating DotNetCore Web Server Instance" 19 | $publishFolder = "$webClientFolder\WebPublish" 20 | 21 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 22 | if (!(Test-Path $NAVWebClientManagementModule)) { 23 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 24 | } 25 | Import-Module $NAVWebClientManagementModule 26 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 27 | -WebServerInstance "$WebServerInstance" ` 28 | -Server "localhost" ` 29 | -ServerInstance "$ServerInstance" ` 30 | -ClientServicesCredentialType $Auth ` 31 | -ClientServicesPort "$clientServicesPort" ` 32 | -WebSitePort $webClientPort @certparam 33 | 34 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 35 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 36 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 37 | $config.NAVWebSettings.RequireSSL = $false 38 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 39 | $config.NAVWebSettings.PersonalizationEnabled = $true 40 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 41 | 42 | if ($customWebSettings -ne "") { 43 | Write-Host "Modifying Web Client config with settings from environment variable" 44 | 45 | $customWebSettingsArray = $customWebSettings -split "," 46 | foreach ($customWebSetting in $customWebSettingsArray) { 47 | $customWebSettingArray = $customWebSetting -split "=" 48 | $customWebSettingKey = $customWebSettingArray[0] 49 | $customWebSettingValue = $customWebSettingArray[1] 50 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 51 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 52 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 53 | } else { 54 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 55 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 56 | } 57 | } 58 | } 59 | 60 | $config | ConvertTo-Json | set-content $navSettingsFile 61 | -------------------------------------------------------------------------------- /generic/Run/110/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/130/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/130/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/130/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 8 | } 9 | 10 | Write-Host "Registering event sources" 11 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 12 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 13 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 14 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 15 | } 16 | } 17 | 18 | Write-Host "Creating DotNetCore Web Server Instance" 19 | $publishFolder = "$webClientFolder\WebPublish" 20 | 21 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 22 | if (!(Test-Path $NAVWebClientManagementModule)) { 23 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 24 | } 25 | # Replace Copy with Robocopy 26 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 27 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 28 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 29 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 30 | while (!(Test-Path $destPath)) { 31 | Write-Host "Waiting for $destPath to be available" 32 | Start-Sleep -Seconds 1 33 | } 34 | }') 35 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 36 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 37 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 38 | 39 | Import-Module $NAVWebClientManagementModule 40 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 41 | -WebServerInstance "$WebServerInstance" ` 42 | -Server "localhost" ` 43 | -ServerInstance "$ServerInstance" ` 44 | -ClientServicesCredentialType $Auth ` 45 | -ClientServicesPort "$clientServicesPort" ` 46 | -WebSitePort $webClientPort @certparam 47 | 48 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 49 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 50 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 51 | $config.NAVWebSettings.RequireSSL = $false 52 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 53 | $config.NAVWebSettings.PersonalizationEnabled = $true 54 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 55 | 56 | if ($customWebSettings -ne "") { 57 | Write-Host "Modifying Web Client config with settings from environment variable" 58 | 59 | $customWebSettingsArray = $customWebSettings -split "," 60 | foreach ($customWebSetting in $customWebSettingsArray) { 61 | $customWebSettingArray = $customWebSetting -split "=" 62 | $customWebSettingKey = $customWebSettingArray[0] 63 | $customWebSettingValue = $customWebSettingArray[1] 64 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 65 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 66 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 67 | } else { 68 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 69 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 70 | } 71 | } 72 | } 73 | 74 | $config | ConvertTo-Json | set-content $navSettingsFile 75 | -------------------------------------------------------------------------------- /generic/Run/130/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/150-new/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/150-new/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /generic/Run/150/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/150/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 8 | } 9 | 10 | Write-Host "Registering event sources" 11 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 12 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 13 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 14 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 15 | } 16 | } 17 | 18 | Write-Host "Creating DotNetCore Web Server Instance" 19 | $publishFolder = "$webClientFolder\WebPublish" 20 | 21 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 22 | if (!(Test-Path $NAVWebClientManagementModule)) { 23 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 24 | } 25 | Import-Module $NAVWebClientManagementModule 26 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 27 | -WebServerInstance "$WebServerInstance" ` 28 | -Server "localhost" ` 29 | -ServerInstance "$ServerInstance" ` 30 | -ClientServicesCredentialType $Auth ` 31 | -ClientServicesPort "$clientServicesPort" ` 32 | -WebSitePort $webClientPort @certparam 33 | 34 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 35 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 36 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 37 | $config.NAVWebSettings.RequireSSL = $false 38 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 39 | $config.NAVWebSettings.PersonalizationEnabled = $true 40 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 41 | 42 | if ($customWebSettings -ne "") { 43 | Write-Host "Modifying Web Client config with settings from environment variable" 44 | 45 | $customWebSettingsArray = $customWebSettings -split "," 46 | foreach ($customWebSetting in $customWebSettingsArray) { 47 | $customWebSettingArray = $customWebSetting -split "=" 48 | $customWebSettingKey = $customWebSettingArray[0] 49 | $customWebSettingValue = $customWebSettingArray[1] 50 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 51 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 52 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 53 | } else { 54 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 55 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 56 | } 57 | } 58 | } 59 | 60 | $config | ConvertTo-Json | set-content $navSettingsFile 61 | -------------------------------------------------------------------------------- /generic/Run/210-new/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/210-new/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($servicesUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $clientServicesFederationMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']") 107 | if ($clientServicesFederationMetadataLocationNode) { 108 | $clientServicesFederationMetadataLocationNode.Value = $federationMetadata 109 | } 110 | $WSFederationLoginEndpointNode = $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") 111 | if ($WSFederationLoginEndpointNode) { 112 | $WSFederationLoginEndpointNode.Value = $federationLoginEndpoint 113 | } 114 | $ADOpenIdMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ADOpenIdMetadataLocation']") 115 | if ($ADOpenIdMetadataLocationNode -and $ADOpenIdMetadataLocationNode.Value -eq "") { 116 | $ADOpenIdMetadataLocationNode.Value = "https://login.microsoftonline.com/common/.well-known/openid-configuration" 117 | } 118 | } 119 | 120 | $CustomConfig.Save($CustomConfigFile) 121 | 122 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 123 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 124 | if ($servicesUseSSL) { 125 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 126 | } 127 | } 128 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 129 | 130 | if ($developerServicesKeyExists) { 131 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 132 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 133 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 134 | if ($legacySecurityPolicyNode) { 135 | $legacySecurityPolicyNode.enabled = "false" 136 | } 137 | $serverConfig.Save($serverConfigFile) 138 | } 139 | -------------------------------------------------------------------------------- /generic/Run/210-new/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /generic/Run/210/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/210/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($servicesUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']").Value = $federationMetadata 107 | if ($customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") -ne $null) { 108 | $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']").Value = $federationLoginEndpoint 109 | } 110 | } 111 | 112 | $CustomConfig.Save($CustomConfigFile) 113 | 114 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 115 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 116 | if ($servicesUseSSL) { 117 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 118 | } 119 | } 120 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 121 | 122 | if ($developerServicesKeyExists) { 123 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 124 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 125 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 126 | if ($legacySecurityPolicyNode) { 127 | $legacySecurityPolicyNode.enabled = "false" 128 | } 129 | $serverConfig.Save($serverConfigFile) 130 | } 131 | -------------------------------------------------------------------------------- /generic/Run/210/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 8 | } 9 | 10 | Write-Host "Registering event sources" 11 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 12 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 13 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 14 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 15 | } 16 | } 17 | 18 | Write-Host "Creating DotNetCore Web Server Instance" 19 | $publishFolder = "$webClientFolder\WebPublish" 20 | 21 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 22 | if (!(Test-Path $NAVWebClientManagementModule)) { 23 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 24 | } 25 | Import-Module $NAVWebClientManagementModule 26 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 27 | -WebServerInstance "$WebServerInstance" ` 28 | -Server "localhost" ` 29 | -ServerInstance "$ServerInstance" ` 30 | -ClientServicesCredentialType $Auth ` 31 | -ClientServicesPort "$clientServicesPort" ` 32 | -WebSitePort $webClientPort @certparam 33 | 34 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 35 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 36 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 37 | $config.NAVWebSettings.RequireSSL = $false 38 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 39 | $config.NAVWebSettings.PersonalizationEnabled = $true 40 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 41 | 42 | if ($customWebSettings -ne "") { 43 | Write-Host "Modifying Web Client config with settings from environment variable" 44 | 45 | $customWebSettingsArray = $customWebSettings -split "," 46 | foreach ($customWebSetting in $customWebSettingsArray) { 47 | $customWebSettingArray = $customWebSetting -split "=" 48 | $customWebSettingKey = $customWebSettingArray[0] 49 | $customWebSettingValue = $customWebSettingArray[1] 50 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 51 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 52 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 53 | } else { 54 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 55 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 56 | } 57 | } 58 | } 59 | 60 | $config | ConvertTo-Json | set-content $navSettingsFile 61 | -------------------------------------------------------------------------------- /generic/Run/240/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/240/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($servicesUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $clientServicesFederationMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']") 107 | if ($clientServicesFederationMetadataLocationNode) { 108 | $clientServicesFederationMetadataLocationNode.Value = $federationMetadata 109 | } 110 | $WSFederationLoginEndpointNode = $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") 111 | if ($WSFederationLoginEndpointNode) { 112 | $WSFederationLoginEndpointNode.Value = $federationLoginEndpoint 113 | } 114 | $ADOpenIdMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ADOpenIdMetadataLocation']") 115 | if ($ADOpenIdMetadataLocationNode -and $ADOpenIdMetadataLocationNode.Value -eq "") { 116 | $ADOpenIdMetadataLocationNode.Value = "https://login.microsoftonline.com/common/.well-known/openid-configuration" 117 | } 118 | } 119 | 120 | $CustomConfig.Save($CustomConfigFile) 121 | 122 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 123 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 124 | if ($servicesUseSSL) { 125 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 126 | } 127 | } 128 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 129 | 130 | if ($developerServicesKeyExists) { 131 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 132 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 133 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 134 | if ($legacySecurityPolicyNode) { 135 | $legacySecurityPolicyNode.enabled = "false" 136 | } 137 | $serverConfig.Save($serverConfigFile) 138 | } 139 | -------------------------------------------------------------------------------- /generic/Run/240/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /generic/Run/260/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/260/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($servicesUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $clientServicesFederationMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']") 107 | if ($clientServicesFederationMetadataLocationNode) { 108 | $clientServicesFederationMetadataLocationNode.Value = $federationMetadata 109 | } 110 | $WSFederationLoginEndpointNode = $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") 111 | if ($WSFederationLoginEndpointNode) { 112 | $WSFederationLoginEndpointNode.Value = $federationLoginEndpoint 113 | } 114 | $ADOpenIdMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ADOpenIdMetadataLocation']") 115 | if ($ADOpenIdMetadataLocationNode -and $ADOpenIdMetadataLocationNode.Value -eq "") { 116 | $ADOpenIdMetadataLocationNode.Value = "https://login.microsoftonline.com/common/.well-known/openid-configuration" 117 | } 118 | } 119 | 120 | $CustomConfig.Save($CustomConfigFile) 121 | 122 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 123 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 124 | if ($servicesUseSSL) { 125 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 126 | } 127 | } 128 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 129 | 130 | if ($developerServicesKeyExists) { 131 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 132 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 133 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 134 | if ($legacySecurityPolicyNode) { 135 | $legacySecurityPolicyNode.enabled = "false" 136 | } 137 | $serverConfig.Save($serverConfigFile) 138 | } 139 | -------------------------------------------------------------------------------- /generic/Run/260/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /generic/Run/270/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$BC' 2 | $WebServerInstance = "BC" 3 | $ServerInstance = "BC" 4 | -------------------------------------------------------------------------------- /generic/Run/270/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($servicesUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $clientServicesFederationMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']") 107 | if ($clientServicesFederationMetadataLocationNode) { 108 | $clientServicesFederationMetadataLocationNode.Value = $federationMetadata 109 | } 110 | $WSFederationLoginEndpointNode = $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") 111 | if ($WSFederationLoginEndpointNode) { 112 | $WSFederationLoginEndpointNode.Value = $federationLoginEndpoint 113 | } 114 | $ADOpenIdMetadataLocationNode = $customConfig.SelectSingleNode("//appSettings/add[@key='ADOpenIdMetadataLocation']") 115 | if ($ADOpenIdMetadataLocationNode -and $ADOpenIdMetadataLocationNode.Value -eq "") { 116 | $ADOpenIdMetadataLocationNode.Value = "https://login.microsoftonline.com/common/.well-known/openid-configuration" 117 | } 118 | } 119 | 120 | $CustomConfig.Save($CustomConfigFile) 121 | 122 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 123 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 124 | if ($servicesUseSSL) { 125 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 126 | } 127 | } 128 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 129 | 130 | if ($developerServicesKeyExists) { 131 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 132 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 133 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 134 | if ($legacySecurityPolicyNode) { 135 | $legacySecurityPolicyNode.enabled = "false" 136 | } 137 | $serverConfig.Save($serverConfigFile) 138 | } 139 | -------------------------------------------------------------------------------- /generic/Run/270/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /generic/Run/70/CheckHealth.ps1: -------------------------------------------------------------------------------- 1 | if ((Get-service -name 'MicrosoftDynamicsNavServer$NAV').Status -eq 'Running') { 2 | exit 0 3 | } 4 | exit 1 5 | -------------------------------------------------------------------------------- /generic/Run/70/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/70/NAVClientInstallation.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Microsoft Dynamics NAV Windows Client Installation 6 | 7 | 30 | 31 | 123 | 124 | 125 | 126 | 127 |
128 | 129 |

Online installation

130 | 131 |

Microsoft Dynamics NAV | Windows client

132 | 133 | 134 | 135 | 137 | 138 | 139 | 145 | 151 | 152 | 153 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 166 | 168 | 169 | 170 | 173 | 174 | 175 | 176 | 177 | 180 | 181 | 182 | 183 |
When installation is complete, you can start the Microsoft Dynamics NAV Windows client from the Start menu. Additional software or upgrades may be necessary. Please refer to the optional installations below. 136 |
140 | 141 | I accept the Microsoft Dynamics NAV 142 | Software License Terms 143 | 144 | 146 | 147 | 148 | 149 | 150 |
154 |

Reporting | Optional installation

155 |
If you want to be able to print or preview Microsoft Dynamics NAV reports, you need to install prerequisites - CLR types for Microsoft SQL server 2014 (ENU\x86\SQLSysClrTypes.msi) and the Microsoft Report Viewer 2015 or later.
165 | 167 |
171 |

System Update | Optional installation

172 |
Microsoft Dynamics NAV requires Microsoft .NET Framework 4.5.2 You may need to download and install it if you run Windows 7. 178 | 179 |
184 | 185 |

Microsoft Dynamics NAV | C/SIDE Development Environment

186 | 187 | 188 | 189 | 191 | 192 | 193 | 194 | 200 | 205 | 206 | 207 | 208 | 209 | 212 | 213 | 214 | 215 | 216 | 219 | 220 | 221 |
When installation is complete, you can start the Microsoft Dynamics NAV C/SIDE Development Environment from the Start menu. Additional software or upgrades may be necessary. Please refer to the optional installations below. 190 |
195 | 196 | I accept the Microsoft Dynamics NAV 197 | Software License Terms 198 | 199 | 201 | 202 | 203 | 204 |
210 |

Required component | Optional installation

211 |
Microsoft Dynamics NAV C/SIDE Development Environment requires the SQL Server Natie Client to connect to a database. If you don't have it installed yet, you need to install it. 217 | 218 |
222 | 223 |

224 | Community 225 | Feedback 226 | Privacy & Cookies 227 | Accessibility 228 | Terms of Use 229 | Trademarks 230 |

231 | 232 | 233 |
234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /generic/Run/70/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/70/SetupClickOnce.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $navDvdPath 3 | # $publicDnsName 4 | # $clickOnceIdentity 5 | # $httpPath 6 | # $dnsIdentity 7 | # $Auth 8 | # $clickOnceInstallerToolsFolder 9 | # $roleTailoredClientFolder 10 | # 11 | # OUTPUT 12 | # $clickOnceWebSiteUrl 13 | # 14 | 15 | Import-Module "$NAVAdministrationScriptsFolder\NAVAdministration.psm1" 16 | Import-Module WebAdministration 17 | 18 | $clickOnceDirectory = Join-Path $httpPath "NAV" 19 | $clickOnceWebSiteUrl = "http://${publicDnsName}:$publicFileSharePort/NAV" 20 | if ($multitenant) { 21 | $clickOnceDirectory += "/$tenantId" 22 | $clickOnceWebSiteUrl += "/$tenantId" 23 | } 24 | Remove-Item $clickOnceDirectory -Force -Recurse -ErrorAction SilentlyContinue 25 | 26 | $ClientUserSettingsFileName = "$runPath\ClientUserSettings.config" 27 | [xml]$ClientUserSettings = Get-Content $clientUserSettingsFileName 28 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='Server']").value = "$publicDnsName" 29 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServerInstance']").value="NAV" 30 | if ($multitenant) { 31 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='TenantId']").value="$tenantId" 32 | } 33 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServicesCertificateValidationEnabled']").value="false" 34 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesPort']").value="$publicWinClientPort" 35 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ACSUri']").value = "" 36 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='DnsIdentity']").value = "$dnsIdentity" 37 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesCredentialType']").value = "$Auth" 38 | 39 | if ($customWinSettings -ne "") { 40 | Write-Host "Modifying Win Client ClickOnce config with settings from environment variable" 41 | Set-ConfigSetting -customSettings $customWinSettings -parentPath "//configuration/appSettings" -leafName "add" -customConfig $clientUserSettings 42 | } 43 | 44 | $applicationName = "NAV Windows Client for $clickOnceIdentity" 45 | $applicationNameFinSql = "NAV C/SIDE for $clickOnceIdentity" 46 | $applicationPublisher = "Microsoft Corporation" 47 | 48 | 49 | # Create empty directory 50 | New-Item $ClickOnceDirectory -type directory | Out-Null 51 | New-Item (Join-Path $ClickOnceDirectory "Win") -type directory | Out-Null 52 | New-Item (Join-Path $ClickOnceDirectory "Finsql") -type directory | Out-Null 53 | 54 | 55 | # Copy file structure from the installation folder 56 | $templateFilesFolder = Join-Path $clickOnceInstallerToolsFolder 'TemplateFiles' 57 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Win") -Recurse 58 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Finsql") -Recurse 59 | Copy-Item (Join-Path $runPath "NAVClientInstallation.html") -Destination $clickOnceDirectory 60 | 61 | # Save config file and copy the relevant WinClient files to the Deployment\ApplicationFiles folder 62 | $clickOnceApplicationFilesDirectoryWin = Join-Path $ClickOnceDirectory 'Win\Deployment\ApplicationFiles' 63 | $clickOnceApplicationFilesDirectoryFinsql = Join-Path $ClickOnceDirectory 'Finsql\Deployment\ApplicationFiles' 64 | $clientUserSettingsFile = Join-Path $ClickOnceApplicationFilesDirectoryFinsql 'ClientUserSettings.config' 65 | $ClientUserSettings.Save($clientUserSettingsFile) 66 | $clientUserSettingsFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'ClientUserSettings.config' 67 | $ClientUserSettings.Save($clientUserSettingsFile) 68 | . (Get-MyFilePath "SetupClickOnceDirectory.ps1") 69 | 70 | $MageExeLocation = Join-Path $runPath 'Install\mage.exe' 71 | 72 | # Win Client 73 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe.manifest' 74 | $applicationIdentityName = "$clickOnceIdentity ClickOnce" 75 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe')).VersionInfo.FileVersion 76 | 77 | Set-ApplicationManifestFileList ` 78 | -ApplicationManifestFile $ApplicationManifestFile ` 79 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryWin ` 80 | -MageExeLocation $MageExeLocation 81 | Set-ApplicationManifestApplicationIdentity ` 82 | -ApplicationManifestFile $ApplicationManifestFile ` 83 | -ApplicationIdentityName $ApplicationIdentityName ` 84 | -ApplicationIdentityVersion $ApplicationIdentityVersion 85 | 86 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Win\Deployment\Microsoft.Dynamics.Nav.Client.application' 87 | $deploymentIdentityName = "$clickOnceIdentity ClickOnce" 88 | $deploymentIdentityVersion = $applicationIdentityVersion 89 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/Microsoft.Dynamics.Nav.Client.application") 90 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/ApplicationFiles/Microsoft.Dynamics.Nav.Client.exe.manifest") 91 | 92 | Set-DeploymentManifestApplicationReference ` 93 | -DeploymentManifestFile $DeploymentManifestFile ` 94 | -ApplicationManifestFile $ApplicationManifestFile ` 95 | -ApplicationManifestUrl $ApplicationManifestUrl ` 96 | -MageExeLocation $MageExeLocation 97 | Set-DeploymentManifestSettings ` 98 | -DeploymentManifestFile $DeploymentManifestFile ` 99 | -DeploymentIdentityName $DeploymentIdentityName ` 100 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 101 | -ApplicationPublisher $ApplicationPublisher ` 102 | -ApplicationName $ApplicationName ` 103 | -DeploymentManifestUrl $DeploymentManifestUrl 104 | 105 | # Finsql 106 | Rename-Item (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'Microsoft.Dynamics.Nav.Client.exe.manifest') (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest') 107 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest' 108 | (Get-Content $applicationManifestFile). 109 | Replace('"msil"', '"x86"'). 110 | Replace('',''). 111 | Replace('name="Microsoft.Dynamics.Nav.Client" version="8.0.0.0"','name="finsql" version="0.0.0.0"') | Set-Content $applicationManifestFile 112 | $applicationIdentityName = "$clickOnceIdentity Finsql ClickOnce" 113 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe')).VersionInfo.FileVersion 114 | 115 | Set-ApplicationManifestFileList ` 116 | -ApplicationManifestFile $ApplicationManifestFile ` 117 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryFinsql ` 118 | -MageExeLocation $MageExeLocation 119 | Set-ApplicationManifestApplicationIdentity ` 120 | -ApplicationManifestFile $ApplicationManifestFile ` 121 | -ApplicationIdentityName $ApplicationIdentityName ` 122 | -ApplicationIdentityVersion $ApplicationIdentityVersion 123 | 124 | Rename-Item (Join-Path $clickOnceDirectory 'Finsql\Deployment\Microsoft.Dynamics.Nav.Client.application') (Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application') 125 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application' 126 | (Get-Content $deploymentManifestFile).replace('"msil"', '"x86"') | Set-Content $deploymentManifestFile 127 | $deploymentIdentityName = "$clickOnceIdentity Finsql ClickOnce" 128 | $deploymentIdentityVersion = $applicationIdentityVersion 129 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/Finsql.application") 130 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/ApplicationFiles/Finsql.exe.manifest") 131 | 132 | Set-DeploymentManifestApplicationReference ` 133 | -DeploymentManifestFile $DeploymentManifestFile ` 134 | -ApplicationManifestFile $ApplicationManifestFile ` 135 | -ApplicationManifestUrl $ApplicationManifestUrl ` 136 | -MageExeLocation $MageExeLocation 137 | Set-DeploymentManifestSettings ` 138 | -DeploymentManifestFile $DeploymentManifestFile ` 139 | -DeploymentIdentityName $DeploymentIdentityName ` 140 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 141 | -ApplicationPublisher $ApplicationPublisher ` 142 | -ApplicationName $applicationNameFinSql ` 143 | -DeploymentManifestUrl $DeploymentManifestUrl 144 | 145 | 146 | # Put a web.config file in the root folder, which will tell IIS which .html file to open 147 | $sourceFile = Join-Path $runPath 'root_web.config' 148 | $targetFile = Join-Path $clickOnceDirectory 'web.config' 149 | Copy-Item $sourceFile -destination $targetFile 150 | 151 | # Put a web.config file in the Deployment folder, which will tell IIS to allow downloading of .config files etc. 152 | $sourceFile = Join-Path $runPath 'deployment_web.config' 153 | $targetFile = Join-Path $clickOnceDirectory 'Win\Deployment\web.config' 154 | Copy-Item $sourceFile -destination $targetFile 155 | $targetFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\web.config' 156 | Copy-Item $sourceFile -destination $targetFile 157 | -------------------------------------------------------------------------------- /generic/Run/70/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "NAV" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | 26 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 27 | if ($taskSchedulerKeyExists) { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 29 | } 30 | 31 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 32 | if ($developerServicesKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 34 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 35 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 36 | } 37 | 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 39 | if ($developerServicesKeyExists) { 40 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/NAV/" 41 | } else { 42 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/NAV/WebClient/" 43 | } 44 | if ($navUseSSL) { 45 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCertificateThumbprint']").Value = "$certificateThumbprint" 46 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCertificateValidationEnabled']").Value = "false" 47 | } 48 | 49 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 50 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 51 | 52 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 53 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 54 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 55 | } 56 | 57 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 58 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 59 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 60 | } 61 | 62 | if ($customNavSettings -ne "") { 63 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 64 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 65 | } 66 | 67 | if ($auth -eq "AccessControlService") { 68 | if ($appIdUri -eq "") { 69 | $appIdUri = "$publicWebBaseUrl" 70 | } 71 | if ($federationMetadata -eq "") { 72 | $federationMetadata = "https://login.windows.net/Common/federationmetadata/2007-06/federationmetadata.xml" 73 | } 74 | if ($federationLoginEndpoint -eq "") { 75 | $federationLoginEndpoint = "https://login.windows.net/Common/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 76 | } 77 | 78 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 79 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']").Value = $federationMetadata 80 | if ($customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") -ne $null) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']").Value = $federationLoginEndpoint 82 | } 83 | } 84 | 85 | $CustomConfig.Save($CustomConfigFile) 86 | 87 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort | % { 88 | netsh http add urlacl url=$protocol+:$_/NAV user="NT AUTHORITY\SYSTEM" | Out-Null 89 | if ($servicesUseSSL) { 90 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 91 | } 92 | } 93 | 94 | if ($navUseSSL) { 95 | netsh http add urlacl url=https://+:$clientServicesPort/NAV user="NT AUTHORITY\SYSTEM" | Out-Null 96 | netsh http add sslcert ipport=0.0.0.0:$clientServicesPort certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 97 | } else { 98 | netsh http add urlacl url=http://+:$clientServicesPort/NAV user="NT AUTHORITY\SYSTEM" | Out-Null 99 | } 100 | 101 | if ($developerServicesKeyExists) { 102 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 103 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 104 | $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy").enabled = "false" 105 | $serverConfig.Save($serverConfigFile) 106 | } 107 | -------------------------------------------------------------------------------- /generic/Run/70/SetupNavUsers.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $username (optional) 4 | # $securePassword (optional) 5 | # 6 | # OUTPUT 7 | # 8 | 9 | if ($auth -eq "Windows") { 10 | if ($username -ne "") { 11 | if (!(Get-NAVServerUser -ServerInstance NAV @tenantParam -ErrorAction Ignore | Where-Object { ($_.UserName) -and ($_.UserName.EndsWith("\$username", [System.StringComparison]::InvariantCultureIgnoreCase) -or $_.UserName -eq $username) })) { 12 | Write-Host "Creating SUPER user with authentication Windows" 13 | New-NavServerUser -ServerInstance NAV @tenantParam -WindowsAccount $username 14 | New-NavServerUserPermissionSet -ServerInstance NAV @tenantParam -WindowsAccount $username -PermissionSetId SUPER 15 | } 16 | } 17 | } else { 18 | if (!(Get-NAVServerUser -ServerInstance NAV @tenantParam -ErrorAction Ignore | Where-Object { $_.UserName -eq $username })) { 19 | Write-Host "Creating SUPER user with other authentication" 20 | New-NavServerUser -ServerInstance NAV @tenantParam -Username $username -Password $securePassword 21 | New-NavServerUserPermissionSet -ServerInstance NAV @tenantParam -username $username -PermissionSetId SUPER 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generic/Run/70/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/71/CheckHealth.ps1: -------------------------------------------------------------------------------- 1 | if ((Get-service -name 'MicrosoftDynamicsNavServer$NAV').Status -eq 'Running') { 2 | exit 0 3 | } 4 | exit 1 5 | -------------------------------------------------------------------------------- /generic/Run/71/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/71/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/71/SetupClickOnce.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $navDvdPath 3 | # $publicDnsName 4 | # $clickOnceIdentity 5 | # $httpPath 6 | # $dnsIdentity 7 | # $Auth 8 | # $clickOnceInstallerToolsFolder 9 | # $roleTailoredClientFolder 10 | # 11 | # OUTPUT 12 | # $clickOnceWebSiteUrl 13 | # 14 | 15 | Import-Module "$NAVAdministrationScriptsFolder\NAVAdministration.psm1" 16 | Import-Module WebAdministration 17 | 18 | $clickOnceDirectory = Join-Path $httpPath "NAV" 19 | $clickOnceWebSiteUrl = "http://${publicDnsName}:$publicFileSharePort/NAV" 20 | if ($multitenant) { 21 | $clickOnceDirectory += "/$tenantId" 22 | $clickOnceWebSiteUrl += "/$tenantId" 23 | } 24 | Remove-Item $clickOnceDirectory -Force -Recurse -ErrorAction SilentlyContinue 25 | 26 | $ClientUserSettingsFileName = "$runPath\ClientUserSettings.config" 27 | [xml]$ClientUserSettings = Get-Content $clientUserSettingsFileName 28 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='Server']").value = "$publicDnsName" 29 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServerInstance']").value="NAV" 30 | if ($multitenant) { 31 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='TenantId']").value="$tenantId" 32 | } 33 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServicesCertificateValidationEnabled']").value="false" 34 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesPort']").value="$publicWinClientPort" 35 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ACSUri']").value = "" 36 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='DnsIdentity']").value = "$dnsIdentity" 37 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesCredentialType']").value = "$Auth" 38 | 39 | if ($customWinSettings -ne "") { 40 | Write-Host "Modifying Win Client ClickOnce config with settings from environment variable" 41 | Set-ConfigSetting -customSettings $customWinSettings -parentPath "//configuration/appSettings" -leafName "add" -customConfig $clientUserSettings 42 | } 43 | 44 | $applicationName = "NAV Windows Client for $clickOnceIdentity" 45 | $applicationNameFinSql = "NAV C/SIDE for $clickOnceIdentity" 46 | $applicationPublisher = "Microsoft Corporation" 47 | 48 | 49 | # Create empty directory 50 | New-Item $ClickOnceDirectory -type directory | Out-Null 51 | New-Item (Join-Path $ClickOnceDirectory "Win") -type directory | Out-Null 52 | New-Item (Join-Path $ClickOnceDirectory "Finsql") -type directory | Out-Null 53 | 54 | 55 | # Copy file structure from the installation folder 56 | $templateFilesFolder = Join-Path $clickOnceInstallerToolsFolder 'TemplateFiles' 57 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Win") -Recurse 58 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Finsql") -Recurse 59 | Copy-Item (Join-Path $runPath "NAVClientInstallation.html") -Destination $clickOnceDirectory 60 | 61 | # Save config file and copy the relevant WinClient files to the Deployment\ApplicationFiles folder 62 | $clickOnceApplicationFilesDirectoryWin = Join-Path $ClickOnceDirectory 'Win\Deployment\ApplicationFiles' 63 | $clickOnceApplicationFilesDirectoryFinsql = Join-Path $ClickOnceDirectory 'Finsql\Deployment\ApplicationFiles' 64 | $clientUserSettingsFile = Join-Path $ClickOnceApplicationFilesDirectoryFinsql 'ClientUserSettings.config' 65 | $ClientUserSettings.Save($clientUserSettingsFile) 66 | $clientUserSettingsFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'ClientUserSettings.config' 67 | $ClientUserSettings.Save($clientUserSettingsFile) 68 | . (Get-MyFilePath "SetupClickOnceDirectory.ps1") 69 | 70 | $MageExeLocation = Join-Path $runPath 'Install\mage.exe' 71 | 72 | # Win Client 73 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe.manifest' 74 | $applicationIdentityName = "$clickOnceIdentity ClickOnce" 75 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe')).VersionInfo.FileVersion 76 | 77 | Set-ApplicationManifestFileList ` 78 | -ApplicationManifestFile $ApplicationManifestFile ` 79 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryWin ` 80 | -MageExeLocation $MageExeLocation 81 | Set-ApplicationManifestApplicationIdentity ` 82 | -ApplicationManifestFile $ApplicationManifestFile ` 83 | -ApplicationIdentityName $ApplicationIdentityName ` 84 | -ApplicationIdentityVersion $ApplicationIdentityVersion 85 | 86 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Win\Deployment\Microsoft.Dynamics.Nav.Client.application' 87 | $deploymentIdentityName = "$clickOnceIdentity ClickOnce" 88 | $deploymentIdentityVersion = $applicationIdentityVersion 89 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/Microsoft.Dynamics.Nav.Client.application") 90 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/ApplicationFiles/Microsoft.Dynamics.Nav.Client.exe.manifest") 91 | 92 | Set-DeploymentManifestApplicationReference ` 93 | -DeploymentManifestFile $DeploymentManifestFile ` 94 | -ApplicationManifestFile $ApplicationManifestFile ` 95 | -ApplicationManifestUrl $ApplicationManifestUrl ` 96 | -MageExeLocation $MageExeLocation 97 | Set-DeploymentManifestSettings ` 98 | -DeploymentManifestFile $DeploymentManifestFile ` 99 | -DeploymentIdentityName $DeploymentIdentityName ` 100 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 101 | -ApplicationPublisher $ApplicationPublisher ` 102 | -ApplicationName $ApplicationName ` 103 | -DeploymentManifestUrl $DeploymentManifestUrl 104 | 105 | # Finsql 106 | Rename-Item (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'Microsoft.Dynamics.Nav.Client.exe.manifest') (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest') 107 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest' 108 | (Get-Content $applicationManifestFile). 109 | Replace('"msil"', '"x86"'). 110 | Replace('',''). 111 | Replace('name="Microsoft.Dynamics.Nav.Client" version="8.0.0.0"','name="finsql" version="0.0.0.0"') | Set-Content $applicationManifestFile 112 | $applicationIdentityName = "$clickOnceIdentity Finsql ClickOnce" 113 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe')).VersionInfo.FileVersion 114 | 115 | Set-ApplicationManifestFileList ` 116 | -ApplicationManifestFile $ApplicationManifestFile ` 117 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryFinsql ` 118 | -MageExeLocation $MageExeLocation 119 | Set-ApplicationManifestApplicationIdentity ` 120 | -ApplicationManifestFile $ApplicationManifestFile ` 121 | -ApplicationIdentityName $ApplicationIdentityName ` 122 | -ApplicationIdentityVersion $ApplicationIdentityVersion 123 | 124 | Rename-Item (Join-Path $clickOnceDirectory 'Finsql\Deployment\Microsoft.Dynamics.Nav.Client.application') (Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application') 125 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application' 126 | (Get-Content $deploymentManifestFile).replace('"msil"', '"x86"') | Set-Content $deploymentManifestFile 127 | $deploymentIdentityName = "$clickOnceIdentity Finsql ClickOnce" 128 | $deploymentIdentityVersion = $applicationIdentityVersion 129 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/Finsql.application") 130 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/ApplicationFiles/Finsql.exe.manifest") 131 | 132 | Set-DeploymentManifestApplicationReference ` 133 | -DeploymentManifestFile $DeploymentManifestFile ` 134 | -ApplicationManifestFile $ApplicationManifestFile ` 135 | -ApplicationManifestUrl $ApplicationManifestUrl ` 136 | -MageExeLocation $MageExeLocation 137 | Set-DeploymentManifestSettings ` 138 | -DeploymentManifestFile $DeploymentManifestFile ` 139 | -DeploymentIdentityName $DeploymentIdentityName ` 140 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 141 | -ApplicationPublisher $ApplicationPublisher ` 142 | -ApplicationName $applicationNameFinSql ` 143 | -DeploymentManifestUrl $DeploymentManifestUrl 144 | 145 | 146 | # Put a web.config file in the root folder, which will tell IIS which .html file to open 147 | $sourceFile = Join-Path $runPath 'root_web.config' 148 | $targetFile = Join-Path $clickOnceDirectory 'web.config' 149 | Copy-Item $sourceFile -destination $targetFile 150 | 151 | # Put a web.config file in the Deployment folder, which will tell IIS to allow downloading of .config files etc. 152 | $sourceFile = Join-Path $runPath 'deployment_web.config' 153 | $targetFile = Join-Path $clickOnceDirectory 'Win\Deployment\web.config' 154 | Copy-Item $sourceFile -destination $targetFile 155 | $targetFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\web.config' 156 | Copy-Item $sourceFile -destination $targetFile 157 | -------------------------------------------------------------------------------- /generic/Run/71/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/80/CheckHealth.ps1: -------------------------------------------------------------------------------- 1 | if ((Get-service -name 'MicrosoftDynamicsNavServer$NAV').Status -eq 'Running') { 2 | exit 0 3 | } 4 | exit 1 5 | -------------------------------------------------------------------------------- /generic/Run/80/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/80/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/80/SetupClickOnce.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $navDvdPath 3 | # $publicDnsName 4 | # $clickOnceIdentity 5 | # $httpPath 6 | # $dnsIdentity 7 | # $Auth 8 | # $clickOnceInstallerToolsFolder 9 | # $roleTailoredClientFolder 10 | # 11 | # OUTPUT 12 | # $clickOnceWebSiteUrl 13 | # 14 | 15 | Import-Module "$NAVAdministrationScriptsFolder\NAVAdministration.psm1" 16 | Import-Module WebAdministration 17 | 18 | $clickOnceDirectory = Join-Path $httpPath "NAV" 19 | $clickOnceWebSiteUrl = "http://${publicDnsName}:$publicFileSharePort/NAV" 20 | if ($multitenant) { 21 | $clickOnceDirectory += "/$tenantId" 22 | $clickOnceWebSiteUrl += "/$tenantId" 23 | } 24 | Remove-Item $clickOnceDirectory -Force -Recurse -ErrorAction SilentlyContinue 25 | 26 | $ClientUserSettingsFileName = "$runPath\ClientUserSettings.config" 27 | [xml]$ClientUserSettings = Get-Content $clientUserSettingsFileName 28 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='Server']").value = "$publicDnsName" 29 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServerInstance']").value="NAV" 30 | if ($multitenant) { 31 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='TenantId']").value="$tenantId" 32 | } 33 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ServicesCertificateValidationEnabled']").value="false" 34 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesPort']").value="$publicWinClientPort" 35 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ACSUri']").value = "" 36 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='DnsIdentity']").value = "$dnsIdentity" 37 | $clientUserSettings.SelectSingleNode("//configuration/appSettings/add[@key='ClientServicesCredentialType']").value = "$Auth" 38 | 39 | if ($customWinSettings -ne "") { 40 | Write-Host "Modifying Win Client ClickOnce config with settings from environment variable" 41 | Set-ConfigSetting -customSettings $customWinSettings -parentPath "//configuration/appSettings" -leafName "add" -customConfig $clientUserSettings 42 | } 43 | 44 | $applicationName = "NAV Windows Client for $clickOnceIdentity" 45 | $applicationNameFinSql = "NAV C/SIDE for $clickOnceIdentity" 46 | $applicationPublisher = "Microsoft Corporation" 47 | 48 | 49 | # Create empty directory 50 | New-Item $ClickOnceDirectory -type directory | Out-Null 51 | New-Item (Join-Path $ClickOnceDirectory "Win") -type directory | Out-Null 52 | New-Item (Join-Path $ClickOnceDirectory "Finsql") -type directory | Out-Null 53 | 54 | 55 | # Copy file structure from the installation folder 56 | $templateFilesFolder = Join-Path $clickOnceInstallerToolsFolder 'TemplateFiles' 57 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Win") -Recurse 58 | Copy-Item $templateFilesFolder\* -Destination (Join-Path $ClickOnceDirectory "Finsql") -Recurse 59 | Copy-Item (Join-Path $runPath "NAVClientInstallation.html") -Destination $clickOnceDirectory 60 | 61 | # Save config file and copy the relevant WinClient files to the Deployment\ApplicationFiles folder 62 | $clickOnceApplicationFilesDirectoryWin = Join-Path $ClickOnceDirectory 'Win\Deployment\ApplicationFiles' 63 | $clickOnceApplicationFilesDirectoryFinsql = Join-Path $ClickOnceDirectory 'Finsql\Deployment\ApplicationFiles' 64 | $clientUserSettingsFile = Join-Path $ClickOnceApplicationFilesDirectoryFinsql 'ClientUserSettings.config' 65 | $ClientUserSettings.Save($clientUserSettingsFile) 66 | $clientUserSettingsFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'ClientUserSettings.config' 67 | $ClientUserSettings.Save($clientUserSettingsFile) 68 | . (Get-MyFilePath "SetupClickOnceDirectory.ps1") 69 | 70 | $MageExeLocation = Join-Path $runPath 'Install\mage.exe' 71 | 72 | # Win Client 73 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe.manifest' 74 | $applicationIdentityName = "$clickOnceIdentity ClickOnce" 75 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryWin 'Microsoft.Dynamics.Nav.Client.exe')).VersionInfo.FileVersion 76 | 77 | Set-ApplicationManifestFileList ` 78 | -ApplicationManifestFile $ApplicationManifestFile ` 79 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryWin ` 80 | -MageExeLocation $MageExeLocation 81 | Set-ApplicationManifestApplicationIdentity ` 82 | -ApplicationManifestFile $ApplicationManifestFile ` 83 | -ApplicationIdentityName $ApplicationIdentityName ` 84 | -ApplicationIdentityVersion $ApplicationIdentityVersion 85 | 86 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Win\Deployment\Microsoft.Dynamics.Nav.Client.application' 87 | $deploymentIdentityName = "$clickOnceIdentity ClickOnce" 88 | $deploymentIdentityVersion = $applicationIdentityVersion 89 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/Microsoft.Dynamics.Nav.Client.application") 90 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Win/Deployment/ApplicationFiles/Microsoft.Dynamics.Nav.Client.exe.manifest") 91 | 92 | Set-DeploymentManifestApplicationReference ` 93 | -DeploymentManifestFile $DeploymentManifestFile ` 94 | -ApplicationManifestFile $ApplicationManifestFile ` 95 | -ApplicationManifestUrl $ApplicationManifestUrl ` 96 | -MageExeLocation $MageExeLocation 97 | Set-DeploymentManifestSettings ` 98 | -DeploymentManifestFile $DeploymentManifestFile ` 99 | -DeploymentIdentityName $DeploymentIdentityName ` 100 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 101 | -ApplicationPublisher $ApplicationPublisher ` 102 | -ApplicationName $ApplicationName ` 103 | -DeploymentManifestUrl $DeploymentManifestUrl 104 | 105 | # Finsql 106 | Rename-Item (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'Microsoft.Dynamics.Nav.Client.exe.manifest') (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest') 107 | $applicationManifestFile = Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe.manifest' 108 | (Get-Content $applicationManifestFile). 109 | Replace('"msil"', '"x86"'). 110 | Replace('',''). 111 | Replace('name="Microsoft.Dynamics.Nav.Client" version="8.0.0.0"','name="finsql" version="0.0.0.0"') | Set-Content $applicationManifestFile 112 | $applicationIdentityName = "$clickOnceIdentity Finsql ClickOnce" 113 | $applicationIdentityVersion = (Get-Item -Path (Join-Path $clickOnceApplicationFilesDirectoryFinsql 'finsql.exe')).VersionInfo.FileVersion 114 | 115 | Set-ApplicationManifestFileList ` 116 | -ApplicationManifestFile $ApplicationManifestFile ` 117 | -ApplicationFilesDirectory $ClickOnceApplicationFilesDirectoryFinsql ` 118 | -MageExeLocation $MageExeLocation 119 | Set-ApplicationManifestApplicationIdentity ` 120 | -ApplicationManifestFile $ApplicationManifestFile ` 121 | -ApplicationIdentityName $ApplicationIdentityName ` 122 | -ApplicationIdentityVersion $ApplicationIdentityVersion 123 | 124 | Rename-Item (Join-Path $clickOnceDirectory 'Finsql\Deployment\Microsoft.Dynamics.Nav.Client.application') (Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application') 125 | $deploymentManifestFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\finsql.application' 126 | (Get-Content $deploymentManifestFile).replace('"msil"', '"x86"') | Set-Content $deploymentManifestFile 127 | $deploymentIdentityName = "$clickOnceIdentity Finsql ClickOnce" 128 | $deploymentIdentityVersion = $applicationIdentityVersion 129 | $deploymentManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/Finsql.application") 130 | $applicationManifestUrl = ($clickOnceWebSiteUrl + "/Finsql/Deployment/ApplicationFiles/Finsql.exe.manifest") 131 | 132 | Set-DeploymentManifestApplicationReference ` 133 | -DeploymentManifestFile $DeploymentManifestFile ` 134 | -ApplicationManifestFile $ApplicationManifestFile ` 135 | -ApplicationManifestUrl $ApplicationManifestUrl ` 136 | -MageExeLocation $MageExeLocation 137 | Set-DeploymentManifestSettings ` 138 | -DeploymentManifestFile $DeploymentManifestFile ` 139 | -DeploymentIdentityName $DeploymentIdentityName ` 140 | -DeploymentIdentityVersion $DeploymentIdentityVersion ` 141 | -ApplicationPublisher $ApplicationPublisher ` 142 | -ApplicationName $applicationNameFinSql ` 143 | -DeploymentManifestUrl $DeploymentManifestUrl 144 | 145 | 146 | # Put a web.config file in the root folder, which will tell IIS which .html file to open 147 | $sourceFile = Join-Path $runPath 'root_web.config' 148 | $targetFile = Join-Path $clickOnceDirectory 'web.config' 149 | Copy-Item $sourceFile -destination $targetFile 150 | 151 | # Put a web.config file in the Deployment folder, which will tell IIS to allow downloading of .config files etc. 152 | $sourceFile = Join-Path $runPath 'deployment_web.config' 153 | $targetFile = Join-Path $clickOnceDirectory 'Win\Deployment\web.config' 154 | Copy-Item $sourceFile -destination $targetFile 155 | $targetFile = Join-Path $clickOnceDirectory 'Finsql\Deployment\web.config' 156 | Copy-Item $sourceFile -destination $targetFile 157 | -------------------------------------------------------------------------------- /generic/Run/80/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/90/Deployment_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /generic/Run/90/ServiceSettings.ps1: -------------------------------------------------------------------------------- 1 | $NavServiceName = 'MicrosoftDynamicsNavServer$NAV' 2 | $WebServerInstance = "NAV" 3 | $ServerInstance = "NAV" 4 | -------------------------------------------------------------------------------- /generic/Run/90/root_web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /generic/Run/AdditionalOutput.ps1: -------------------------------------------------------------------------------- 1 | # This file is intentionally empty 2 | -------------------------------------------------------------------------------- /generic/Run/AdditionalSetup.ps1: -------------------------------------------------------------------------------- 1 | # This file is intentionally empty 2 | -------------------------------------------------------------------------------- /generic/Run/CheckHealth.ps1: -------------------------------------------------------------------------------- 1 | try { 2 | . (Join-Path $PSScriptRoot "ServiceSettings.ps1") 3 | $CustomConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config" 4 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 5 | $publicWebBaseUrl = $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value 6 | $serverInstance = $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value 7 | if ($publicWebBaseUrl -ne "") { 8 | # WebClient installed use WebClient base Health endpoint 9 | if (!($publicWebBaseUrl.EndsWith("/"))) { $publicWebBaseUrl += "/" } 10 | $result = Invoke-WebRequest -Uri "${publicWebBaseUrl}Health/System" -UseBasicParsing -TimeoutSec 10 11 | if ($result.StatusCode -eq 200 -and ((ConvertFrom-Json $result.Content).result)) { 12 | # Web Client Health Check Endpoint will test Web Client, Service Tier and Database Connection 13 | exit 0 14 | } 15 | } else { 16 | # WebClient not installed, check Service Tier 17 | if ((Get-service -name "$NavServiceName").Status -eq 'Running') { 18 | exit 0 19 | } 20 | } 21 | } catch { 22 | } 23 | exit 1 -------------------------------------------------------------------------------- /generic/Run/GetDvdArtifactPaths.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Gets the path to the server's W1DVD Service folder 4 | .DESCRIPTION 5 | Gets the path to the server's W1DVD Service folder 6 | #> 7 | function Get-NavDvdServiceFolder { 8 | Param( 9 | [Parameter(Mandatory=$true)] 10 | [string] $platformArtifactPath 11 | ) 12 | 13 | $ServiceFolder = Join-Path $platformArtifactPath "ServiceTier\pfiles64\Microsoft Dynamics NAV\*\Service" 14 | if (!(Test-Path $ServiceFolder)) { 15 | # Use the legacy folder path used before version 27 (wix 6.0) 16 | $ServiceFolder = Join-Path $platformArtifactPath "ServiceTier\program files\Microsoft Dynamics NAV\*\Service" 17 | } 18 | 19 | return (Get-Item $ServiceFolder).FullName 20 | } 21 | 22 | <# 23 | .SYNOPSIS 24 | Gets the name of the Common App Data folder on the dvd image 25 | .DESCRIPTION 26 | Gets the name of the Common App Data folder on the dvd image 27 | #> 28 | function Get-WixCommonAppData { 29 | Param( 30 | [Parameter(Mandatory=$true)] 31 | [string] $platformArtifactPath 32 | ) 33 | 34 | $CommonAppData = "CommApp" 35 | $databaseFolder = Join-Path $platformArtifactPath "SQLDemoDatabase\$CommonAppData" 36 | if (!(Test-Path $databaseFolder -PathType Container)) { 37 | # Use the legacy folder path used before version 27 (wix 6.0) 38 | $CommonAppData = "CommonAppData" 39 | } 40 | 41 | return $CommonAppData 42 | } 43 | 44 | <# 45 | .SYNOPSIS 46 | Gets the name of the Program Files folder on the dvd image 47 | .DESCRIPTION 48 | Gets the name of the Program Files folder on the dvd image 49 | #> 50 | function Get-WixProgramFiles64 { 51 | Param( 52 | [Parameter(Mandatory=$true)] 53 | [string] $platformArtifactPath 54 | ) 55 | 56 | $pfiles64 = "pfiles64" 57 | $ServiceFolder = Join-Path $platformArtifactPath "ServiceTier\$pfiles64\Microsoft Dynamics NAV\*\Service" 58 | if (!(Test-Path $ServiceFolder)) { 59 | # Use the legacy folder path used before version 27 (wix 6.0) 60 | $pfiles64 = "program files" 61 | } 62 | 63 | return $pfiles64 64 | } 65 | 66 | <# 67 | .SYNOPSIS 68 | Gets the path to the DevTools W1DVD folder 69 | .DESCRIPTION 70 | Gets the path to the DevTools W1DVD folder 71 | #> 72 | function Get-NavDvdDevToolsFolder { 73 | Param( 74 | [Parameter(Mandatory=$true)] 75 | [string] $platformArtifactPath 76 | ) 77 | 78 | $rootPath = Join-Path $platformArtifactPath "ModernDev\pfiles" 79 | if (!(Test-Path $rootPath)) { 80 | # Use the legacy folder path used before version 27 and wix 6.0 81 | $rootPath = Join-Path $platformArtifactPath "ModernDev\program files" 82 | } 83 | 84 | return (Join-Path $rootPath "Microsoft Dynamics NAV") 85 | } 86 | 87 | <# 88 | .SYNOPSIS 89 | Gets the path to the WebRoot W1DVD folder 90 | .DESCRIPTION 91 | Gets the path to the WebRoot W1DVD folder 92 | #> 93 | function Get-NavDvdWebRootFolder { 94 | Param( 95 | [Parameter(Mandatory=$true)] 96 | [string] $platformArtifactPath 97 | ) 98 | 99 | $WebRoot = Join-Path $platformArtifactPath "WebClient\pfiles\Microsoft Dynamics NAV" 100 | if (!(Test-Path $webRoot)) 101 | { 102 | # Use the legacy folder path used before version 27 and wix 6.0 103 | $WebRoot = Join-Path $platformArtifactPath "WebClient\Microsoft Dynamics NAV" 104 | } 105 | 106 | return $WebRoot 107 | } 108 | 109 | <# 110 | .SYNOPSIS 111 | Gets the path to the NavSip component on the W1DVD 112 | .DESCRIPTION 113 | Gets the path to the NavSip component on the W1DVD 114 | #> 115 | function Get-NavDvdSipComponentPath { 116 | Param( 117 | [Parameter(Mandatory=$true)] 118 | [string] $platformArtifactPath 119 | ) 120 | 121 | $sipComponentPath = Join-Path $platformArtifactPath "ServiceTier\System64" 122 | if (!(Test-Path $sipComponentPath)) { 123 | # Use the legacy folder path used before version 27 and wix 6.0 124 | $sipComponentPath = Join-Path $platformArtifactPath "ServiceTier\System64Folder" 125 | } 126 | 127 | return $sipComponentPath 128 | } 129 | -------------------------------------------------------------------------------- /generic/Run/Healthcheck.ps1: -------------------------------------------------------------------------------- 1 | if ((Test-Path "$PSScriptRoot\my" -PathType Container) -and (Test-Path "$PSScriptRoot\my\CheckHealth.ps1" -PathType Leaf)) { 2 | . "$PSScriptRoot\my\CheckHealth.ps1" 3 | } else { 4 | . "$PSScriptRoot\CheckHealth.ps1" 5 | } 6 | 7 | exit $LASTEXITCODE 8 | -------------------------------------------------------------------------------- /generic/Run/MainLoop.ps1: -------------------------------------------------------------------------------- 1 | $lastCheck = (Get-Date).AddSeconds(-2) 2 | Write-Host "Starting EventLog Monitor" 3 | 4 | ######################################################################################################## 5 | ### Setup EventLog to Monitor 6 | ######################################################################################################## 7 | $ComputerName = "." ### LocalHost 8 | $EventLogName = "Application" ### Application Event Log 9 | $EventLogSource = "" ### Source cannot be filtered 10 | 11 | ######################################################################################################## 12 | ### Setup Sources to Filter 13 | ######################################################################################################## 14 | ### Get All Event Source for the selected Event Log 15 | $EventLogSources = (Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\$($EventLogName)).pschildname 16 | 17 | ### Create array of EventSources to monitor in Global variable / need to be global so ObjectEvent can pick it up 18 | $Global:EventLogSourcesToMonitor = $EventLogSources | where-object { ($_ -ilike "*Dynamics*") -or ($_ -ilike "MSSQL`$*")} 19 | Write-Host "Monitoring EventSources from EventLog[$($EventLogName)]:" 20 | foreach($EventLogSourceToMonitor in $Global:EventLogSourcesToMonitor){ 21 | Write-Host "- $($EventLogSourceToMonitor)" 22 | } 23 | Write-Host "" 24 | 25 | ######################################################################################################## 26 | ### Create the EventLog Object 27 | ######################################################################################################## 28 | ### Initialize the LastEventLogIndex 29 | $Global:LastEventLogIndex = 0 30 | 31 | ### Initialize dotnet EventLog object 32 | $EventLog = [System.Diagnostics.EventLog]::New($EventLogName, $ComputerName, $EventLogSource) 33 | 34 | ######################################################################################################## 35 | ### Register to the EventLog event "EntryWritten" 36 | ######################################################################################################## 37 | Register-ObjectEvent -InputObject $EventLog ` 38 | -EventName "EntryWritten" ` 39 | -Action { 40 | ### Save event in Global variable / Not required / Handy for debugging 41 | $Global:LastEvent = $Event 42 | 43 | ### Map the received to event to variable for cleaner code 44 | $EventLogEntry = $Event.SourceEventArgs.Entry 45 | 46 | ### !!! ATTENTION !!! 47 | ### This part is uber-important due to how the EventLog works 48 | ### When the EventLog is full, is Rolls-Over (default setting) 49 | ### When the EventLog Rolls-Over, all previous events are retriggered 50 | ### Checking the Index, which is unique will prevent old events from displaying again 51 | ### Events are always triggered and processed in order, so no risk in missing events. 52 | if ($EventLogEntry.Index -le $Global:LastEventLogIndex) { return } 53 | $Global:LastEventLogIndex = $EventLogEntry.Index 54 | 55 | ### Check if the Event is from a selected source, ifnot exit 56 | ### The array.Contains ask more performance than the Index check, thats why its second 57 | if (!($Global:EventLogSourcesToMonitor.Contains($EventLogEntry.Source))) { return } 58 | 59 | ### Profit! Print the received event 60 | Write-Host "TimeGenerated : $($EventLogEntry.TimeGenerated)" 61 | Write-Host "EventSource: $($EventLogEntry.Source)" 62 | Write-Host "EntryType : $($EventLogEntry.EntryType)" 63 | Write-Host "Message : " 64 | Write-Host "$($EventLogEntry.Message)" 65 | Write-Host "" 66 | } | Out-Null 67 | 68 | while ($true) 69 | { 70 | Start-Sleep -Seconds 60 71 | } 72 | -------------------------------------------------------------------------------- /generic/Run/Prompt.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [switch]$silent 4 | ) 5 | 6 | function ImportModule([string] $path) { 7 | if (Test-Path $path) { 8 | Import-Module $path -wa SilentlyContinue 9 | } 10 | } 11 | 12 | $isPsCore = [System.Version]$PSVersionTable.PSVersion -ge [System.Version]"7.4.1" 13 | 14 | . "c:\run\ServiceSettings.ps1" 15 | if ($PSScriptRoot -eq "c:\run" -and (Test-Path "c:\run\my\prompt.ps1")) { 16 | . "c:\run\my\prompt.ps1" 17 | } 18 | else { 19 | $serviceTierFolder = (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName 20 | if ($isPsCore -and (Test-Path "$serviceTierFolder\Admin")) { 21 | ImportModule "$serviceTierFolder\Admin\Microsoft.Dynamics.Nav.Management.psm1" 22 | ImportModule "$serviceTierFolder\Admin\Microsoft.BusinessCentral.Management.psd1" 23 | ImportModule "$serviceTierFolder\Admin\Microsoft.BusinessCentral.Apps.Management.dll" 24 | if (Test-Path 'c:\run\my\pscoreoverrides.ps1') { 25 | . 'c:\run\my\pscoreoverrides.ps1' 26 | } 27 | else { 28 | . 'c:\run\pscoreoverrides.ps1' 29 | } 30 | } 31 | else { 32 | if (Test-Path "$serviceTierFolder\Microsoft.Dynamics.Nav.Management.psm1") { 33 | Import-Module "$serviceTierFolder\Microsoft.Dynamics.Nav.Management.psm1" -wa SilentlyContinue 34 | } 35 | else { 36 | Import-Module "$serviceTierFolder\Microsoft.Dynamics.Nav.Management.dll" -wa SilentlyContinue 37 | } 38 | $serviceTierFolder = (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName 39 | $roleTailoredClientItem = Get-Item "C:\Program Files (x86)\Microsoft Dynamics NAV\*\RoleTailored Client" -ErrorAction Ignore 40 | if ($roleTailoredClientItem) { 41 | $roleTailoredClientFolder = $roleTailoredClientItem.FullName 42 | $NavIde = Join-Path $roleTailoredClientFolder "finsql.exe" 43 | if (!(Test-Path $NavIde)) { 44 | $NavIde = "" 45 | } 46 | if (Test-Path "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Ide.psm1") { 47 | Import-Module "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Ide.psm1" -wa SilentlyContinue 48 | } 49 | if (Test-Path "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1") { 50 | Import-Module "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1" -wa SilentlyContinue 51 | } 52 | elseif (Test-Path "$serviceTierFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1") { 53 | Import-Module "$serviceTierFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1" -wa SilentlyContinue 54 | } 55 | if (Test-Path "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Tools.psd1") { 56 | Import-Module "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Tools.psd1" -wa SilentlyContinue 57 | } 58 | elseif (Test-Path "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Tools.dll") { 59 | Import-Module "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Apps.Tools.dll" -wa SilentlyContinue 60 | } 61 | if (Test-Path "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Model.Tools.psd1") { 62 | Import-Module "$roleTailoredClientFolder\Microsoft.Dynamics.Nav.Model.Tools.psd1" -wa SilentlyContinue 63 | } 64 | } 65 | else { 66 | $roleTailoredClientFolder = "" 67 | $NavIde = "" 68 | if (Test-Path "$serviceTierFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1") { 69 | Import-Module "$serviceTierFolder\Microsoft.Dynamics.Nav.Apps.Management.psd1" -wa SilentlyContinue 70 | } 71 | elseif (Test-Path "$serviceTierFolder\Management\Microsoft.Dynamics.Nav.Apps.Management.psd1") { 72 | Import-Module "$serviceTierFolder\Management\Microsoft.Dynamics.Nav.Apps.Management.psd1" -wa SilentlyContinue 73 | } 74 | } 75 | } 76 | 77 | cd "c:\run" 78 | if (!$silent) { 79 | if ($NavIde) { 80 | Write-Host -ForegroundColor Green "Welcome to the NAV Container PowerShell prompt" 81 | } 82 | else { 83 | Write-Host -ForegroundColor Green "Welcome to the Business Central Container PowerShell prompt" 84 | } 85 | Write-Host 86 | } 87 | } -------------------------------------------------------------------------------- /generic/Run/SQLConf.ini: -------------------------------------------------------------------------------- 1 | ;SQL Server 2019 Configuration File 2 | [OPTIONS] 3 | ACTION="Install" 4 | SUPPRESSPRIVACYSTATEMENTNOTICE="True" 5 | ENU="True" 6 | QUIET="True" 7 | SUPPRESSPAIDEDITIONNOTICE="True" 8 | FEATURES=SQLEngine,FullText 9 | INSTANCENAME="SQLEXPRESS" 10 | INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server" 11 | INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server" 12 | INSTANCEID="SQLEXPRESS" 13 | SQLTELSVCACCT="NT Service\SQLTELEMETRY$SQLEXPRESS" 14 | SQLTELSVCSTARTUPTYPE="Manual" 15 | INSTANCEDIR="C:\Program Files\Microsoft SQL Server" 16 | AGTSVCACCOUNT="NT AUTHORITY\System" 17 | AGTSVCSTARTUPTYPE="Disabled" 18 | SQLSVCSTARTUPTYPE="Manual" 19 | FILESTREAMLEVEL="0" 20 | SQLMAXDOP="0" 21 | ENABLERANU="False" 22 | SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS" 23 | SQLSVCACCOUNT="NT AUTHORITY\System" 24 | SQLSYSADMINACCOUNTS="BUILTIN\Administrators" 25 | ADDCURRENTUSERASSQLADMIN="False" 26 | TCPENABLED="1" 27 | NPENABLED="0" 28 | BROWSERSVCSTARTUPTYPE="Manual" 29 | SQLMAXMEMORY="2147483647" 30 | SQLMINMEMORY="0" 31 | -------------------------------------------------------------------------------- /generic/Run/SetupAddIns.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $runPath 3 | # $serviceTierFolder 4 | # $roleTailoredClientFolder 5 | # 6 | # OUTPUT 7 | # 8 | 9 | $AddinsFolder = (Join-Path $runPath "Add-ins") 10 | if (Test-Path $AddinsFolder -PathType Container) { 11 | copy-item -Path (Join-Path $AddinsFolder "*") -Destination (Join-Path $serviceTierFolder "Add-ins") -Recurse 12 | if ($roleTailoredClientFolder -and (Test-Path (Join-Path $roleTailoredClientFolder "Add-ins"))) { 13 | copy-item -Path (Join-Path $AddinsFolder "*") -Destination (Join-Path $roleTailoredClientFolder "Add-ins") -Recurse 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /generic/Run/SetupCertificate.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $runPath 3 | # 4 | # OUTPUT 5 | # $certificateCerFile (if self signed) 6 | # $certificateThumbprint 7 | # $dnsIdentity 8 | # 9 | 10 | Write-Host "Creating Self Signed Certificate" 11 | $cert = New-SelfSignedCertificate -DnsName @($publicDnsName, $hostName) -CertStoreLocation Cert:\LocalMachine\My 12 | 13 | $certificatePfxPassword = Get-RandomPassword 14 | $SecurePfxPassword = ConvertTo-SecureString -String $certificatePfxPassword -AsPlainText -Force 15 | 16 | $certificatePfxFile = Join-Path $runPath "certificate.pfx" 17 | $certificateCerFile = Join-Path $runPath "certificate.cer" 18 | 19 | Export-PfxCertificate -Cert $cert -FilePath $certificatePfxFile -Password $SecurePfxPassword | Out-Null 20 | Export-Certificate -Cert $cert -FilePath $CertificateCerFile | Out-Null 21 | 22 | $certificateThumbprint = $cert.Thumbprint 23 | Write-Host "Self Signed Certificate Thumbprint $certificateThumbprint" 24 | Import-PfxCertificate -Password $SecurePfxPassword -FilePath $certificatePfxFile -CertStoreLocation "cert:\localMachine\TrustedPeople" | Out-Null 25 | 26 | $dnsidentity = $cert.GetNameInfo('SimpleName',$false) 27 | Write-Host "DNS identity $dnsidentity" 28 | -------------------------------------------------------------------------------- /generic/Run/SetupConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $protocol 4 | # $publicDnsName 5 | # $ServiceTierFolder 6 | # $navUseSSL 7 | # $servicesUseSSL 8 | # $certificateThumbprint 9 | # 10 | # OUTPUT 11 | # 12 | 13 | Write-Host "Modifying Service Tier Config File with Instance Specific Settings" 14 | $CustomConfigFile = Join-Path $ServiceTierFolder "CustomSettings.config" 15 | $CustomConfig = [xml](Get-Content $CustomConfigFile) 16 | 17 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value = $databaseServer 18 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value = $databaseInstance 19 | $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value = "$databaseName" 20 | $customConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value = "$serverInstance" 21 | $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value = "$managementServicesPort" 22 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesPort']").Value = "$clientServicesPort" 23 | $customConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesPort']").Value = "$soapServicesPort" 24 | $customConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesPort']").Value = "$oDataServicesPort" 25 | $customConfig.SelectSingleNode("//appSettings/add[@key='DefaultClient']").Value = "Web" 26 | $customConfig.SelectSingleNode("//appSettings/add[@key='Multitenant']").Value = "$multitenant" 27 | if (!$multitenant -and "$applicationInsightsInstrumentationKey" -ne "") { 28 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApplicationInsightsInstrumentationKey']").Value = "$applicationInsightsInstrumentationKey" 29 | } 30 | 31 | $taskSchedulerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']") -ne $null) 32 | if ($taskSchedulerKeyExists) { 33 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "false" 34 | } 35 | 36 | $developerServicesKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']") -ne $null) 37 | if ($developerServicesKeyExists) { 38 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesPort']").Value = "$developerServicesPort" 39 | $customConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesEnabled']").Value = "true" 40 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='DeveloperServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 41 | } 42 | 43 | $SnapshotDebuggerKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']") -ne $null) 44 | if ($SnapshotDebuggerKeyExists) { 45 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesPort']").Value = "$snapshotDebuggerServicesPort" 46 | $customConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerEnabled']").Value = "true" 47 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SnapshotDebuggerServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 48 | } 49 | 50 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value = $auth 51 | if ($developerServicesKeyExists) { 52 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/" 53 | } else { 54 | $publicWebBaseUrl = "$protocol$publicDnsName$publicwebClientPort/$WebServerInstance/WebClient/" 55 | } 56 | if ($WebClient -ne "N") { 57 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value = $publicWebBaseUrl 58 | } 59 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicSOAPBaseUrl']").Value = "$protocol${publicDnsName}:$publicSoapPort/$ServerInstance/WS/" 60 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicODataBaseUrl']").Value = "$protocol${publicDnsName}:$publicODataPort/$ServerInstance/OData" 61 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='PublicWinBaseUrl']").Value = "DynamicsNAV://${publicDnsName}:$publicWinClientPort/$ServerInstance/" 62 | if ($navUseSSL) { 63 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateThumbprint']").Value = "$certificateThumbprint" 64 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServicesCertificateValidationEnabled']").Value = "false" 65 | } 66 | 67 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='SOAPServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 68 | $CustomConfig.SelectSingleNode("//appSettings/add[@key='ODataServicesSSLEnabled']").Value = $servicesUseSSL.ToString().ToLower() 69 | 70 | $enableSymbolLoadingAtServerStartupKeyExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']") -ne $null) 71 | if ($enableSymbolLoadingAtServerStartupKeyExists) { 72 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableSymbolLoadingAtServerStartup']").Value = "$($enableSymbolLoadingAtServerStartup -eq $true)" 73 | } 74 | 75 | $apiServicesEnabledExists = ($customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']") -ne $null) 76 | if (($enableApiServices -ne $null) -and $apiServicesEnabledExists) { 77 | $customConfig.SelectSingleNode("//appSettings/add[@key='ApiServicesEnabled']").Value = "$($enableApiServices -eq $true)" 78 | } 79 | 80 | if ($isBcSandbox) { 81 | $customConfig.SelectSingleNode("//appSettings/add[@key='EnableTaskScheduler']").Value = "true" 82 | Set-ConfigSetting -customSettings "TenantEnvironmentType=Sandbox" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 83 | Set-ConfigSetting -customSettings "EnableSaasExtensionInstall=true" -parentPath "//appSettings" -leafName "add" -customConfig $customConfig -silent 84 | } 85 | 86 | if ($customNavSettings -ne "") { 87 | Write-Host "Modifying Service Tier Config File with settings from environment variable" 88 | Set-ConfigSetting -customSettings $customNavSettings -parentPath "//appSettings" -leafName "add" -customConfig $CustomConfig 89 | } 90 | 91 | if ($auth -eq "AccessControlService") { 92 | if ($appIdUri -eq "") { 93 | $appIdUri = "$publicWebBaseUrl" 94 | } 95 | if ("$aadTenant" -eq "") { 96 | $aadTenant = "Common" 97 | } 98 | if ($federationMetadata -eq "") { 99 | $federationMetadata = "https://login.microsoftonline.com/$aadTenant/FederationMetadata/2007-06/FederationMetadata.xml" 100 | } 101 | if ($federationLoginEndpoint -eq "") { 102 | $federationLoginEndpoint = "https://login.microsoftonline.com/$aadTenant/wsfed?wa=wsignin1.0%26wtrealm=$appIdUri" 103 | } 104 | 105 | $customConfig.SelectSingleNode("//appSettings/add[@key='AppIdUri']").Value = $appIdUri 106 | $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesFederationMetadataLocation']").Value = $federationMetadata 107 | if ($customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']") -ne $null) { 108 | $customConfig.SelectSingleNode("//appSettings/add[@key='WSFederationLoginEndpoint']").Value = $federationLoginEndpoint 109 | } 110 | } 111 | 112 | $CustomConfig.Save($CustomConfigFile) 113 | 114 | $managementServicesPort,$soapServicesPort,$oDataServicesPort,$developerServicesPort,$SnapshotDebuggerServicesPort | % { 115 | netsh http add urlacl url=$protocol+:$_/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 116 | if ($servicesUseSSL) { 117 | netsh http add sslcert ipport=0.0.0.0:$_ certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 118 | } 119 | } 120 | 121 | if ($navUseSSL) { 122 | netsh http add urlacl url=https://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 123 | netsh http add sslcert ipport=0.0.0.0:$clientServicesPort certhash=$certificateThumbprint appid="{00112233-4455-6677-8899-AABBCCDDEEFF}" | Out-Null 124 | } else { 125 | netsh http add urlacl url=http://+:$clientServicesPort/$ServerInstance user="NT AUTHORITY\SYSTEM" | Out-Null 126 | } 127 | 128 | if ($developerServicesKeyExists) { 129 | $serverConfigFile = Join-Path $ServiceTierFolder "Microsoft.Dynamics.Nav.Server.exe.config" 130 | $serverConfig = [xml](Get-Content -Path $serverConfigFile) 131 | $legacySecurityPolicyNode = $serverConfig.SelectSingleNode("//configuration/runtime/NetFx40_LegacySecurityPolicy") 132 | if ($legacySecurityPolicyNode) { 133 | $legacySecurityPolicyNode.enabled = "false" 134 | } 135 | $serverConfig.Save($serverConfigFile) 136 | } 137 | -------------------------------------------------------------------------------- /generic/Run/SetupDatabase.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $restartingInstance (optional) 3 | # $bakFile (optional) 4 | # $appBacpac and tenantBacpac (optional) 5 | # $databaseCredentials (optional) 6 | # 7 | # OUTPUT 8 | # $databaseServer 9 | # $databaseInstance 10 | # $databaseName 11 | # 12 | 13 | if ($restartingInstance) { 14 | 15 | # Nothing to do 16 | 17 | } elseif ($bakfile -ne "") { 18 | 19 | # .bak file specified - restore and use 20 | # if bakfile specified, download, restore and use 21 | 22 | if ($bakfile.StartsWith("https://") -or $bakfile.StartsWith("http://")) 23 | { 24 | $bakfileurl = $bakfile 25 | $databaseFile = (Join-Path $runPath "mydatabase.bak") 26 | Write-Host "Downloading database backup file '$bakfileurl'" 27 | (New-Object System.Net.WebClient).DownloadFile($bakfileurl, $databaseFile) 28 | 29 | } else { 30 | 31 | Write-Host "Using Database .bak file '$bakfile'" 32 | if (!(Test-Path -Path $bakfile -PathType Leaf)) { 33 | Write-Error "ERROR: Database Backup File not found." 34 | Write-Error "The file must be uploaded to the container or available on a share." 35 | exit 1 36 | } 37 | $databaseFile = $bakFile 38 | } 39 | 40 | # Restore database 41 | $databaseFolder = "c:\databases\my" 42 | 43 | if (!(Test-Path -Path $databaseFolder -PathType Container)) { 44 | New-Item -Path $databaseFolder -itemtype Directory | Out-Null 45 | } 46 | 47 | $databaseServerInstance = $databaseServer 48 | if ("$databaseInstance" -ne "") { 49 | $databaseServerInstance += "\$databaseInstance" 50 | } 51 | Write-Host "Using database server $databaseServerInstance" 52 | 53 | if (!$multitenant) { 54 | New-NAVDatabase -DatabaseServer $databaseServer ` 55 | -DatabaseInstance $databaseInstance ` 56 | -DatabaseName "$databaseName" ` 57 | -FilePath "$databaseFile" ` 58 | -DestinationPath "$databaseFolder" ` 59 | -Timeout $SqlTimeout | Out-Null 60 | 61 | Set-DatabaseCompatibilityLevel -DatabaseServer $databaseServer -DatabaseInstance $databaseInstance -DatabaseName $databaseName 62 | 63 | if ($roleTailoredClientFolder -and (Test-Path "$roleTailoredClientFolder\finsql.exe")) { 64 | Start-Process -FilePath "$roleTailoredClientFolder\finsql.exe" -ArgumentList "Command=upgradedatabase, Database=$databaseName, ServerName=$databaseServerInstance, ntauthentication=1, logFile=c:\run\errorlog.txt" -Wait 65 | } 66 | else { 67 | Invoke-NAVApplicationDatabaseConversion -databaseServer $databaseServerInstance -databaseName $databaseName -Force | Out-Null 68 | } 69 | } else { 70 | New-NAVDatabase -DatabaseServer $databaseServer ` 71 | -DatabaseInstance $databaseInstance ` 72 | -DatabaseName "tenant" ` 73 | -FilePath "$databaseFile" ` 74 | -DestinationPath "$databaseFolder" ` 75 | -Timeout $SqlTimeout | Out-Null 76 | 77 | Set-DatabaseCompatibilityLevel -DatabaseServer $databaseServer -DatabaseInstance $databaseInstance -DatabaseName "tenant" 78 | 79 | if ($roleTailoredClientFolder -and (Test-Path "$roleTailoredClientFolder\finsql.exe")) { 80 | Start-Process -FilePath "$roleTailoredClientFolder\finsql.exe" -ArgumentList "Command=upgradedatabase, Database=$databaseName, ServerName=$databaseServerInstance, ntauthentication=1, logFile=c:\run\errorlog.txt" -Wait 81 | } 82 | else { 83 | Invoke-NAVApplicationDatabaseConversion -databaseServer $databaseServerInstance -databaseName "tenant" -force | Out-Null 84 | } 85 | 86 | Write-Host "Exporting Application to $DatabaseName" 87 | Invoke-sqlcmd -serverinstance $databaseServerInstance -Database "tenant" -query 'CREATE USER "NT AUTHORITY\SYSTEM" FOR LOGIN "NT AUTHORITY\SYSTEM";' 88 | Export-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -DestinationDatabaseName $databaseName -Force -ServiceAccount 'NT AUTHORITY\SYSTEM' | Out-Null 89 | Write-Host "Removing Application from tenant" 90 | Remove-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -Force | Out-Null 91 | } 92 | 93 | } elseif ("$appBacpac" -ne "") { 94 | 95 | # appBacpac and tenantBacpac specified - restore and use 96 | 97 | if (Test-NavDatabase -DatabaseName "tenant") { 98 | Remove-NavDatabase -DatabaseName "tenant" 99 | } 100 | if (Test-NavDatabase -DatabaseName "default") { 101 | Remove-NavDatabase -DatabaseName "default" 102 | } 103 | 104 | $dbName = "app" 105 | $appBacpac, $tenantBacpac | % { 106 | if ($_) { 107 | if ($_.StartsWith("https://") -or $_.StartsWith("http://")) 108 | { 109 | $databaseFile = (Join-Path $runPath "${dbName}.bacpac") 110 | Write-Host "Downloading ${dbName}.bacpac" 111 | (New-Object System.Net.WebClient).DownloadFile($_, $databaseFile) 112 | } else { 113 | if (!(Test-Path -Path $_ -PathType Leaf)) { 114 | Write-Error "ERROR: Database Backup File not found." 115 | Write-Error "The file must be uploaded to the container or available on a share." 116 | exit 1 117 | } 118 | $databaseFile = $_ 119 | } 120 | Restore-BacpacWithRetry -Bacpac $databaseFile -DatabaseName $dbName 121 | } 122 | $dbName = "tenant" 123 | } 124 | 125 | $databaseServer = "localhost" 126 | $databaseInstance = "SQLEXPRESS" 127 | $databaseName = "app" 128 | 129 | if ("$licenseFile" -eq "") { 130 | $licenseFile = Join-Path $serviceTierFolder "Cronus.flf" 131 | } 132 | 133 | } elseif ($databaseCredentials) { 134 | 135 | if (Test-Path $myPath -PathType Container) { 136 | $EncryptionKeyFile = Join-Path $myPath 'DynamicsNAV.key' 137 | } else { 138 | $EncryptionKeyFile = Join-Path $runPath 'DynamicsNAV.key' 139 | } 140 | if (!(Test-Path $EncryptionKeyFile -PathType Leaf)) { 141 | New-NAVEncryptionKey -KeyPath $EncryptionKeyFile -Password $EncryptionSecurePassword -Force | Out-Null 142 | } 143 | 144 | Set-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName "EnableSqlConnectionEncryption" -KeyValue "true" -WarningAction SilentlyContinue 145 | Set-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName "TrustSQLServerCertificate" -KeyValue "true" -WarningAction SilentlyContinue 146 | 147 | $databaseServerInstance = $databaseServer 148 | if ("$databaseInstance" -ne "") { 149 | $databaseServerInstance += "\$databaseInstance" 150 | } 151 | Write-Host "Import Encryption Key" 152 | Import-NAVEncryptionKey -ServerInstance $ServerInstance ` 153 | -ApplicationDatabaseServer $databaseServerInstance ` 154 | -ApplicationDatabaseCredentials $DatabaseCredentials ` 155 | -ApplicationDatabaseName $DatabaseName ` 156 | -KeyPath $EncryptionKeyFile ` 157 | -Password $EncryptionSecurePassword ` 158 | -WarningAction SilentlyContinue ` 159 | -Force 160 | 161 | Set-NavServerConfiguration -serverinstance $ServerInstance -databaseCredentials $DatabaseCredentials -WarningAction SilentlyContinue 162 | 163 | } elseif ($databaseServer -eq "localhost" -and $databaseInstance -eq "SQLEXPRESS" -and $multitenant) { 164 | 165 | if (!(Test-NavDatabase -DatabaseName "tenant")) { 166 | Copy-NavDatabase -SourceDatabaseName $databaseName -DestinationDatabaseName "tenant" 167 | Remove-NavDatabase -DatabaseName $databaseName 168 | Write-Host "Exporting Application to $DatabaseName" 169 | Invoke-sqlcmd -serverinstance "$DatabaseServer\$DatabaseInstance" -Database tenant -query 'CREATE USER "NT AUTHORITY\SYSTEM" FOR LOGIN "NT AUTHORITY\SYSTEM";' 170 | Export-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -DestinationDatabaseName $databaseName -Force -ServiceAccount 'NT AUTHORITY\SYSTEM' | Out-Null 171 | Write-Host "Removing Application from tenant" 172 | Remove-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -Force | Out-Null 173 | } 174 | } 175 | 176 | -------------------------------------------------------------------------------- /generic/Run/SetupFileShare.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $httpPath 3 | # $runPath 4 | # $certificateCerFile (optional) 5 | # $servicesUseSSL (optional) 6 | # 7 | # OUTPUT 8 | # 9 | 10 | if ($certificateCerFile -and $servicesUseSSL) { 11 | Copy-Item -Path $certificateCerFile -Destination $httpPath 12 | } 13 | Copy-Item -Path "$runPath\*.vsix" -Destination $httpPath 14 | -------------------------------------------------------------------------------- /generic/Run/SetupGeneric2.ps1: -------------------------------------------------------------------------------- 1 | Write-Host "FilesOnly=$env:filesOnly" 2 | Write-Host "only24=$env:only24" 3 | $filesonly = $env:filesonly -eq 'true' 4 | $only24 = $env:only24 -eq 'true' 5 | if (-not $filesonly) { 6 | Write-Host 'Installing SqlServer Module in PowerShell 7' 7 | pwsh -Command 'Install-Module -Name SqlServer -RequiredVersion 22.2.0 -Scope AllUsers -Force' 8 | Write-Host 'Done' 9 | } 10 | -------------------------------------------------------------------------------- /generic/Run/SetupLicense.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $serviceTierFolder 3 | # $licenseFile (optional) 4 | # 5 | # OUTPUT 6 | # 7 | 8 | if ($restartingInstance) { 9 | 10 | # Nothing to do 11 | 12 | } elseif ($licensefile -ne "") { 13 | 14 | if ($licensefile.StartsWith("https://") -or $licensefile.StartsWith("http://")) 15 | { 16 | $licensefileurl = $licensefile 17 | $licensefile = (Join-Path $runPath "license.flf") 18 | Write-Host "Downloading license file '$licensefileurl'" 19 | (New-Object System.Net.WebClient).DownloadFile($licensefileurl, $licensefile) 20 | } else { 21 | Write-Host "Using license file '$licensefile'" 22 | if (!(Test-Path -Path $licensefile -PathType Leaf)) { 23 | Write-Error "ERROR: License File not found." 24 | Write-Error "The file must be uploaded to the container or available on a share." 25 | exit 1 26 | } 27 | } 28 | Write-Host "Import License" 29 | Import-NAVServerLicense -LicenseData ([Byte[]]$(Get-Content -Path $licensefile -Encoding Byte)) -ServerInstance $ServerInstance -Database NavDatabase -WarningAction SilentlyContinue 30 | } 31 | -------------------------------------------------------------------------------- /generic/Run/SetupNavUsers.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $username (optional) 4 | # $securePassword (optional) 5 | # 6 | # OUTPUT 7 | # 8 | 9 | if ($auth -eq "Windows") { 10 | if ($username -ne "") { 11 | if (!(Get-NAVServerUser -ServerInstance $ServerInstance @tenantParam -ErrorAction Ignore | Where-Object { $_.UserName.EndsWith("\$username", [System.StringComparison]::InvariantCultureIgnoreCase) -or $_.UserName -eq $username })) { 12 | Write-Host "Creating SUPER user" 13 | New-NavServerUser -ServerInstance $ServerInstance @tenantParam -WindowsAccount $username 14 | New-NavServerUserPermissionSet -ServerInstance $ServerInstance @tenantParam -WindowsAccount $username -PermissionSetId SUPER 15 | } 16 | } 17 | } else { 18 | if (!(Get-NAVServerUser -ServerInstance $ServerInstance @tenantParam -ErrorAction Ignore | Where-Object { $_.UserName -eq $username })) { 19 | Write-Host "Creating SUPER user" 20 | New-NavServerUser -ServerInstance $ServerInstance @tenantParam -Username $username -Password $securePassword -AuthenticationEMail $authenticationEMail 21 | New-NavServerUserPermissionSet -ServerInstance $ServerInstance @tenantParam -username $username -PermissionSetId SUPER 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /generic/Run/SetupSqlUsers.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $databaseServer 4 | # $username (optional) 5 | # $securePassword (optional) 6 | # 7 | # OUTPUT 8 | # 9 | 10 | if ($securePassword) { 11 | Write-Host "Setting SA Password and enabling SA" 12 | $sqlcmd = "ALTER LOGIN sa with password='" + ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)).Replace('"','""').Replace('''','''''')) + "',CHECK_POLICY = OFF;ALTER LOGIN sa ENABLE;" 13 | Invoke-SqlCmd -ServerInstance "$databaseServer\$databaseInstance" -QueryTimeout 0 -ErrorAction Stop -Query $sqlcmd 14 | 15 | if ($auth -ne "Windows" -and $username -ne "") { 16 | Write-Host "Creating $username as SQL User and add to sysadmin" 17 | $sqlcmd = 18 | "IF NOT EXISTS 19 | (SELECT name 20 | FROM master.sys.server_principals 21 | WHERE name = '$username') 22 | BEGIN 23 | CREATE LOGIN [$username] with password='" + ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)).Replace('"','""').Replace('''','''''')) + "',CHECK_POLICY = OFF 24 | EXEC sp_addsrvrolemember '$username', 'sysadmin' 25 | END 26 | 27 | ALTER LOGIN [$username] ENABLE 28 | GO" 29 | 30 | Invoke-SqlCmd -ServerInstance "$databaseServer\$databaseInstance" -QueryTimeout 0 -ErrorAction Stop -Query $sqlcmd 31 | } 32 | } else { 33 | if ($auth -eq "Windows" -and $username -ne "") { 34 | Write-Host "Adding $username to sysadmin" 35 | $sqlcmd = 36 | "IF NOT EXISTS 37 | (SELECT name 38 | FROM master.sys.server_principals 39 | WHERE name = '$username') 40 | BEGIN 41 | CREATE LOGIN [$username] FROM WINDOWS 42 | EXEC sp_addsrvrolemember '$username', 'sysadmin' 43 | END 44 | 45 | ALTER LOGIN [$username] ENABLE 46 | GO" 47 | 48 | Invoke-SqlCmd -ServerInstance "$databaseServer\$databaseInstance" -QueryTimeout 0 -ErrorAction Stop -Query $sqlcmd 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /generic/Run/SetupTenant.ps1: -------------------------------------------------------------------------------- 1 | if ($newPublicDnsName -and $databaseServer -eq "localhost" -and $databaseInstance -eq "SQLEXPRESS") { 2 | 3 | if (!(Test-NavDatabase -DatabaseName $TenantId)) { 4 | Write-Host "Copying template database" 5 | Copy-NavDatabase -SourceDatabaseName "tenant" -DestinationDatabaseName $TenantId 6 | } 7 | else { 8 | Write-Host "Dismounting Tenant" 9 | Dismount-NavTenant -ServerInstance $ServerInstance -Tenant $TenantId -Force | Out-Null 10 | } 11 | 12 | $hostname = hostname 13 | $dotidx = $hostname.indexOf('.') 14 | if ($dotidx -eq -1) { $dotidx = $hostname.Length } 15 | $tenantHostname = $hostname.insert($dotidx,"-$tenantId") 16 | $alternateId = @($tenantHostname) 17 | 18 | if ($applicationInsightsInstrumentationKey) { 19 | Write-Host "Mounting Tenant with ApplicationInsightsInstrumentationKey" 20 | } 21 | else { 22 | Write-Host "Mounting Tenant" 23 | } 24 | $parameters = @{ 25 | "ServerInstance" = $ServerInstance 26 | "TenantId" = $TenantId 27 | "DatabaseName" = $TenantId 28 | "AlternateId" = $alternateId 29 | "applicationInsightsInstrumentationKey" = $applicationInsightsInstrumentationKey 30 | } 31 | if ($AuthenticationEmail) { 32 | $aadTenantId = "$env:aadTenant" 33 | if ($aadTenantId -eq "" -or $aadTenantId -eq "common") { 34 | $aadTenantId = $AuthenticationEmail.Split('@')[1] 35 | } 36 | $parameters += @{ 37 | "AadTenantId" = $aadTenantId 38 | } 39 | Write-Host "Setting AadTenantId to $aadTenantId" 40 | } 41 | Mount-NavDatabase @parameters 42 | $tenantStartTime = [DateTime]::Now 43 | while ([DateTime]::Now.Subtract($tenantStartTime).TotalSeconds -le 60) { 44 | $tenantInfo = Get-NAVTenant -ServerInstance $ServerInstance -Tenant $TenantId 45 | if ($tenantInfo.State -eq "Operational") { break } 46 | Start-Sleep -Seconds 1 47 | } 48 | Write-Host "Tenant is $($TenantInfo.State)" 49 | } -------------------------------------------------------------------------------- /generic/Run/SetupUrls.ps1: -------------------------------------------------------------------------------- 1 | $sql2019url = 'https://aka.ms/bcdocker-Sql2019Url' 2 | 3 | # https://learn.microsoft.com/en-us/troubleshoot/sql/releases/download-and-install-latest-updates#latest-updates-available-for-currently-supported-versions-of-sql-server 4 | # Click the link under latest cumulative update including the latest GDR update (NOT the link under latest GDR) 5 | # In the KB article, click Method 3: Microsoft Download Center -> Download Pakcage now -> Download and right click "click here to download manually" -> Copy link address 6 | # The file is around 900Mb (GDR update alone is smaller) 7 | $sql2019LatestCuUrl = 'https://aka.ms/bcdocker-Sql2019LatestCuUrl' 8 | 9 | # https://dotnet.microsoft.com/en-us/download/dotnet/6.0 - grab the direct link behind ASP.NET Core Runtime Windows -> Hosting Bundle 10 | $dotNet6url = 'https://aka.ms/bcdocker-DotNet6Url' 11 | 12 | # https://dotnet.microsoft.com/en-us/download/dotnet/8.0 - grab the direct link behind ASP.NET Core Runtime Windows -> Hosting Bundle 13 | $dotNet8url = 'https://aka.ms/bcdocker-DotNet8Url' 14 | 15 | # https://github.com/PowerShell/PowerShell/releases - grab the latest PowerShell-7.4.x-win-x64.msi link 16 | $powerShell7url = 'https://aka.ms/bcdocker-PowerShell7Url' 17 | 18 | # Misc URLs 19 | $rewriteUrl = 'https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi' 20 | $sqlncliUrl = 'https://download.microsoft.com/download/B/E/D/BED73AAC-3C8A-43F5-AF4F-EB4FEA6C8F3A/ENU/x64/sqlncli.msi' 21 | $vcredist_x86url = 'https://aka.ms/highdpimfc2013x86enu' 22 | $vcredist_x64url = 'https://aka.ms/highdpimfc2013x64enu' 23 | $vcredist_x64_140url = 'https://aka.ms/vs/17/release/vc_redist.x64.exe' 24 | 25 | # NAV/BC Docker Install Files 26 | $navDockerInstallUrl = 'https://bcartifacts-exdbf9fwegejdqak.b02.azurefd.net/prerequisites/nav-docker-install.zip' 27 | $openXmlSdkV25url = 'https://bcartifacts-exdbf9fwegejdqak.b02.azurefd.net/prerequisites/OpenXMLSDKv25.msi' 28 | -------------------------------------------------------------------------------- /generic/Run/SetupWebConfiguration.ps1: -------------------------------------------------------------------------------- 1 | # Changes to Web Client configuration 2 | 3 | if ($isBcSandbox -or $multitenant) { 4 | 5 | $wwwRootPath = Get-WWWRootPath 6 | if ($isBcSandbox) { 7 | write-Host "Enabling Financials User Experience" 8 | $navsettingsFile = Join-Path $wwwRootPath "$webServerInstance\navsettings.json" 9 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 10 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "DefaultApplicationId" -NotePropertyValue "true" -ErrorAction SilentlyContinue 11 | $config.NAVWebSettings.DefaultApplicationId = "FIN" 12 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "Designer" -NotePropertyValue "true" -ErrorAction SilentlyContinue 13 | $config.NAVWebSettings.Designer = $true 14 | $config | ConvertTo-Json | set-content $navSettingsFile 15 | } 16 | 17 | if ($multitenant) { 18 | $webConfigFile = Join-Path $wwwRootPath "$webServerInstance\web.config" 19 | try { 20 | $webConfig = [xml](Get-Content $webConfigFile) 21 | $webConfig.configuration.'system.webServer'.rewrite.rules.GetEnumerator() | % { 22 | Write-Host "Enabling rewrite rule: $($_.Name)" 23 | $_.Enabled = "true" 24 | } 25 | $webConfig.Save($webConfigFile) 26 | } 27 | catch {} 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /generic/Run/SetupWindowsUsers.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $auth 3 | # $username (optional) 4 | # $password (optional) 5 | # 6 | # OUTPUT 7 | # 8 | 9 | if ($auth -eq "Windows") { 10 | if (($securePassword) -and $username -ne "") { 11 | Write-Host "Creating Windows user $username" 12 | New-LocalUser -AccountNeverExpires -PasswordNeverExpires -FullName $username -Name $username -Password $securePassword | Out-Null 13 | Add-LocalGroupMember -Group administrators -Member $username 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /generic/Run/UpdatePowerShellExeConfig.ps1: -------------------------------------------------------------------------------- 1 | $newConfigFile = Join-Path $PSScriptRoot "powershell.exe.config" 2 | if (Test-Path $newConfigFile) { 3 | "C:\Windows\SysWOW64\WindowsPowerShell\v1.0\PowerShell.exe.config","C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe.config" | % { 4 | $existingConfigFile = $_ 5 | if (Test-Path -Path $existingConfigFile) { 6 | $Acl = Get-Acl $existingConfigFile 7 | $Ar = New-Object system.security.accesscontrol.filesystemaccessrule("BUILTIN\Administrators","FullControl","Allow") 8 | $Acl.AddAccessRule($Ar) 9 | Set-Acl $existingConfigFile $Acl 10 | [xml]$existing = Get-Content -Path $existingConfigFile 11 | [xml]$new = Get-Content -Path $newConfigFile 12 | $existing.configuration.AppendChild($existing.ImportNode($new.configuration.runtime,$true)) | Out-Null 13 | $existing.Save($existingConfigFile) 14 | } else { 15 | Copy-Item -Path $newConfigFile -Destination $existingConfigFile -Force 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /generic/Run/buildimage.ps1: -------------------------------------------------------------------------------- 1 | if ("$env:NAVDVDURL" -ne "") { 2 | Write-Host "Downloading NAVDVD" 3 | (New-Object System.Net.WebClient).DownloadFile("$env:NAVDVDURL", "C:\NAVDVD.zip") 4 | [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.Filesystem") | Out-Null 5 | [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\NAVDVD.zip","C:\NAVDVD\") 6 | Remove-Item -Path "C:\NAVDVD.zip" -Force 7 | } 8 | if ("$env:VSIXURL" -ne "") { 9 | Write-Host "Downloading VSIX" 10 | (New-Object System.Net.WebClient).DownloadFile("$env:VSIXURL", ("C:\NAVDVD\"+"$env:VSIXURL".Substring("$env:VSIXURL".LastIndexOf("/")+1))) 11 | } 12 | 13 | $setupVersion = (Get-Item -Path "c:\navdvd\setup.exe").VersionInfo.FileVersion 14 | $versionNo = [Int]::Parse($setupVersion.Split('.')[0]+$setupVersion.Split('.')[1]) 15 | $versionFolder = "" 16 | Get-ChildItem -Path $PSScriptRoot -Directory | where-object { [Int]::TryParse($_.Name, [ref]$null) } | % { [Int]::Parse($_.Name) } | Sort-Object | % { 17 | if ($_ -le $versionNo) { 18 | $versionFolder = Join-Path $PSScriptRoot "$_" 19 | } 20 | } 21 | if ($versionFolder -eq "") { 22 | throw "unable to locate installation folder" 23 | } 24 | 25 | Copy-Item -Path "$versionFolder\*" -Destination $PSScriptRoot -Recurse -Force 26 | 27 | # Remove version specific folders 28 | Get-ChildItem -Path $PSScriptRoot -Directory | where-object { [Int]::TryParse($_.Name, [ref]$null) } | % { 29 | Remove-Item (Join-Path $PSScriptRoot $_.Name) -Recurse -Force -ErrorAction Ignore 30 | } 31 | 32 | . (Join-Path $PSScriptRoot "navinstall.ps1") 33 | 34 | if ("$env:NAVDVDURL" -ne "") { 35 | while (Test-Path -Path "C:\NAVDVD" -PathType Container) { 36 | try { 37 | Remove-Item -Path "C:\NAVDVD" -Force -Recurse 38 | } catch { 39 | Start-sleep -Seconds 5 40 | } 41 | } 42 | } 43 | 44 | Remove-Item "c:\run\navinstall.ps1" -Force 45 | Remove-Item "c:\run\buildimage.ps1" -Force 46 | -------------------------------------------------------------------------------- /generic/Run/powershell.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /generic/Run/pscoreoverrides.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-SqlCmd { SqlServer\Invoke-Sqlcmd @args -Encrypt Optional } 2 | function Backup-SqlDatabase { SqlServer\Backup-SqlDatabase @args -Encrypt Optional } 3 | function Restore-SqlDatabase { SqlServer\Restore-SqlDatabase @args -Encrypt Optional } 4 | -------------------------------------------------------------------------------- /generic/Run/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /generic/build.ps1: -------------------------------------------------------------------------------- 1 | $RootPath = $PSScriptRoot 2 | $ErrorActionPreference = "stop" 3 | Set-StrictMode -Version 2.0 4 | 5 | $isolation = "hyperv" 6 | $filesOnly = $false 7 | $only24 = $false 8 | $image = "mygeneric" 9 | 10 | # Get osVersion to use for the right base image 11 | $genericImage = Get-BestGenericImageName 12 | $osVersion = ($genericImage.Split(':')[1]).Split('-')[0] # should return ltsc2016, ltsc2019 or ltsc2022 13 | if ($osVersion -notlike 'ltsc20??') { 14 | throw "Unexpected osversion" 15 | } 16 | 17 | # Get the latest generic tag to use 18 | $labels = Get-BcContainerImageLabels -imageName $genericImage 19 | $tagVersion = [System.Version]$labels.tag 20 | $genericTag = "$($tagVersion.Major).$($tagVersion.Minor).$($tagVersion.Build).$($tagVersion.Revision+1)" 21 | 22 | # Manual overrides could be like this: 23 | # $osVersion = '10.0.19042.1889' # 20H2 24 | # $osVersion = '10.0.19041.1415' # 2004 25 | # $genericTag = '2.0.0.0' 26 | 27 | $created = [DateTime]::Now.ToUniversalTime().ToString("yyyyMMddHHmm") 28 | 29 | if ($only24) { 30 | $baseimage = "mcr.microsoft.com/windows/servercore:$osVersion" 31 | } 32 | elseif ($osVersion -like 'ltsc*') { 33 | $baseimage = "mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-$osVersion" 34 | } 35 | else { 36 | Write-Host "Using OS Version $osVersion" 37 | $webclient = New-Object System.Net.WebClient 38 | $basetags = (Get-NavContainerImageTags -imageName "mcr.microsoft.com/dotnet/framework/runtime").tags | Where-Object { $_.StartsWith('4.8-20') } | Sort-Object -Descending | Where-Object { -not $_.endswith("-1803") } 39 | $basetags | ForEach-Object { 40 | if (!($baseImage)) { 41 | $manifest = (($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/manifests/$_") | ConvertFrom-Json).history[0].v1Compatibility | ConvertFrom-Json) 42 | Write-Host "$osVersion == $($manifest.'os.version')" 43 | if ($osVersion -eq $manifest.'os.version') { 44 | $baseImage = "mcr.microsoft.com/dotnet/framework/runtime:$_" 45 | Write-Host "$baseImage matches the host OS version" 46 | } 47 | } 48 | } 49 | if (!($baseImage)) { 50 | Write-Error "Unable to find a matching mcr.microsoft.com/dotnet/framework/runtime docker image" 51 | } 52 | } 53 | 54 | Write-Host "Using base image: $baseimage" 55 | 56 | $setupUrlsFile = Join-Path $rootPath "Run/SetupUrls.ps1" 57 | Get-Content -Path $setupUrlsFile | Out-Host 58 | 59 | $dockerfile = Join-Path $RootPath "DOCKERFILE" 60 | if ($only24) { 61 | $image += "-24" 62 | } 63 | if ($filesOnly) { 64 | $dockerfile += '-filesonly' 65 | $image += '-filesonly' 66 | } 67 | docker pull $baseimage 68 | $osversion = docker inspect --format "{{.OsVersion}}" $baseImage 69 | 70 | docker images --format "{{.Repository}}:{{.Tag}}" | % { 71 | if ($_ -eq $image) 72 | { 73 | docker rmi $image -f 74 | } 75 | } 76 | 77 | docker build --build-arg baseimage=$baseimage ` 78 | --build-arg created=$created ` 79 | --build-arg tag="$genericTag" ` 80 | --build-arg osversion="$osversion" ` 81 | --build-arg filesonly="$filesonly" ` 82 | --build-arg only24="$only24" ` 83 | --isolation=$isolation ` 84 | --memory 32G ` 85 | --tag $image ` 86 | --file $dockerfile ` 87 | $RootPath 88 | 89 | if ($LASTEXITCODE -ne 0) { 90 | Write-Error "Failed with exit code $LastExitCode" 91 | } 92 | else { 93 | Write-Host "SUCCESS" 94 | } 95 | -------------------------------------------------------------------------------- /generic/cleanup.ps1: -------------------------------------------------------------------------------- 1 | # Cleanup is intentionally left empty -------------------------------------------------------------------------------- /generic/tag.txt: -------------------------------------------------------------------------------- 1 | 1.0.2.0 2 | -------------------------------------------------------------------------------- /override/SelfSignedCertificateEx/SetupCertificate.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $runPath 3 | # 4 | # OUTPUT 5 | # $certificateCerFile (if self signed) 6 | # $certificateThumbprint 7 | # $dnsIdentity 8 | # 9 | . (Get-MyFilePath "New-SelfSignedCertificateEx.ps1") 10 | 11 | Write-Host "Creating Self Signed Certificate" 12 | $certificatePfxFile = Join-Path $runPath "certificate.pfx" 13 | $certificateCerFile = Join-Path $runPath "certificate.cer" 14 | $certificatePfxPassword = Get-RandomPassword 15 | $SecurePfxPassword = ConvertTo-SecureString -String $certificatePfxPassword -AsPlainText -Force 16 | New-SelfSignedCertificateEx -Subject "CN=$publicDnsName" -SubjectAlternativeName @($publicDnsName) -IsCA $true -Exportable -Path $certificatePfxFile -Password $SecurePfxPassword -SignatureAlgorithm sha256 | Out-Null 17 | $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certificatePfxFile, $certificatePfxPassword) 18 | Export-Certificate -Cert $cert -FilePath $CertificateCerFile | Out-Null 19 | $certificateThumbprint = $cert.Thumbprint 20 | Write-Host "Self Signed Certificate Thumbprint $certificateThumbprint" 21 | Import-PfxCertificate -Password $SecurePfxPassword -FilePath $certificatePfxFile -CertStoreLocation "cert:\localMachine\my" | Out-Null 22 | Import-PfxCertificate -Password $SecurePfxPassword -FilePath $certificatePfxFile -CertStoreLocation "cert:\localMachine\Root" | Out-Null 23 | $dnsidentity = $cert.GetNameInfo('SimpleName',$false) 24 | -------------------------------------------------------------------------------- /override/aci/AdditionalSetup.ps1: -------------------------------------------------------------------------------- 1 | Write-Host "Creating Windows user $username" 2 | New-LocalUser -AccountNeverExpires -PasswordNeverExpires -FullName $username -Name $username -Password $securePassword | Out-Null 3 | Add-LocalGroupMember -Group administrators -Member $username 4 | 5 | Write-Host "Configure WinRM on $publicDnsName with $certificateThumbprint" 6 | winrm create winrm/config/Listener?Address=*+Transport=HTTPS ("@{Hostname=""$publicDnsName""; CertificateThumbprint=""$certificateThumbprint""}") 7 | winrm set winrm/config/service/Auth '@{Basic="true"; Kerberos="false"; Negotiate="false"}' 8 | 9 | -------------------------------------------------------------------------------- /override/attachdb/SetupDatabase.ps1: -------------------------------------------------------------------------------- 1 | if ($restartingInstance) { 2 | # Nothing to do 3 | } 4 | else { 5 | $dbpath = "c:\mydb" 6 | $mdf = (Get-Item (Join-Path $dbpath "*.mdf")).FullName 7 | $ldf = (Get-Item (Join-Path $dbpath "*.ldf")).FullName 8 | $databaseName = "MYCRONUS" 9 | $databaseServer = "localhost" 10 | $databaseInstance = "SQLEXPRESS" 11 | $attachcmd = "USE [master] CREATE DATABASE [$DatabaseName] ON (FILENAME = '$mdf'),(FILENAME = '$ldf') FOR ATTACH" 12 | Write-Host "Attaching database in $mdf/$ldf as $DatabaseName" 13 | Invoke-Sqlcmd -ServerInstance localhost\SQLEXPRESS -QueryTimeOut 0 -ea Stop -Query $attachcmd 14 | } 15 | -------------------------------------------------------------------------------- /override/issue2434/SetupDatabase.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $restartingInstance (optional) 3 | # $bakFile (optional) 4 | # $appBacpac and tenantBacpac (optional) 5 | # $databaseCredentials (optional) 6 | # 7 | # OUTPUT 8 | # $databaseServer 9 | # $databaseInstance 10 | # $databaseName 11 | # 12 | 13 | if ($restartingInstance) { 14 | 15 | # Nothing to do 16 | 17 | } elseif ($bakfile -ne "") { 18 | 19 | # .bak file specified - restore and use 20 | # if bakfile specified, download, restore and use 21 | 22 | if ($bakfile.StartsWith("https://") -or $bakfile.StartsWith("http://")) 23 | { 24 | $bakfileurl = $bakfile 25 | $databaseFile = (Join-Path $runPath "mydatabase.bak") 26 | Write-Host "Downloading database backup file '$bakfileurl'" 27 | (New-Object System.Net.WebClient).DownloadFile($bakfileurl, $databaseFile) 28 | 29 | } else { 30 | 31 | Write-Host "Using Database .bak file '$bakfile'" 32 | if (!(Test-Path -Path $bakfile -PathType Leaf)) { 33 | Write-Error "ERROR: Database Backup File not found." 34 | Write-Error "The file must be uploaded to the container or available on a share." 35 | exit 1 36 | } 37 | $databaseFile = $bakFile 38 | } 39 | 40 | # Restore database 41 | $databaseFolder = "c:\databases\my" 42 | 43 | if (!(Test-Path -Path $databaseFolder -PathType Container)) { 44 | New-Item -Path $databaseFolder -itemtype Directory | Out-Null 45 | } 46 | 47 | $databaseServerInstance = $databaseServer 48 | if ("$databaseInstance" -ne "") { 49 | $databaseServerInstance += "\$databaseInstance" 50 | } 51 | Write-Host "Using database server $databaseServerInstance" 52 | 53 | if (!$multitenant) { 54 | New-NAVDatabase -DatabaseServer $databaseServer ` 55 | -DatabaseInstance $databaseInstance ` 56 | -DatabaseName "$databaseName" ` 57 | -FilePath "$databaseFile" ` 58 | -DestinationPath "$databaseFolder" ` 59 | -Timeout $SqlTimeout | Out-Null 60 | 61 | Set-DatabaseCompatibilityLevel -DatabaseServer $databaseServer -DatabaseInstance $databaseInstance -DatabaseName $databaseName 62 | 63 | if ($roleTailoredClientFolder -and (Test-Path "$roleTailoredClientFolder\finsql.exe")) { 64 | Start-Process -FilePath "$roleTailoredClientFolder\finsql.exe" -ArgumentList "Command=upgradedatabase, Database=$databaseName, ServerName=$databaseServerInstance, ntauthentication=1, logFile=c:\run\errorlog.txt" -Wait 65 | } 66 | else { 67 | Invoke-NAVApplicationDatabaseConversion -databaseServer $databaseServerInstance -databaseName $databaseName -Force | Out-Null 68 | } 69 | } else { 70 | New-NAVDatabase -DatabaseServer $databaseServer ` 71 | -DatabaseInstance $databaseInstance ` 72 | -DatabaseName "tenant" ` 73 | -FilePath "$databaseFile" ` 74 | -DestinationPath "$databaseFolder" ` 75 | -Timeout $SqlTimeout | Out-Null 76 | 77 | Set-DatabaseCompatibilityLevel -DatabaseServer $databaseServer -DatabaseInstance $databaseInstance -DatabaseName "tenant" 78 | 79 | if ($roleTailoredClientFolder -and (Test-Path "$roleTailoredClientFolder\finsql.exe")) { 80 | Start-Process -FilePath "$roleTailoredClientFolder\finsql.exe" -ArgumentList "Command=upgradedatabase, Database=$databaseName, ServerName=$databaseServerInstance, ntauthentication=1, logFile=c:\run\errorlog.txt" -Wait 81 | } 82 | else { 83 | Invoke-NAVApplicationDatabaseConversion -databaseServer $databaseServerInstance -databaseName "tenant" -force | Out-Null 84 | } 85 | 86 | Write-Host "Exporting Application to $DatabaseName" 87 | Invoke-sqlcmd -serverinstance $databaseServerInstance -Database "tenant" -query 'CREATE USER "NT AUTHORITY\SYSTEM" FOR LOGIN "NT AUTHORITY\SYSTEM";' 88 | Export-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -DestinationDatabaseName $databaseName -Force -ServiceAccount 'NT AUTHORITY\SYSTEM' | Out-Null 89 | Write-Host "Removing Application from tenant" 90 | Remove-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -Force | Out-Null 91 | } 92 | 93 | } elseif ("$appBacpac" -ne "") { 94 | 95 | # appBacpac and tenantBacpac specified - restore and use 96 | 97 | if (Test-NavDatabase -DatabaseName "tenant") { 98 | Remove-NavDatabase -DatabaseName "tenant" 99 | } 100 | if (Test-NavDatabase -DatabaseName "default") { 101 | Remove-NavDatabase -DatabaseName "default" 102 | } 103 | 104 | $dbName = "app" 105 | $appBacpac, $tenantBacpac | % { 106 | if ($_) { 107 | if ($_.StartsWith("https://") -or $_.StartsWith("http://")) 108 | { 109 | $databaseFile = (Join-Path $runPath "${dbName}.bacpac") 110 | Write-Host "Downloading ${dbName}.bacpac" 111 | (New-Object System.Net.WebClient).DownloadFile($_, $databaseFile) 112 | } else { 113 | if (!(Test-Path -Path $_ -PathType Leaf)) { 114 | Write-Error "ERROR: Database Backup File not found." 115 | Write-Error "The file must be uploaded to the container or available on a share." 116 | exit 1 117 | } 118 | $databaseFile = $_ 119 | } 120 | Restore-BacpacWithRetry -Bacpac $databaseFile -DatabaseName $dbName 121 | } 122 | $dbName = "tenant" 123 | } 124 | 125 | $databaseServer = "localhost" 126 | $databaseInstance = "SQLEXPRESS" 127 | $databaseName = "app" 128 | 129 | if ("$licenseFile" -eq "") { 130 | $licenseFile = Join-Path $serviceTierFolder "Cronus.flf" 131 | } 132 | 133 | } elseif ($databaseCredentials) { 134 | 135 | if (Test-Path $myPath -PathType Container) { 136 | $EncryptionKeyFile = Join-Path $myPath 'DynamicsNAV.key' 137 | } else { 138 | $EncryptionKeyFile = Join-Path $runPath 'DynamicsNAV.key' 139 | } 140 | if (!(Test-Path $EncryptionKeyFile -PathType Leaf)) { 141 | New-NAVEncryptionKey -KeyPath $EncryptionKeyFile -Password $EncryptionSecurePassword -Force | Out-Null 142 | } 143 | 144 | Set-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName "EnableSqlConnectionEncryption" -KeyValue "true" -WarningAction SilentlyContinue 145 | Set-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName "TrustSQLServerCertificate" -KeyValue "true" -WarningAction SilentlyContinue 146 | 147 | $databaseServerInstance = $databaseServer 148 | if ("$databaseInstance" -ne "") { 149 | $databaseServerInstance += "\$databaseInstance" 150 | } 151 | Write-Host "Import Encryption Key" 152 | Import-NAVEncryptionKey -ServerInstance $ServerInstance ` 153 | -ApplicationDatabaseServer $databaseServerInstance ` 154 | -ApplicationDatabaseCredentials $DatabaseCredentials ` 155 | -ApplicationDatabaseName $DatabaseName ` 156 | -KeyPath $EncryptionKeyFile ` 157 | -Password $EncryptionSecurePassword ` 158 | -WarningAction SilentlyContinue ` 159 | -Force 160 | 161 | Set-NavServerConfiguration -serverinstance $ServerInstance -databaseCredentials $DatabaseCredentials -WarningAction SilentlyContinue 162 | 163 | } elseif ($databaseServer -eq "localhost" -and $databaseInstance -eq "SQLEXPRESS" -and $multitenant) { 164 | 165 | if (!(Test-NavDatabase -DatabaseName "tenant")) { 166 | Copy-NavDatabase -SourceDatabaseName $databaseName -DestinationDatabaseName "tenant" 167 | Remove-NavDatabase -DatabaseName $databaseName 168 | Write-Host "Exporting Application to $DatabaseName" 169 | Invoke-sqlcmd -serverinstance "$DatabaseServer\$DatabaseInstance" -Database tenant -query 'CREATE USER "NT AUTHORITY\SYSTEM" FOR LOGIN "NT AUTHORITY\SYSTEM";' 170 | Export-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -DestinationDatabaseName $databaseName -Force -ServiceAccount 'NT AUTHORITY\SYSTEM' | Out-Null 171 | Write-Host "Removing Application from tenant" 172 | Remove-NAVApplication -DatabaseServer $DatabaseServer -DatabaseInstance $DatabaseInstance -DatabaseName "tenant" -Force | Out-Null 173 | } 174 | } 175 | 176 | -------------------------------------------------------------------------------- /override/issue2434/SetupWebClient.ps1: -------------------------------------------------------------------------------- 1 | # Remove Default Web Site 2 | Get-WebSite | Remove-WebSite 3 | Get-WebBinding | Remove-WebBinding 4 | 5 | $certparam = @{} 6 | if ($servicesUseSSL) { 7 | Write-Host "CertificateThumprint $certificateThumbprint" 8 | $certparam += @{CertificateThumbprint = $certificateThumbprint} 9 | } 10 | 11 | Write-Host "Registering event sources" 12 | "MicrosoftDynamicsNAVClientWebClient","MicrosoftDynamicsNAVClientClientService" | % { 13 | if (-not [System.Diagnostics.EventLog]::SourceExists($_)) { 14 | $frameworkDir =  (Get-Item "HKLM:\SOFTWARE\Microsoft\.NETFramework").GetValue("InstallRoot") 15 | New-EventLog -LogName Application -Source $_ -MessageResourceFile (get-item (Join-Path $frameworkDir "*\EventLogMessages.dll")).FullName 16 | } 17 | } 18 | 19 | Write-Host "Creating DotNetCore Web Server Instance" 20 | $publishFolder = "$webClientFolder\WebPublish" 21 | 22 | $runtimeConfigJsonFile = Join-Path $publishFolder "Prod.Client.WebCoreApp.runtimeconfig.json" 23 | if (Test-Path $runtimeConfigJsonFile) { 24 | $runtimeConfigJson = Get-Content $runtimeConfigJsonFile | ConvertFrom-Json 25 | if (!($runtimeConfigJson.runtimeOptions.configProperties.PSObject.Properties.Name -eq "System.Globalization.UseNls")) { 26 | Add-Member -InputObject $runtimeConfigJson.runtimeOptions.configProperties -NotePropertyName "System.Globalization.UseNls" -NotePropertyValue "true" 27 | $runtimeConfigJson | ConvertTo-Json -Depth 99 | Set-Content $runtimeConfigJsonFile 28 | } 29 | } 30 | 31 | $NAVWebClientManagementModule = "$webClientFolder\Modules\NAVWebClientManagement\NAVWebClientManagement.psm1" 32 | if (!(Test-Path $NAVWebClientManagementModule)) { 33 | $NAVWebClientManagementModule = "$webClientFolder\Scripts\NAVWebClientManagement.psm1" 34 | } 35 | # Replace Copy with Robocopy 36 | $WebManagementModuleSource = Get-Content -Path $NAVWebClientManagementModule -Raw -Encoding UTF8 37 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Copy-Item $SourcePath -Destination $siteRootFolder -Recurse -Container -Force','RoboCopy "$SourcePath" "$siteRootFolder" "*" /e /NFL /NDL /NJH /NJS /nc /ns /np /mt /z /nooffload | Out-Null 38 | Get-ChildItem -Path $SourcePath -Filter "*" -Recurse | ForEach-Object { 39 | $destPath = Join-Path $siteRootFolder $_.FullName.Substring($SourcePath.Length) 40 | while (!(Test-Path $destPath)) { 41 | Write-Host "Waiting for $destPath to be available" 42 | Start-Sleep -Seconds 1 43 | } 44 | }') 45 | $WebManagementModuleSource = $WebManagementModuleSource.Replace('Write-Verbose','Write-Host') 46 | $NAVWebClientManagementModule = "c:\run\my\NAVWebClientManagement.psm1" 47 | Set-Content -Path $NAVWebClientManagementModule -Value $WebManagementModuleSource -Encoding UTF8 48 | 49 | Import-Module $NAVWebClientManagementModule 50 | New-NAVWebServerInstance -PublishFolder $publishFolder ` 51 | -WebServerInstance "$WebServerInstance" ` 52 | -Server "localhost" ` 53 | -ServerInstance "$ServerInstance" ` 54 | -ClientServicesCredentialType $Auth ` 55 | -ClientServicesPort "$clientServicesPort" ` 56 | -WebSitePort $webClientPort @certparam 57 | 58 | $navsettingsFile = Join-Path $wwwRootPath "$WebServerInstance\navsettings.json" 59 | $config = Get-Content $navSettingsFile | ConvertFrom-Json 60 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "RequireSSL" -NotePropertyValue "true" -ErrorAction SilentlyContinue 61 | $config.NAVWebSettings.RequireSSL = $false 62 | Add-Member -InputObject $config.NAVWebSettings -NotePropertyName "PersonalizationEnabled" -NotePropertyValue "true" -ErrorAction SilentlyContinue 63 | $config.NAVWebSettings.PersonalizationEnabled = $true 64 | $config.NAVWebSettings.ManagementServicesPort = $ManagementServicesPort 65 | 66 | if ($customWebSettings -ne "") { 67 | Write-Host "Modifying Web Client config with settings from environment variable" 68 | 69 | $customWebSettingsArray = $customWebSettings -split "," 70 | foreach ($customWebSetting in $customWebSettingsArray) { 71 | $customWebSettingArray = $customWebSetting -split "=" 72 | $customWebSettingKey = $customWebSettingArray[0] 73 | $customWebSettingValue = $customWebSettingArray[1] 74 | if ($config.NAVWebSettings.$customWebSettingKey -eq $null) { 75 | Write-Host "Creating $customWebSettingKey and setting it to $customWebSettingValue" 76 | $config.NAVWebSettings | Add-Member $customWebSettingKey $customWebSettingValue 77 | } else { 78 | Write-Host "Setting $customWebSettingKey to $customWebSettingValue" 79 | $config.NAVWebSettings.$customWebSettingKey = $customWebSettingValue 80 | } 81 | } 82 | } 83 | 84 | $config | ConvertTo-Json | set-content $navSettingsFile 85 | -------------------------------------------------------------------------------- /override/issue7100/setupWebConfiguration.ps1: -------------------------------------------------------------------------------- 1 | $wwwRootPath = Get-WWWRootPath 2 | $webConfigFile = Join-Path $wwwRootPath "$webServerInstance\web.config" 3 | $webconfig = Get-Content -Path $webConfigFile -Raw -Encoding UTF8 4 | $webConfig = $webconfig.Replace('','').Replace('{R:0}?tenant={C:1}','{R:0}?tenant=default') 5 | Set-Content -Path $webConfigFile -Value $webconfig -Encoding UTF8 6 | . 'C:\run\SetupWebConfiguration.ps1' -------------------------------------------------------------------------------- /override/selfsignedcertificate/SetupCertificate.ps1: -------------------------------------------------------------------------------- 1 | # INPUT 2 | # $runPath 3 | # 4 | # OUTPUT 5 | # $certificateCerFile (if self signed) 6 | # $certificateThumbprint 7 | # $dnsIdentity 8 | # 9 | 10 | Write-Host "Creating Self Signed Certificate" 11 | $cert = New-SelfSignedCertificate -DnsName @($publicDnsName, $hostName) -CertStoreLocation Cert:\LocalMachine\My 12 | 13 | $certificatePfxPassword = Get-RandomPassword 14 | $SecurePfxPassword = ConvertTo-SecureString -String $certificatePfxPassword -AsPlainText -Force 15 | 16 | $certificatePfxFile = Join-Path $runPath "certificate.pfx" 17 | $certificateCerFile = Join-Path $runPath "certificate.cer" 18 | 19 | Export-PfxCertificate -Cert $cert -FilePath $certificatePfxFile -Password $SecurePfxPassword | Out-Null 20 | Export-Certificate -Cert $cert -FilePath $CertificateCerFile | Out-Null 21 | 22 | $certificateThumbprint = $cert.Thumbprint 23 | Write-Host "Self Signed Certificate Thumbprint $certificateThumbprint" 24 | #Import-PfxCertificate -Password $SecurePfxPassword -FilePath $certificatePfxFile -CertStoreLocation "cert:\localMachine\Root" | Out-Null 25 | Import-PfxCertificate -Password $SecurePfxPassword -FilePath $certificatePfxFile -CertStoreLocation "cert:\localMachine\TrustedPeople" | Out-Null 26 | 27 | $dnsidentity = $cert.GetNameInfo('SimpleName',$false) 28 | Write-Host "DNS identity $dnsidentity" 29 | --------------------------------------------------------------------------------