microsoft / navcontainerhelper

Official Microsoft repository for BcContainerHelper, a PowerShell module, which makes it easier to work with Business Central Containers on Docker.
MIT License
384 stars 247 forks source link

NavConfigurationException when using AAD with bccontainer #3079

Open gntpet opened 1 year ago

gntpet commented 1 year ago

Describe the issue When users authenticates to bc container, warning message with NavConfigurationException is generated in eventlog Is there some setup missing, or this platform bug?

Scripts used to create container and cause the issue

$version = '22.0.54157.55195'
$url = Get-BCArtifactUrl -type OnPrem -country w1 -version $version
$cred = (Get-StoredCredential gps)
$containerName = 'baseaad'

New-NavContainer `
-accept_eula `
-containerName $containerName `
-artifactUrl $url `
-isolation 'hyperv' `
-auth AAD `
-updateHosts `
-useBestContainerOS `
-shortcuts desktop `
-authenticationEMail 'gintautas@shellrecharge.onmicrosoft.com' `
-AadTenant '65d1aab7-6256-47e9-836c-23cceed270cf' `
-AadAppId 'bbc0ffd6-94db-4031-aa41-85586401ef36' `
-AadAppIdUri 'api://bbc0ffd6-94db-4031-aa41-85586401ef36' `
-Credential $cred `
-useSSL

Full output of scripts

