Using the Retail Reprovisioning tool for Dynamics 365 for Operations

When you do any kind of copying between environments in Dynamics there are some settings which are copied that are actually wrong for the destination environment. To fix these you need to run a tool called Retail Reprovisioning tool (also called Environment retargeting tool)

At the beginning this was only supposed to be run for environments actively using the Retail Components. The recommendation at the moment (2017-11-29) is to run it for every environment since al of the actually contains Retail components.

1. To make sure that you have the latest version of the tool go to LCS – Asset Library. Go to Software Deployable Packages – Import  and Select the latest Environment Reprovisioning tool.

2. The next step is different depending on which type of environment you are using.

If you are using a 2-tier environment; go to the environment, select Maintain and  Apply Updates. Select the Environment Reprovisioning tool and click Apply. Continue to Step 5

If you are using a Dev environment you are not able to deploy using LCS and you will have to deploy from command line according steps 3 – 4

3. Unblock the downloaded file by Right-clicking the file and going to Properties – General Unblock for the fil

4. Extract the file to a temporary directory

Install using these command lines:

AXUpdateInstaller.exe list

Fix the DefaultTopologyData.xml and make it look like this:

<?xml version=”1.0″ encoding=”utf-8″?>
<TopologyData xmlns:xsd=”
http://www.w3.org/2001/XMLSchema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
   <Name>AX topology</Name>
   <MachineList>
     <Machine>
       <Name>localhost</Name>
       <ServiceModelList>
         <string>RetailServer</string>
         <string>ALMService</string>
         <string>AOSService</string>
         <string>BIService</string>
         <string>DevToolsService</string>
         <string>DIXFService</string>
         <string>DocumentRoutingAgent</string>
         <string>MROneBox</string>
         <string>PayrollTaxModule</string>
         <string>PerfSDK</string>
         <string>ReportingService</string>
         <string>RetailCloudPos</string>
         <string>RetailHQConfiguration</string>
         <string>RetailSDK</string>
         <string>RetailSelfService</string>
         <string>RetailStorefront</string>
         <string>SCMSelfService</string>
         <!– DefaultTopologyData are only for dev vhd, which we only support AOS update–>
         <!– Create a new topology data for your Cloud AX topology–>
       </ServiceModelList>
     </Machine>
   </MachineList>
   <BackupScript>
     <FileName />
     <Automated>false</Automated>
     <Description>Please backup your environment now, set this step to complete once you finished backup</Description>
   </BackupScript>
</TopologyData>

Generate The Runbook
AXUpdateInstaller.exe generate -runbookid=[runbookID] -topologyfile=[topologyFile] -servicemodelfile=[serviceModelFile] -runbookfile=[runbookFile]
AXUpdateInstaller.exe import -runbookfile=[runbookFile]

Verify the runbook

AXUpdateInstaller.exe list

Execute the runbook

AXUpdateInstaller.exe execute -runbookid=[runbookID]

Post Steps:

5. After the retargeting tool is run you need to run these four steps

a. Open the “Retail Parameters” form, and press the “Initialize” link under the “General” tab. Answer “Yes” to the prompt. This will provide any new Retail seed data.

clip_image001

b. Open the “Initialize Retail Scheduler” form, and run it with “delete existing configuration” set to “Yes“.

c. Restart the “Microsoft Dynamics AX Batch Service” on all AOS VMs. This will update any cached connection credentials that may be used when running a CDX data sync. (done by DSE if PROD => you need to raise a ticket)

d. Navigate to the “Channel Database” form and run a CDX 9999 sync (full sync). This should succeed if everything is properly configured for Retail.

6. Sometimes there is issues with some columns in some tables in the channel database looses their setting for full text indexing (this seems to be an effect of the BacPac procedure when sopying to and from an Azure Environment), this results in not being able to search in for instance MPOS. To verify this you can use this script:

SELECT
SCHEMA_NAME(t.schema_id) as TableSchema,
       t.name AS TableName,
       c.name AS CatalogName ,
       i.name AS UniqueIdxName,
       cl.name AS ColumnName,
COLUMNPROPERTY(t.object_id, cl.name, ‘IsFulltextIndexed’) as IsFullTextEnabledOnTable,
          fi.is_enabled AS isEnabledOnColumn
FROM
sys.tables t
INNER JOIN
sys.fulltext_indexes fi
ON
    t.[object_id] = fi.[object_id]
