microsoft / navcontainerhelper

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

Restoring the BC Cloud bacpac backup to On Premise | The new users do not meet the terms of the current license. The current license allows 4 full users and 0 limited users #3310

Open shadab256 opened 9 months ago

shadab256 commented 9 months ago

Issue - we are restoring the online backup file (.bacpac) to on premise container. we already restore the database backup file and mounted same as your script. At the end of the script (New-BcContainerBcUser) we are getting below error:

Ref Article - https://freddysblog.com/2021/03/02/restoring-your-online-business-central-database-locally/

Error - 
The new users do not meet the terms of the current license. The current license allows 4 full users and 0 limited users.
At C:\Program Files\WindowsPowerShell\Modules\BcContainerHelper\6.0.4\ContainerHandling\Invoke-ScriptInNavContainer.ps1:112 char:13
+             throw $errorMessage
+             ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (The new users d... limited users.:String) [], RuntimeException
    + FullyQualifiedErrorId : The new users do not meet the terms of the current license. The current license allows 4 full users an 
   d 0 limited users.

we used below script -
$containerName = "saas"
$environment = "Production"

$artifactUrl = Get-BCArtifactUrl -type 'Sandbox' -country w1 -version "21.5.53619.53819" -select 'Closest' `

 $backupFile = "C:\20240118_01.bacpac"

$auth = "UserPassword"
$credential = New-Object pscredential `
    -ArgumentList 'bcadmin', (ConvertTo-SecureString 'Logon2me' -AsPlainText -Force)

$dbCredential = New-Object pscredential `
    -ArgumentList 'sa', (ConvertTo-SecureString 'P@ssw0rd2024' -AsPlainText -Force)
$databaseParams = @{
    "databaseServer" = "SRV-BC"
    "databaseInstance" = ""
    "databasePrefix" = "$($containerName)-"
    "databaseName" = "BCDB"
    "databaseCredential" = $dbCredential
    "multitenant" = $true
}
New-BcContainer @databaseParams -replaceExternalDatabases `
    -accept_eula `
    -containerName "$containerName" `
    -credential $credential `
    -auth $auth `
    -artifactUrl $artifactUrl `
    -enableTaskScheduler `
    -licenseFile "C:\7319836\7319836.flf"
    -updateHosts

$tenantId = $environment
$dacDll = Get-Item "C:\Program Files\Microsoft SQL Server\*\DAC\bin\Microsoft.SqlServer.Dac.dll"
if (-not($dacDll)) {
throw "DAC Framework is not installed"
}
Add-Type -path $dacDll.FullName
[System.Reflection.Assembly]::LoadFrom($dacDll) | Out-Null
$databaseName = "$($databaseParams.databasePrefix)$tenantId"
$conn = @(
    "Data Source=localhost"
    "Initial Catalog=master"
    "Connection Timeout=0"
    "User Id=$($dbCredential.UserName)"
    "Password=$($dbCredential.Password)"
) -join ";"
 Write-Host "Restoring Database from $backupFile as $databaseName"
 $AppimportBac = New-Object Microsoft.SqlServer.Dac.DacServices $conn
 $ApploadBac = [Microsoft.SqlServer.Dac.BacPackage]::Load($backupFile)
 $AppimportBac.ImportBacpac($ApploadBac, $databaseName)

$removeApps = $removeApps = @("App1", "App2", "App3")
$removeApps | ForEach-Object {
Invoke-Sqlcmd -Query "USE [$databaseName]
GO
DELETE FROM [dbo].[NAV App Published App]
WHERE Name = '$_'
DELETE FROM [dbo].[NAV App Installed App]
WHERE Name = '$_'
GO"
}