BcContainerHelper is version 4.0.15
BcContainerHelper is running as administrator
HyperV is Enabled
UsePsSession is True
Host is Microsoft Windows 11 Enterprise - 10.0.22621.1702
Docker Client Version is 23.0.5
Docker Server Version is 23.0.5
Removing Session baseaad
Removing container baseaad
Removing entries from hosts
Removing baseaad from container hosts file
Removing baseaad-* from container hosts file
Removing Desktop shortcuts
Removing C:\ProgramData\BcContainerHelper\Extensions\baseaad
Fetching all docker images
Fetching all docker volumes
Using image mcr.microsoft.com/businesscentral:10.0.20348.1726
Creating Container baseaad
Style: onprem
Multitenant: No
Version: 22.0.54157.55195
Platform: 22.0.55180.0
Generic Tag: 1.0.2.14
Container OS Version: 10.0.20348.1726 (ltsc2022)
Host OS Version: 10.0.22621.1702 (22H2)
Using hyperv isolation
Using locale en-US
Disabling the standard eventlog dump to container log every 2 seconds (use -dumpEventLog to enable)
Additional Parameters:
--env customNavSettings=ValidAudiences=bbc0ffd6-94db-4031-aa41-85586401ef36;https://api.businesscentral.dynamics.com,DisableTokenSigningCertificateValidation=True,ExtendedSecurityTokenLifetime=24,ClientServicesCredentialType=NavUserPassword
--env customWebSettings=AadApplicationId=bbc0ffd6-94db-4031-aa41-85586401ef36,AadAuthorityUri=https://login.microsoftonline.com/65d1aab7-6256-47e9-836c-23cceed270cf
Files in C:\ProgramData\BcContainerHelper\Extensions\baseaad\my:
- AdditionalOutput.ps1
- MainLoop.ps1
- SetupVariables.ps1
- updatehosts.ps1
Creating container baseaad from image mcr.microsoft.com/businesscentral:10.0.20348.1726
651b62f9982c45fff09a3d92559f8172bd438b694d459558e01369e2818dcba3
Waiting for container baseaad to be ready
Using artifactUrl https://bcartifacts.azureedge.net/onprem/22.0.54157.55195/w1
Using installer from C:\Run\210-new
Installing Business Central
Installing from artifacts
Starting Local SQL Server
Starting Internet Information Server
Copying Service Tier Files
c:\dl\onprem\22.0.54157.55195\platform\ServiceTier\Program Files
c:\dl\onprem\22.0.54157.55195\platform\ServiceTier\System64Folder
Copying PowerShell Scripts
c:\dl\onprem\22.0.54157.55195\platform\WindowsPowerShellScripts\Cloud\NAVAdministration
c:\dl\onprem\22.0.54157.55195\platform\WindowsPowerShellScripts\WebSearch
Copying Web Client Files
c:\dl\onprem\22.0.54157.55195\platform\WebClient\Microsoft Dynamics NAV
Copying ModernDev Files
c:\dl\onprem\22.0.54157.55195\platform
c:\dl\onprem\22.0.54157.55195\platform\ModernDev\program files\Microsoft Dynamics NAV
Copying additional files
Copying ConfigurationPackages
C:\dl\onprem\22.0.54157.55195\platform\ConfigurationPackages
Copying Test Assemblies
C:\dl\onprem\22.0.54157.55195\platform\Test Assemblies
Copying Applications
C:\dl\onprem\22.0.54157.55195\platform\Applications
Copying dependencies
Copying ReportBuilder
Importing PowerShell Modules
Restoring CRONUS Demo Database
Setting CompatibilityLevel for CRONUS on localhost\SQLEXPRESS
Modifying Business Central Service Tier Config File for Docker
Creating Business Central Service Tier
Installing SIP crypto provider: 'C:\Windows\System32\NavSip.dll'
Starting Business Central Service Tier
Importing license file
Stopping Business Central Service Tier
Installation took 147 seconds
Installation complete
Initializing...
Setting host.docker.internal to 192.168.2.193 in container hosts file (copy from host hosts file)
Setting gateway.docker.internal to 192.168.2.193 in container hosts file (copy from host hosts file)
Setting kubernetes.docker.internal to 127.0.0.1 in container hosts file (copy from host hosts file)
Setting host.containerhelper.internal to 172.23.64.1 in container hosts file
Starting Container
Hostname is baseaad
PublicDnsName is baseaad
Using AccessControlService Authentication
Creating Self Signed Certificate
Self Signed Certificate Thumbprint 241BA9521CDE39C07146273CF769D07A04E97C18
DNS identity baseaad
Modifying Service Tier Config File with Instance Specific Settings
Modifying Service Tier Config File with settings from environment variable
Setting ValidAudiences to bbc0ffd6-94db-4031-aa41-85586401ef36;https://api.businesscentral.dynamics.com
Setting DisableTokenSigningCertificateValidation to True
Setting ExtendedSecurityTokenLifetime to 24
Setting ClientServicesCredentialType to NavUserPassword
Starting Service Tier
CertificateThumprint 241BA9521CDE39C07146273CF769D07A04E97C18
Registering event sources
Creating DotNetCore Web Server Instance
Using application pool name: BC
Using default container name: NavWebApplicationContainer
Copy files to WWW root C:\inetpub\wwwroot\BC
Create the application pool BC
Create website: NavWebApplicationContainer with SSL
Update configuration: navsettings.json
Done Configuring Web Client
Modifying Web Client config with settings from environment variable
Setting AadApplicationId to bbc0ffd6-94db-4031-aa41-85586401ef36
Setting AadAuthorityUri to https://login.microsoftonline.com/65d1aab7-6256-47e9-836c-23cceed270cf
Creating http download site
Setting SA Password and enabling SA
Creating gps as SQL User and add to sysadmin
Creating SUPER user
Container IP Address: 172.23.79.231
Container Hostname  : baseaad
Container Dns Name  : baseaad
Web Client          : https://baseaad/BC/
Dev. Server         : https://baseaad
Dev. ServerInstance : BC
Setting baseaad to 172.23.79.231 in host hosts file

Files:
http://baseaad:8080/ALLanguage.vsix
http://baseaad:8080/certificate.cer

Container Total Physical Memory is 8.5Gb
Container Free Physical Memory is 6.6Gb

Initialization took 43 seconds
Ready for connections!
Reading CustomSettings.config from baseaad
Creating Desktop Shortcuts for baseaad
Cleanup old dotnet core assemblies
Container baseaad successfully created

Use:
Get-BcContainerEventLog -containerName baseaad to retrieve a snapshot of the event log from the container
Get-BcContainerDebugInfo -containerName baseaad to get debug information about the container
Enter-BcContainer -containerName baseaad to open a PowerShell prompt inside the container
Remove-BcContainer -containerName baseaad to remove the container again
docker logs baseaad to retrieve information about URL's again