INNER JOIN
sys.fulltext_index_columns ic
ON
    ic.[object_id] = t.[object_id]
INNER JOIN sys.columns cl ON
        ic.column_id = cl.column_id
AND ic.[object_id] = cl.[object_id]
INNER JOIN
sys.fulltext_catalogs c
ON
    fi.fulltext_catalog_id = c.fulltext_catalog_id
INNER JOIN
sys.indexes i
ON
        fi.unique_index_id = i.index_id
AND fi.[object_id] = i.[object_id]
where c.name like ‘COMMERCEFULLTEXTCATALOG’
order by Tablename ASC

look for the ones having a ‘0’ in any column and fix them by runing:

ALTER FULLTEXT INDEX
ON [ax].tablename
ENABLE

ALTER FULLTEXT INDEX
ON [ax].tablename
SET CHANGE_TRACKING=MANUAL;
GO

ALTER FULLTEXT INDEX ON [ax].tablename START FULL POPULATION;
GO

ALTER FULLTEXT INDEX
ON [ax].tablename
SET CHANGE_TRACKING=AUTO;
GO

Links:
https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package

Retail servicing data is not present in the RetailServer web.config when running Retail Retargeting tool

Thi is an issyue we have noticed on especially new environments that we have refreshed with a database from an existing Retail Enable environment. After refreshing the database we need to run the retargeting tool to make sure that all settings are corrected.

When the tool is run it fails at step 3 and when we look in the Step3RetargetRetailServer-logfile we find this:

12/6/2017 9:35:52 AM:     – Trying to get information of the website – AOSService …
Unexpected error. Microsoft.Dynamics.ApplicationPlatform.Environment.Settings.ConfigurationKeyNotFoundException: No setting keys found for prefix ‘CertificateHandler’.
    at Microsoft.Dynamics.ApplicationPlatform.Environment.Settings.BaseConfigSetting.GetSettingsForPrefix(String prefix)
    at ConfigEncryptor.Program.Main(String[] args).
12/6/2017 9:35:52 AM:
PSMessageDetails      :
Exception             : System.Management.Automation.RuntimeException: Retail servicing data is not present in the
                         RetailServer web.config, please contact DSE team.
TargetObject          : Retail servicing data is not present in the RetailServer web.config, please contact DSE team.
CategoryInfo          : OperationStopped: (Retail servicin…ntact DSE team.:String) [], RuntimeException
FullyQualifiedErrorId : Retail servicing data is not present in the RetailServer web.config, please contact DSE team.
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, F:\DeployablePackages\a2f41617-591e-45c9-bce4-1934c1b17ca6\RetailServer\scrip
                         ts\RetargetRetailServer.ps1: line 299
                         at <ScriptBlock>, <No file>: line 3
                         at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {}
12/6/2017 9:35:52 AM: Executed:
F:\DeployablePackages\a2f41617-591e-45c9-bce4-1934c1b17ca6\RetailServer\scripts\RetargetRetailServer.ps1
Exiting with error code .

This error is due to missing information in the Web.Config file for Retail. Fortunately there is a fairly easy fix… there is a script in the Retail Retargeting tool called Update-RetailServicingInformation.ps1 which populates the web.config file with the correct information. The parameters you will need to provide is the database name which you can find in SQL Server Management Studio and the SQL Server name. The server name for OneBox Environments is Localhost. For Tie-2 and up you will need to provide the Azure SQL name which you can find in LCS, don´t forget to add database.windows.net to make it a FQDN

/Johan

Error in Environment Reprovisioning tool

I have been working with an upgrade of Dynamics 365 for Operations now for a while and found an issue when it comes to Environment Reprovisioning tool, also known as Retail Retargeting Tool. This is a tool used to fix the retail conponents in an environment after you have done a database copy to the environment from another environment. We did this as part of the upgrade to Platfor Update 10.

When we ran the tool from the command prompt in the environemnt we gor the following error:

The step completed
Executing step: 3
GlobalUpdate script for service model: RetailServer on machine: localhost
Run RetargetRetailServer.ps1
RetargetRetailServer.ps1 failed.
The step failed
The step: 3 is in failed state, you can use rerunstep command to debug the step explicitly
at Microsoft.Dynamics.AX.AXUpdateInstallerBase.RunbookExecutor.executeRunbookStepList(RunbookData runbookData, List`1 runbookStepList, String updatePackageFilePath, Boolean silent, String stepID, ExecuteStepMode executeStepMode, Boolean versionCheck, Boolean restore, Parameters parameters)
at Microsoft.Dynamics.AX.AXUpdateInstallerBase.RunbookExecutor.executeRunbook(RunbookData runbookData, String updatePackageFilePath, Boolean silent, String stepID, ExecuteStepMode executeStepMode, Boolean versionCheck, Boolean restore, Parameters parameters)
at Microsoft.Dynamics.AX.AXUpdateInstallerBase.AXUpdateInstallerBase.execute(String runbookID, Boolean silent, String updatePackageFilePath, IRunbookExecutor runbookExecutor, Boolean versionCheck, Boolean restore)
at Microsoft.Dynamics.AX.AXUpdateInstaller.Program.InstallUpdate(String[] args)
at Microsoft.Dynamics.AX.AXUpdateInstaller.Program.Main(String[] args)

So this error was not that obvious to me… So I took a look at the loggs for the Deployable package which are located in the RunbookWorkingFolder (located in the folder where you extracted the package). There I found this:

Exception : System.Management.Automation.RuntimeException: The servicing data of this box has not been migrated yet, please rerun this tool with axlocaladmin
TargetObject : The servicing data of this box has not been migrated yet, please rerun this tool with axlocaladmin

This made me think… The older environments always had an account called axlocaladmin but the newer ones does not. After some digging around in the script called RetargetRetailServer.ps1 I found this (on line 302) :

if($env:UserName -ne ‘axlocaladmin’)
{
$errorMessage = “The servicing data of this box has not been migrated yet, please rerun this tool with axlocaladmin”
Log-TimedMessage $errorMessage
throw $errorMessage
}

I simply changed it to:

if($env:UserName -ne ‘adminXXXXXXXXXX’)
{
$errorMessage = “The servicing data of this box has not been migrated yet, please rerun this tool with axlocaladmin”
Log-TimedMessage $errorMessage
throw $errorMessage
}

where adminXXXXXXXXXX is the account name for my user and the i re-ran:

AXUpdateInstaller.exe execute -runbookid=env-reprovision -rerunstep=3

And presto… it worked 🙂

Note that this is the reprovisioning tool from 8/30/2017, I have not looked at any other verisons.

/Johan

The Real-Time Service call Failed when trying to use CloudPoS

One of my colleagues contacted me today about an issue. When he was logged into the Dynamics 365 for Operations  Cloud POS and he tried to perform a “Real-Time Operation” such as resetting a password he got this error:

4BF47ABA

To reproduce it I tried to do the same, and low and behold it worked… we used the same PoS worker and we had the same Roles in Dynamics…

While he was doing some more testing i logged in to the Dynamics Server using RDP to see if there was anything in the Event viewer… Found something!

Real-time Service client library call for API ‘InvokeMethod’ method ‘UpdateStaffPassword’, language ‘sv-SE’, and company ‘usrt’ failed. Exception: ‘System.ServiceModel.FaultException`1[Microsoft.Dynamics.Retail.TransactionServices.ClientProxy.Fault]: Fault was thrown by the service for request c7f48632-52a9-447e-ba42-9d7cb4c800ba. Exception details:
Type: Microsoft.Dynamics.Ax.Xpp.ErrorException

Message: The language sv-SE is not supported by Microsoft Dynamics 365 for Operations
. For a list of supported languages, see Microsoft Dynamics 365 for Operations Online. (Fault Detail is equal to Microsoft.Dynamics.Retail.TransactionServices.ClientProxy.Fault).’.

The language sv-SE is not supported by Dynamics 365 for Operations… that’s better… now I know where to look. My browser was using english and my colleague was using swedish. We changed it to look like this by switching the order and moving English to the top…

image

… it worked !!!

That is all for today

/Johan

Issues with Retail Layout designer

One of my colleagues had an issue accessing the Screen Layout designer in the AX Client and I was a bit confused… it worked for me… This turned out to be two separate issues.

image    image

The first one was that he and I was logged into two different AOSes and the Retail Headquarter was not installed on the one he was logged on to… simple enough to fix… I simply installed it. The Retail Headquarter component includes some DLLS that are required. If you want to be able to run the Retail Layout Designer on a  client or terminal server you will need to install the retail components on the client/terminal server as well.

When we installed the Headquarter components we unfortunately missed the fact the we “probably should” install Expression Blend Sad smile (note to self… read all the instructions)

image

When we tried to start the Designer it crashed with this error.

image

I found information on this issue on LCS Issue Search (Link below). The trick is to install Expression Blend Dev Kit for .NET and then copy Microsoft.Expression.Interactions.dll and System.Windows.Interactivity.dll from “C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries” to “C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin”

When these issues was fixed and my colleague tried to start the Button Grid Layout he gets this error:

SNAGHTML54766cd

Normally the AX AOS Service user is used to access the AX database but in some cases the individual user needs to have specific access… below is a link to an article that describes steps involved

 

Links
https://fix.lcs.dynamics.com/Issue/Solution/1223064?bugId=3725829&qc=dd5219a830d7a93c687ff03083b2970a6ae1775a018daa69b8be820ab77ae101

http://daxdude.blogspot.se/2013/02/ax-issue-method-start-in-com-object-of.html

The given value of type String from the data source cannot be converted to type nvarchar of the specified target column when syncing Retail Data to Channel Database

One of our customer are going to use the AX 2012 R3 Retail solution and the setup of the Async Server – Client in the TEST environment was setup and tested. The application consultants started importing the product data to AX and suddenly the sync stopped with this error:

Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.ProcessSourceRequestHeaderException: ProcessTargetRequestHeader failed due to an InvalidOperationException.connectionString: Data Source=XXXXXX;Initial Catalog=ClientChannelDB;Integrated Security=True;Connect Timeout=60;Application Name=”Commerce Data Exchange Async Client” —> System.InvalidOperationException: The given value of type String from the data source cannot be converted to type nvarchar of the specified target column. —> System.InvalidOperationException: String or binary data would be truncated.

After having a look online I found that there is no sync of the schema between the AX database and the Channel Database (!!!). This meant that when we imported data to AX everything worked but when we did the sync jobs it failed. The reason being that some field types did not match.

After talking to MS support I got a script to try to figure out which fields were wrong

select t1.table_name, t1.column_name, t1.character_maximum_length, t2.character_maximum_length
from MicrosoftDynamicsAX.INFORMATION_SCHEMA.columns t1
inner join RetailHoustonStore.INFORMATION_SCHEMA.columns t2
on t1.table_name = t2.table_name
and t1.column_name = t2.column_name
and t1.character_maximum_length != t2.character_maximum_length order by TABLE_NAME

this query finds all of the fields which are not matched between the AX database and the Channel Database. With some help we found that the issue probably was the field called RETAILVARIANTID which was present in INVENTDIMCOMBINATION and INVENTITEMBARCODE

We ran these SQL queries:

ALTER TABLE [ClientChannelDB].ax.INVENTDIMCOMBINATION ALTER COLUMN RETAILVARIANTID nvarchar(25) NOT NULL;
ALTER TABLE [ClientChannelDB].ax.INVENTITEMBARCODE ALTER COLUMN RETAILVARIANTID nvarchar(25) NOT NULL;

And there was also a view called INVENTDIMCOMBINATION which we scripted out to a query windows, deleted and recreated again. This solved the issue.

System.InvalidOperationException: The given value of type String from the data source cannot be converted to type datetime of the specified target column.

I had an issue today with the sync between Async Server and Client. Some of the jobs worked and some threw an error

Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.ProcessSourceRequestHeaderException: ProcessTargetRequestHeader failed due to an InvalidOperationException.
connectionString: Data Source=XXXXXXXX;Initial Catalog=ClientChannelDB;Integrated Security=True;Connect Timeout=60;Application Name=”Commerce Data Exchange Async Client” —> System.InvalidOperationException: The given value of type String from the data source cannot be converted to type datetime of the specified target column. —> System.FormatException: Failed to convert parameter value from a String to a DateTime. —> System.FormatException: String was not recognized as a valid DateTime.
   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
   at System.Convert.ToDateTime(String value, IFormatProvider provider)
   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
   at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
   — End of inner exception stack trace —
   at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
   at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
   — End of inner exception stack trace —
   at System.Data.SqlClient.SqlBulkCopy.ConvertValue(Object value, _SqlMetaData metadata, Boolean isNull, Boolean& isSqlType, Boolean& coercedToDataFeed)
   at System.Data.SqlClient.SqlBulkCopy.ReadWriteColumnValueAsync(Int32 col)
   at System.Data.SqlClient.SqlBulkCopy.CopyColumnsAsync(Int32 col, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyRowsAsync(Int32 rowsSoFar, Int32 totalRows, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinued(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestContinuedAsync(BulkCopySimpleResultSet internalResults, CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource`1 source)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync(CancellationToken ctoken)
   at System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync(Int32 columnCount, CancellationToken ctoken)
   at System.Data.SqlClient.SqlBulkCopy.WriteToServer(IDataReader reader)
   at Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.SCSqlWriteRequestRunner.BulkCopyData(SqlConnection connection, SqlTransaction transaction)
   at Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.SCSqlWriteRequestRunner.Run(SqlConnection connection, SqlTransaction transaction)
   at Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.SCSqlTargetRequestHandler.ProcessWriteRequest(SqlConnection connection, SqlTransaction transaction)
   at Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.SCSqlTargetRequestHandler.ProcessTargetRequestHeader(ISCTargetRequestHeader targetRequestHeader)
   — End of inner exception stack trace —
   at Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.SCSqlTargetRequestHandler.ProcessTargetRequestHeader(ISCTargetRequestHeader targetRequestHeader)
   at Microsoft.Dynamics.Retail.SynchClient.Core.DownloadAgent.ApplySessionFileToClientDatabase(SessionManager sessionMgr, String fileName)

The error turned out to be a mismatch in the configuration of the Channel Data Group where I had set the force locale to EN-UK instead of EN-US and apprently there is a difference in the date format. After changeing this parameter everything worked again.

RetailCDXMonDataSync object not initialized when processing Status Messages in AX 2012 Retail

Todays issue is regarding AX 2012 Retail…

When I try to Process status messages under Retail – Inqueries – Download sessions i get the following error

image

First I found some hints online that it had to do with the Working Folders set up in Retail – Setup – POS – Retail Scheduler – Channel Integration – Working Folders. I verified that the settings were OK and then I set the permissions on the folders to allow the service account for AsyncServer/AsyncClient had full access to them.

That did not help… strange… so I thought that I really needed to verify the permissions… Process Monitor to the rescue

image

Apparently the changes I made did not propagate all through the folder structure… After fixing it everything is working nicely.

Links:
https://community.dynamics.com/ax/b/dynamicsaxretail/archive/2016/03/13/retailcdxmondatasync-object-not-initialized-when-you-run-process-status-message

Changing the certificate used for Channel database sync in AX 2012 Retail

I have been trying the past couple of bays to get retail up and running on the Microsoft Dynamics AX 2012 R3 demo environment. There are some issues in the default environment that needs to be fixed before everything is running flawlessly.

One issue I noticed was that the SSL certificate used between the async client and async server has expired (in 2015 Smile ).

           image

To fix this we first need to request and issue a new certificate. Since the CA in the Demo is a stand-alone CA we cannot use the MMC to request the certificate, so I am using the web interface. Start Internet Explorer and browse to the address https://localhost/certsrv (since the certificate for the site is not issued to localhost there will be an error… ignore this).

           image

Select Request a certificate

           image

Select advanced certificate request

           image

Select create and submit a request to this CA

           image

Click Yes to continue

          image

Fill in the name of the certificate. In our case the adress is retail.contoso.com, the other fields are not mandatory. Select Server Authentication Certificate and check  Mark keys as exportable. Click Submit.

           image

Note the id of the request and start the Certificate Authority mmc Management Console

           image

Find the request above under Pending Request. Right-click and select the task Issue

           image

Go back to https://localhost/certsrv and click View the status of a pending certificate request. Click your request.

           image

Click Yes to continue.

          image

Click the Install this certificate. Unfortunately the certificate will be installed in you personal Certificate Store and you will have to move it before IIS can use it.

          image

Start the management Console and add the Certificates snap-in for Current User and for Local Computer. Go to Current User – Personal – Certificates and find your new certificate

          image

Right click the certificate and select Export

            image

Select Yes, export the private key

           image

Check Export all extended properties and click next

           image

Enter a password and click next

          image

In the console on Local Computer – Personal – Certificates right click and import the Certificate you exported previously

          image     image

In IIS Manager edit Binding for the sites AsyncServerSite and Retail Server Website and change the certificate for HTTPS. Restart the IIS sites.

That is all

/Johan