Write-Host "Mount tenant $tenantId"
Invoke-ScriptInBcContainer `
    -containerName $containerName `
    -scriptBlock { 
    Param(
        $databaseServer,
        $databaseInstance,
        $databaseCredential,
        $tenantId,
        $databaseName)
    Mount-NavTenant `
        -ServerInstance $ServerInstance `
        -id $tenantId `
        -databaseserver $databaseServer `
        -databaseinstance $databaseInstance `
        -databasename $databaseName `
        -databaseCredentials $databaseCredential `
        -EnvironmentType Sandbox `
        -OverwriteTenantIdInDatabase `
        -Force
    Sync-NavTenant `
        -ServerInstance $ServerInstance `
        -Tenant $tenantId `
        -Mode ForceSync `
        -Force
} -argumentList `
    $databaseParams.databaseServer,
    $databaseParams.databaseInstance,
    $databaseParams.databaseCredential,
    $tenantId,
    $databaseName

Get-NavContainerAppInfo `
    -containername $containerName `
    -tenant $tenantId `
    -tenantSpecificProperties `
    -sort DependenciesFirst | ForEach-Object {
        $syncState = $_.SyncState.ToString()
        $appName = $_.Name
        if ($SyncState -eq "NotSynced") {
            Sync-NavContainerApp `
                -containerName $containerName `
                -tenant $tenantId `
                -appName $appName `
                -Force
        }
}

Get-NavContainerAppInfo `
    -containername $containerName `
    -tenant $tenantId `
    -tenantSpecificProperties `
    -sort DependenciesFirst | ForEach-Object {
        if ($_.NeedsUpgrade) {
            Start-BcContainerAppDataUpgrade `
                -containerName $containerName `
                -tenant $tenantId `
                -appName $_.Name
        }
}

Invoke-ScriptInBcContainer `
    -containerName $containerName `
    -scriptblock { Param( $tenantId )
        Start-NAVDataUpgrade `
            -ServerInstance $serverInstance `
            -Tenant $tenantId `
            -Force `
            -FunctionExecutionMode Serial `
            -SkipIfAlreadyUpgraded
        Get-NAVDataUpgrade `
            -ServerInstance $serverInstance `
            -Tenant $tenantId `
            -Progress
} -argumentList $tenantId

New-BcContainerBcUser `
    -containerName $containerName `
    -tenant $tenantId `
    -Credential $credential `
    -PermissionSetId 'SUPER' `
    -ChangePasswordAtNextLogOn:$false

Start-Process "http://$containerName/BC?tenant=$tenantId"

Error Output:
Creating User bcadmin
The new users do not meet the terms of the current license. The current license allows 4 full users and 0 limited users.

Exception Script Stack Trace:
at <ScriptBlock>, <No file>: line 61

PowerShell Call Stack:
at Invoke-ScriptInBcContainer, C:\Program Files\WindowsPowerShell\Modules\BcContainerHelper\6.0.4\ContainerHandling\Invoke-ScriptInNav
Container.ps1: line 71
at New-BcContainerBcUser, C:\Program Files\WindowsPowerShell\Modules\BcContainerHelper\6.0.4\UserHandling\New-NavContainerNavUser.ps1:
 line 60
at <ScriptBlock>, C:\Users\Administrator\Documents\Untitled6.ps1: line 291

Container Free Physical Memory: 18.4Gb

Services in container saas:
- MicrosoftDynamicsNavServer$BC is Running
- MSSQL$SQLEXPRESS is Stopped

Relevant event log from container saas:
- 20240124 08:57:00 - MicrosoftDynamicsNavServer$BC

  Server instance: BC
  Category: Security
  ClientSessionId: 573cf852-f3e4-43f2-a34d-bdf7b2c6adb7
  ClientActivityId: efec7323-1009-4f5f-8b49-789850d82524
  ServerSessionUniqueId: 947716be-bc09-46b4-954f-37c572a03cae
  ServerActivityId: a650185c-073a-4009-9900-d55fc3db52b5
  EventTime: 01/24/2024 16:57:00
  Message (FaultException`1): NewUser(String, String, NavUserState, DateTime, String, Boolean, LicenseType, String, String, Boolean, D
ateTime, String, String, String, Guid, String, String, Nullable`1) FAILURE.
  RootException: FaultException`1
  ExceptionStackTrace:
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.ErrorMappingCombinator(ServiceOperationContext context, ServiceOperati
on innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.PartnerTelemetryPermissionErrorCombinator(ServiceOperationContext cont
ext, ServiceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.PushPopCombinator(ServiceOperationContext context, ServiceOperation in
nerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.TelemetryCombinator(Category telemetryCategory, Verbosity telemetryVer
bosity, ServiceOperationContext context, ServiceOperation innerOperation)
  CallerStackTrace:
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.TelemetryCombinator(Category telemetryCategory, Verbosity telemetryVer
bosity, ServiceOperationContext context, ServiceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.ErrorMappingCombinator(ServiceOperationContext context, ServiceOperati
on innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.PartnerTelemetryPermissionErrorCombinator(ServiceOperationContext cont
ext, ServiceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.PushPopCombinator(ServiceOperationContext context, ServiceOperation in
nerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.TelemetryCombinator(Category telemetryCategory, Verbosity telemetryVer
bosity, ServiceOperationContext context, ServiceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationTracer.TraceScopeCombinator(Category telemetryCategory, ServiceOperationContext
 context, ServiceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.<>c__DisplayClass7_0.<PerformanceCounterCombinator>b__0()
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.PerformanceCounterCombinator(ServiceOperationContext context, ServiceO
peration innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.InitClientTelemetryIdsCombinator(ServiceOperationContext context, Serv
iceOperation innerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationPipeline.TlsClearCombinator(ServiceOperationContext context, ServiceOperation i
nnerOperation)
     at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
     at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
     at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
     at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
     at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
     at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationCon
text currentOperationContext)
     at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
     at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
     at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
     at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
     at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
     at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(IAsyncResult result)
     at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
     at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
     at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(Object state)
     at System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(Object state)
     at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
     at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
     at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
     at System.Net.Security.NegotiateStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolR
equest asyncRequest)
     at System.Net.Security.NegotiateStream.ReadCallback(AsyncProtocolRequest asyncRequest)
     at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result)
     at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
     at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
     at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
     at System.ServiceModel.Channels.ConnectionStream.IOAsyncResult.OnAsyncIOComplete(Object state)
     at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
     at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags fl
ags)
     at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOver
lapped)
     at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERL
AP)

  ProcessId: 1800
  Tag: 00000ZX
  ThreadId: 91
  CounterInformation: 
  CustomParameters: {
  }
  GatewayCorrelationId: 312c0a26-b32e-4b4a-ab98-81f72bd8c8d5

New-BcContainerBcUser Telemetry Correlation Id: d27defcc-fbdd-41f8-bf8e-f7998039af71
The new users do not meet the terms of the current license. The current license allows 4 full users and 0 limited users.
At C:\Program Files\WindowsPowerShell\Modules\BcContainerHelper\6.0.4\ContainerHandling\Invoke-ScriptInNavContainer.ps1:112 char:13
+             throw $errorMessage
+             ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (The new users d... limited users.:String) [], RuntimeException
    + FullyQualifiedErrorId : The new users do not meet the terms of the current license. The current license allows 4 full users an 
   d 0 limited users.
freddydk commented 9 months ago

I think the error message is very clear - the license allows 4 full users and you might have more than that in the database. Which license are you using? I think the CRONUS (DEMO) license allows 4 users - in that case, I assume that you can disable or delete users in the database directly (I don't know which tables you need to modify, sorry) to be able to mount.

shadab256 commented 9 months ago

Hi we have created multi-tenant container, and we can see we have 4 Database. saas-BCAPIDB saas-default saas-Production (This is our online Backup, which we restored) saas-tenant

we can see dbo.User in saas-default and saas-tenant only.

saas-Production doesn't have any user table. As mentioned by MS support this database only contain Business Data only.

We are able to login successfully in default (Cronus). Facing issue while login into Production tenant.

please let me know if cmd to use for disabling or deleting users.

About license, we generated Production license from Microsoft MBS portal.

Seeking for your support to streamline this setup.

freddydk commented 9 months ago

How many users do you have in the Production license? If that is 4, then I guess the license is correctly imported.

dbo.User is (I think) SQL Server users. The users you need to cleanup are Business Central Users (I guess) I do not know which table contains the Business Central Users I do think that BCAPIDB is your app database and Production is your tenant DB - the last one should (probably) contain the users.

Sorry that I cannot be of more help - but this is not my area of expertise.