Warning message

The description for Event ID 705 from source MicrosoftDynamicsNavServer$BC cannot be found. Either the component that raises this event is not installed on your local computer or the installation is corrupted. You can install or repair the component on the local computer.

If the event originated on another computer, the display information had to be saved with the event.

The following information was included with the event: 

Server instance: BC
Category: Security
ClientSessionId: a06a0351-605d-4eb0-89a2-785f6088c230
ClientActivityId: 6219292f-e362-f0fd-c3d9-001f2e2f1173
ServerSessionUniqueId: 768a30b9-0d43-40ab-a11d-f263a5a05512
ServerActivityId: 2c2e1891-8586-4810-8635-e5edc7001713
EventTime: 06/02/2023 20:18:04
Message (NavConfigurationException): RootException: NavConfigurationException
Message not shown because the NavBaseException constructor was used without privacy classification
ExceptionStackTrace:
   at Microsoft.Dynamics.Nav.Runtime.NavAuthenticationHandlerFactory.ValidateSetup(ClientApplicationInfo setup)
   at Microsoft.Dynamics.Nav.Runtime.NavAuthenticationHandlerFactory.CreateSecureAuthenticationHandlerSetup()
   at Microsoft.Dynamics.Nav.Runtime.NavAuthenticationHandlerFactory.CreateSecureHandler(NavDiagnostics diagnosticsInstance, IAuthenticationHandler authenticationHandler, Func`1 authenticationHeaderDelegate)
   at Microsoft.Dynamics.Nav.Runtime.NavTenant.get_SecureAuthenticationHandler()
   at Microsoft.Dynamics.Nav.Runtime.AzureADCodeGrantFlow.AcquireTokenByAuthorizationCode(String authorizationCode, String[] scopes)
   at Microsoft.Dynamics.Nav.Runtime.ALAzureAdCodeGrantFlow.ALAcquireTokensByAuthorizationCode(String authorizationCode, String[] scopes)
CallerStackTrace:
   at Microsoft.Dynamics.Nav.Runtime.ALAzureAdCodeGrantFlow.TraceException(Exception exception, Verbosity verbosity)
   at Microsoft.Dynamics.Nav.Runtime.ALAzureAdCodeGrantFlow.ALAcquireTokensByAuthorizationCode(String authorizationCode, String[] scopes)
   at Microsoft.Dynamics.Nav.Runtime.ALAzureAdCodeGrantFlow.ALAcquireTokenByAuthorizationCode(String authorizationCode, String[] scopes)
   at Microsoft.Dynamics.Nav.Runtime.NavUserAuthentication.ObtainUserAccessToken(NavSession session)
   at Microsoft.Dynamics.Nav.Runtime.NavSession.<Open>b__493_0()
   at Microsoft.Dynamics.Nav.Runtime.SessionTransactionManager.TransactionScope(Action code)
   at Microsoft.Dynamics.Nav.Runtime.SessionTransactionExtensions.TransactionScope(NavSession session, Action operation)
   at Microsoft.Dynamics.Nav.Runtime.NavSession.Open(Boolean useUserPersonalization, Byte[] licenseToUse, Boolean allowAppsDisabledMode)
   at Microsoft.Dynamics.Nav.Runtime.NavSession.Open()
   at Microsoft.Dynamics.Nav.Runtime.NavChildSessionTaskRuntime.Run(NavCancellationToken cancellationToken)
   at Microsoft.Dynamics.Nav.Runtime.NavChildSessionTaskScheduler.RunChildSessionTask(Int32 childSessionTaskId, NavChildSessionTaskRuntimeBase taskRuntime, NavChildSessionsState childSessionsStates)
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Microsoft.Dynamics.Nav.Runtime.NavChildSessionTaskScheduler.RunChildSessionTask(Int32 childSessionTaskId, NavChildSessionTaskRuntimeBase taskRuntime, NavChildSessionsState childSessionsStates)
   at Microsoft.Dynamics.Nav.Runtime.NavChildSessionTaskScheduler.<>c__DisplayClass3_0.<ScheduleChildSessionTaskRun>b__0()
   at Microsoft.Dynamics.Nav.Runtime.NavTaskFactory.<>c__DisplayClass4_0`1.<RunTask>b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
   at System.Threading.Tasks.ThreadPoolTaskScheduler.<>c.<.cctor>b__10_0(Object s)
   at System.Threading.Thread.StartCallback()

ProcessId: 2476
Tag: 00000CY
ThreadId: 29
CounterInformation: 
CustomParameters: {
}
GatewayCorrelationId: 

Element not found

Best Regards, Gintautas

freddydk commented 1 year ago

I would assume that something is wrong in your AAD App Registration. I have this script, which I run to validate AAD Auth (and OAuth and S2S)

It does use some keyvault secrets, which have been read - but I just ran it with the version above, and it works fine. Maybe you can compare and find the difference.

function Parse-JWTtoken([string]$token) {
    if ($token.Contains(".") -and $token.StartsWith("eyJ")) {
        $tokenHeader = $token.Split(".")[0].Replace('-', '+').Replace('_', '/')
        while ($tokenHeader.Length % 4) { $tokenHeader += "=" }
        Write-Host ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenHeader)) | ConvertFrom-Json)
        $tokenPayload = $token.Split(".")[1].Replace('-', '+').Replace('_', '/')
        while ($tokenPayload.Length % 4) { $tokenPayload += "=" }
        return [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($tokenPayload)) | ConvertFrom-Json
    }
    throw "Invalid token"
}

#  _____                               _                
# |  __ \                             | |               
# | |__) |_ _ _ __ __ _ _ __ ___   ___| |_ ___ _ __ ___ 
# |  ___/ _` | '__/ _` | '_ ` _ \ / _ \ __/ _ \ '__/ __|
# | |  | (_| | | | (_| | | | | | |  __/ |_  __/ |  \__ \
# |_|   \__,_|_|  \__,_|_| |_| |_|\___|\__\___|_|  |___/
#

$containerName = "bcserver"
$licenseFile = $LicenseFileUrlSecret.SecretValue | Get-PlainText
$credential = New-Object pscredential -ArgumentList 'admin', $PasswordSecret.SecretValue
$artifactUrl = Get-BCArtifactUrl -country us -select NextMinor -sasToken ($InsiderSasTokenSecret.SecretValue | Get-PlainText)
$aadCredential = New-Object pscredential -ArgumentList ($AadUserNameSecret.SecretValue | Get-PlainText), $AadPasswordSecret.SecretValue

$version = '22.0.54157.55195'
$artifactUrl = Get-BCArtifactUrl -type OnPrem -country w1 -version $version

$useSSL = $false
$params = @{ "useSSL" = $useSSL }
if ($useSSL) {
    $protocol = "https://"
    $params += @{
        "isolation" = "hyperv"
        "installCertificateOnHost" = $true
    }
}
else {
    $protocol = "http://"
}

$aadTenant = "12ad5b0b-86c3-4df1-a022-a2083f9909a8"
$aadDomain = $aadCredential.UserName.Split('@')[1]
$appIdUri = "$protocol$containerName.$aadDomain/BC"

#   _____                _                              _                          ______         ____   _____ 
#  / ____|              | |              /\            | |   /\                   |  ____|       |  _ \ / ____|
# | |     _ __ ___  __ _| |_ ___ ______ /  \   __ _  __| |  /  \   _ __  _ __  ___| |__ ___  _ __| |_) | |     
# | |    | '__/ _ \/ _` | __/ _ \______/ /\ \ / _` |/ _` | / /\ \ | '_ \| '_ \/ __|  __/ _ \| '__|  _ <| |     
# | |____| | |  __/ (_| | |_  __/     / ____ \ (_| | (_| |/ ____ \| |_) | |_) \__ \ | | (_) | |  | |_) | |____ 
#  \_____|_|  \___|\__,_|\__\___|    /_/    \_\__,_|\__,_/_/    \_\ .__/| .__/|___/_|  \___/|_|  |____/ \_____|
#                                                                 | |   | |                                    
#                                                                 |_|   |_|                                    

Write-Host "AAD Tenant: $aadTenant"
Write-Host "AAD Domain: $aadDomain"
Write-Host "AppIdUri: $appIdUri"

Connect-MgGraph -Scopes 'Application.ReadWrite.All'

$AdProperties = New-AadAppsForBC `
    -appIdUri $appIdUri `
    -publicWebBaseUrl "$protocol$($containerName)/BC" `
    -PreAuthorizePowerShell `
    -IncludeApiAccess `
    -IncludeOtherServicesAadApp `
    -IncludeExcelAadApp `
    -useCurrentMicrosoftGraphConnection

#  _   _                      ____        _____            _        _                 
# | \ | |                    |  _ \      / ____|          | |      (_)                
# |  \| | _____      ________| |_) | ___| |     ___  _ __ | |_ __ _ _ _ __   ___ _ __ 
# | . ` |/ _ \ \ /\ / /______|  _ < / __| |    / _ \| '_ \| __/ _` | | '_ \ / _ \ '__|
# | |\  |  __/\ V  V /       | |_) | (__| |____ (_) | | | | |_ (_| | | | | |  __/ |   
# |_| \_|\___| \_/\_/        |____/ \___|\_____\___/|_| |_|\__\__,_|_|_| |_|\___|_|   
#                                                                                     

New-BcContainer @params `
    -containerName $containerName `
    -accept_eula `
    -artifact $artifactUrl `
    -auth AAD `
    -Credential $credential `
    -licenseFile $licenseFile `
    -updatehosts `
    -AuthenticationEMail $AadCredential.UserName `
    -AadTenant $aadTenant `
    -AadAppId $AdProperties.SsoAdAppId `
    -AadAppIdUri $appIdUri `
    -dns 'hostDNS' -multitenant:$false `
    -additionalParameters @("--env customNavSettings=ExcelAddInAzureActiveDirectoryClientId=$($AdProperties.ExcelAdAppId)")

#Import-TestToolkitToBcContainer -containerName $containerName -includeTestFrameworkOnly

#  _   _                      ____                     _   _      _____            _            _   
# | \ | |                    |  _ \         /\        | | | |    / ____|          | |          | |  
# |  \| | _____      ________| |_) | ___   /  \  _   _| |_| |__ | |     ___  _ __ | |_ _____  __ |_ 
# | . ` |/ _ \ \ /\ / /______|  _ < / __| / /\ \| | | | __| '_ \| |    / _ \| '_ \| __/ _ \ \/ / __|
# | |\  |  __/\ V  V /       | |_) | (__ / ____ \ |_| | |_| | | | |____ (_) | | | | |_  __/>  <| |_ 
# |_| \_|\___| \_/\_/        |____/ \___/_/    \_\__,_|\__|_| |_|\_____\___/|_| |_|\__\___/_/\_\\__|
#                                                                                                   

# Get AuthContext using Devicelogin flow (Delegation)
$authcontextDL = New-BcAuthContext -includeDeviceLogin -tenantID $aadTenant
$authcontextDL
Parse-JWTtoken $authcontextDL.AccessToken

# Get AuthContext using RefreshToken (Delegation)
$authcontextRT = New-BcAuthContext -refreshToken $authcontextDL.RefreshToken -tenantID $aadTenant
$authcontextRT
Parse-JWTtoken $authcontextRT.AccessToken

#           _____ _____             _               ____            _                      _   _     
#     /\   |  __ \_   _|           (_)             |  _ \          (_)          /\        | | | |    
#    /  \  | |__) || |    _   _ ___ _ _ __   __ _  | |_) | __ _ ___ _  ___     /  \  _   _| |_| |__  
#   / /\ \ |  ___/ | |   | | | / __| | '_ \ / _` | |  _ < / _` / __| |/ __|   / /\ \| | | | __| '_ \ 
#  / ____ \| |    _| |_  | |_| \__ \ | | | | (_| | | |_) | (_| \__ \ | (__   / ____ \ |_| | |_| | | |
# /_/    \_\_|   |_____|  \__,_|___/_|_| |_|\__, | |____/ \__,_|___/_|\___| /_/    \_\__,_|\__|_| |_|
#                                            __/ |                                                   
#                                           |___/                                                    

# API using basic auth
#$companyId = Get-NavContainerApiCompanyId -containerName $containerName -tenant "default" -credential $credential
#$CompanyId
#(Invoke-BcContainerApi -containerName $containerName -credential $credential -CompanyId $CompanyId -APIVersion "v2.0" -Query "customers").value

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

# API using AAD auth (Delegation)
$CompanyId = Get-NavContainerApiCompanyId -containerName $containerName -bcAuthContext $authContextDL -APIVersion "v1.0"
$CompanyId
(Invoke-BcContainerApi -containerName $containerName -bcAuthContext $authContextDL -CompanyId $CompanyId -APIVersion "v2.0" -Query "customers").value

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

Write-Host "Open $protocol$containerName/BC?tenant=default and add $($AdProperties.ApiAdAppId) as Aad registration"
Write-Host "Remember to grant access, Enable the app and add D365 AUTOMATION + D365 BUS FULL ACCESS to permissions"
Read-Host "Press ENTER when done"

# Get AuthContexct using ClientCredentials flow (S2S)
$authcontextCC = New-BcAuthContext `
                        -clientId $AdProperties.ApiAdAppId `
                        -clientSecret $AdProperties.ApiAdAppKeyValue `
                        -tenantID $aadTenant `
                        -scopes "$appIdUri/.default"
$authcontextCC
Parse-JWTtoken $authcontextCC.AccessToken

# API using AAD auth (S2S)
$CompanyId = Get-NavContainerApiCompanyId -containerName $containerName -bcAuthContext $authContextCC -APIVersion "v1.0"
$CompanyId
(Invoke-BcContainerApi -containerName $containerName -bcAuthContext $authContextCC -CompanyId $CompanyId -APIVersion "v2.0" -Query "customers").value

#              _     _   _____                       ____ _____                        
#     /\      | |   | | |  __ \                     |  _ \_   _|     /\                
#    /  \   __| | __| | | |__) |____      _____ _ __| |_) || |      /  \   _ __  _ __  
#   / /\ \ / _` |/ _` | |  ___/ _ \ \ /\ / / _ \ '__|  _ < | |     / /\ \ | '_ \| '_ \ 
#  / ____ \ (_| | (_| | | |  | (_) \ V  V /  __/ |  | |_) || |_   / ____ \| |_) | |_) |
# /_/    \_\__,_|\__,_| |_|   \___/ \_/\_/ \___|_|  |____/_____| /_/    \_\ .__/| .__/ 
#                                                                         | |   | |    
#                                                                         |_|   |_|    
#

Publish-BcContainerApp -containerName $containerName -appFile "https://businesscentralapps.azureedge.net/azureadappsetup/18.0.67361.0/apps.zip" -install -sync -skipVerification

$companyId = Get-NavContainerApiCompanyId -containerName $containerName -tenant "default" -credential $credential

$parameters = @{ 
    "name" = "SetupAzureAdApp"
    "value" = "$($AdProperties.OtherServicesAdAppId),$($AdProperties.OtherServicesAdAppKeyValue)"
}
Invoke-NavContainerApi -containerName $containerName -tenant "default" -credential $credential -APIPublisher "Microsoft" -APIGroup "Setup" -APIVersion "beta" -CompanyId $companyId -Method "POST" -Query "aadApps" -body $parameters | Out-Null

# Work in progress - programatically add Aad App Registration to BC
$parameters = @{ 
    "name" = "SetupAadApplication"
    "value" = "$($AdProperties.ApiAdAppId),API,D365 ADMINISTRATOR:D365 FULL ACCESS"
}
Invoke-NavContainerApi -containerName $containerName -tenant "default" -credential $credential -APIPublisher "Microsoft" -APIGroup "Setup" -APIVersion "beta" -CompanyId $companyId -Method "POST" -Query "aadApps" -body $parameters | Out-Null