Introduction to Commerce Sealed Installers
Table of Contents
- Introduction
- Differences between Sealed and Legacy Installers
- Downloading Base Product Installers
- On-Prem Scale Unit Installer
- MPOS Installer
- Hardware Station Installer
- Assigning a certificate to an AAD application
- Creating a self-signed certificate
- An alternative way supplying arguments
- Troubleshooting
Introduction
Those who need to deploy on-prem products shipped by Dynamics 365 Commerce are familiar with 3 installers: Hardware Station, Modern POS, Commerce Scale Unit (self-hosted). The installers have 2 main characteristics:
1. Some of them, like the last one above, require UI interaction.
2. They contain both - the base functionality provided by Microsoft Out Of the Box and an extension which is produced by 3rd parties.
The first point means there could be a challenge to deploy in an automated or mass deployment scenarios.
The second means:
- even if you want to only update an extension - you have to repackage the whole thing, the Microsoft's written functionality and your extensions, and then re-install the whole thing. These result in extra development effort, required to create the whole package, and a significant amount of actions performed by the installer at deployment time because the whole set of services should be fully reinstalled.
- if Microsoft releases a new version of the base functionality provided out of the box, you cannot simply use those new installers to update your systems, instead you need to re-package your extension by using a new version of the SDK and only then install it, in other words there is no way to update the system with a newer set of base functionality without involving a developers' activities.
A new generation of installers was created to avoid those limitations - Sealed Installers built on top of a new Sealed Installers Framework. The presence of "Sealed" indicates the packaging and the deployment of the Base, Out Of the Box part of the Product shipped by Microsoft, is now separated from the Extensions' packaging and deployment.
Below benefits apply to all 3 new installers:
- An extension can be packaged and deployed without doing anything with the Base Product (whether it is MPOS, On-Prem CSU or Hardware Station).
- A new version of the Base Product can be installed without a need to do anything with an installed extension.
- Deployment time issues can be investigated by analyzing a single log file available in well known location (the path is printed at the beginning and end of the installation log).
- All the deployment time parameters are supplied via a command line, there is no dependency on any GUI which makes the installers Mass Deployment friendly.
- Description of the supported verbs and options doesn't require any documentation, it is embedded directly into the installer
Differences between Sealed and Legacy Installers
On-Prem Commerce Scale Unit (CSU)
- The installer doesn't manage any AAD applications, it is now up to a customer to fully make required AAD setup. The Legacy Installer asks a user to login with AAD credentials and then the security context of the logged-in user is used to manage the AAD instance associated with the user. That sometimes resulted in "not always easy to investigate" class of issues due to the user's permissions as well as a directory's settings which resulted in a blocked CSU installation for the reasons other than core Dynamics 365 Commerce functionality. As a result the customer could troubleshoot these issues only to the extent of the installer's capabilities and was mainly limited by the installer's logs. If the logs didn't allow to understand a root cause, then a help from Dynamics 365 Commerce support was needed. The Sealed Installer's model is out of business managing AAD applications which opens up a possibility for customers to get help from much broader set of sources including numerous online documentations related to AAD as well as directly from AAD support. Another benefit is automated/mass deployment aspect: a customer is now free to use any scripts and/or preconfigured applications they want to manage the AAD part.
- The installer doesn't ask a user to provide any secrets, instead, when acquiring security tokens from AAD, it relies on customers' owned certificates referenced to the installers via command line arguments which include a certificate location (pointing to a cert store such as LocalMachine/My) as well as its thumbprint. None of those are considered secrets therefore it is safe to store/log/distribute entire command line in a clear text as is without being a risk to leak a secret. This makes the Sealed Installers standing out comparing to the Legacy On-Prem CSU Installer requiring AAD application secret required to be provided at the deployment time in clear text via the installer's UI as well as in the pop-up AAD login request.
- All the prerequisites checks are performed but no prerequisites are automatically installed. This was done to avoid limiting investigations when certain required service (like IIS or SQL Server for instance) could not be automatically setup and to improve mass deployment experience when prerequisites might be configured via dedicated scripts owned by customers specific to their environments.
- There is a dedicated verb, which can be used with the Scale Unit Installer, allowing to update just certificates without touching anything else. This feature allows performing certificates' rotation and it is done in not intrusive way - you don't have to reinstall the whole scale unit and provide a new secret anymore as you do with the Legacy Installer.
- There is an install time verb which instructs the installer to apply a Demo Data to the locally deployed Channel DB, this might be useful in Self-Host mode used for Development scenarios when Channel DB is not populated by a CDX with data from HQ DB.
- Retail Server is based on the ASP.NET Core 3.1 (.NET 6 starting release 10.0.26) rather than on older, non Core version of ASP.NET which is .NET Framework based as is used in the Legacy Installer. One of the biggest benefits is improved performance of the Retail Server.
- Sealed Scale Unit can be deployed in classic complete mode (IIS hosted), containing all the actual components required for production operation, as well as lightweight Self-Hosted mode which will be found a convenient compromise handy at the development time because it doesn't require IIS, HQ, Async Client, CDX.
- Retail Server's Application Pool is backed by the IIS Application Pool Identity rather than a regular Windows User so there is no longer need to maintain a password for that user.
- Retail Server supports multiple extensions where install/uninstall of one extension is independent from another. This is support is limited to non-conflicting extensions, for instance, one extension could provide a handler to Customer Read and another one to Cart Update but there is no way to expect that 2 different extensions providing a handler for the same request, let's say the one dealing with Customer Read.
- Prerequisites checks were enhanced, they are performed close to the start of the deployment to report issues as soon as possible. Some examples of those checks:
- Http ping to HQ Transaction Service endpoint to make sure the configuration file provided corresponds to a working HQ instance;
- AAD credentials (AppId and Certificate) are validated at the beginning of the installation to make sure they can indeed be used to acquire a security token, this is to avoid situations when the install process is completed but the test performed at the end of installation reveals incorrect AAD credentials provided to the installer- now such issues will be detected at the very beginning of the deployment thus saving time.
- Certificates are validated for number of required points, such as Key Length and Purposes.
MPOS
- Client Broker is no longer used to run .NET code, instead the Desktop Bridge is used in Sealed MPOS. This means debugging in Offline mode or Local Hardware Station is done by attaching a debugger to the process Microsoft.Dynamics.Commerce.Pos.DesktopBridge.exe rather than DllHost.exe
- There is no more need to setup your own MPOS AAD Application for a sake of Device Activation as was required for Legacy MPOS. This results in less setup on HQ side's Identity Providers section since the Relying Party, the one corresponding to MPOS, is no longer needed to be setup manually because it is setup automatically during the environment's deployment.
- There are no more separate packages in regards to Offline support, the Base Sealed MPOS package supports both modes, if you need support for Offline - specify the switch InstallOffline
Downloading Base Product Installers
All 3 Base Product Installers are downloadable via the section Retail Self-service package of the LCS Shared Asset Library, find there the version you need, like 10.0.25, 10.0.25 and so on and look for the suffix (SEALED):
Given the packages' Sealed nature, they are always produced and uploaded by Microsoft. While downloading an installer for the given (10.0.22, 10.0.23, ...) release, make sure to select the version you need while downloading it. If there is more than one version is available (this is for sure the case because Microsoft publishes Base Installers continuously) then you will see a number of versions published in the column Version seen below:
Once you click the link VERSIONS, you will see all published versions where you could download the one you need:
As for those releases which are not GA yet, the Base Installers are named by leveraging the prefix (Preview):
On-Prem Scale Unit Installer
Deploying in a Self-Hosted mode
The Sealed installer offers this new deployment mode which deploys a lightweight version Retail Server and a Channel DB, this topology can unlikely be used in production but is a good companion for various development tasks which don't need a fully setup HQ/Async Client and needs a small set of prerequisites and minimal configuration. See the list of prerequisites in the section Shared across Self-Hosted and IIS-Hosted modes. To deploy in this mode you can use the below command:
CommerceStoreScaleUnitSetup.exe install --UseSelfHost --RetailServerCertFullPath "store:///My/LocalMachine?FindByThumbprint=ReplaceWithYourCertsUpperCasedThumbprint"
Let's review the parameters supplied to the installer:
install - that is the verb shared across all installers built on top of the Sealed Installer Framework and instructs to proceed with the installation action
UseSelfHost - this switch is used to request Self-Hosted installation. If not provided then full, IIS-hosted deployment will be performed.
RetailServerCertFullPath - the option used to supply a location of the certificate used for various scenarios, such as, for instance, when RS needs to sign being issued security token. note the self describing Uri format in this option's value - it indicates that the certificate will be loaded from the StoreName My and from the StoreLocation LocalMachine and that the search will be performed by the Thumbprint. Don't forget to substitute ReplaceWithYourCertsUpperCasedThumbprint with your thumbprint in the above command line.
Ideally, in production systems, you should use verifiable certificates rather than self-signed ones. But for development you might supply a self-signed one, the instructions on how to create it are shown in the section Creating a self-signed certificate. Whatever certificate you will use, install it in the My\LocalMachine.
Upon successful installation you will see an output with no errors similar to the below one (note the last line with the log's location):
At the same time another console window will be opened - this one corresponds to just deployed RS host application
Note the Url http://localhost:81/healthcheck?testname=ping&resultformat=json in the above window displaying RS logs in real-time - that Url corresponds to the health-check request the installer makes at the end of the deployment to verify successful completion, if you open the Url in the browser you will see the health-check's output:
which indicates that both - RTS and DB checks succeeded.
If you will need to attach a debugger to the Self-hosted RS - attach to the process Microsoft.Dynamics.Retail.RetailServerSelfHost.AspNetCore.exe.
Finally, you will see just installed Scale Unit in Add or remove programs, search there for Commerce:
To uninstall it use the above UI or explicitly execute the installer and supply the verb uninstall:
CommerceStoreScaleUnitSetup.exe uninstall
Troubleshooting
The installers were created with rich and actionable error reports which should be self describing, I therefore will not go into every possible prerequisites validation failure but instead will point just few:
1. If, while checking the DB availability, there is an error similar to "The certificate chain was issued by an authority that is not trusted", this is an indication that your SQL Server instance was setup with a Self-Signed certificate used to encrypt traffic. Given the Self-Signed certificate doesn't guarantee security, to eliminate that prerequisite check error, you might either provision a verifiable certificate to your server (this is the preferred option) or, if this is your development environment which will never get production traffic and if you understand the security risks outlined in the above link, you might decide to instruct the installer to setup a connection with SQL Server in such a way that the Server will trust the self-signed certificate, to achieve that append the switch --TrustSqlServerCertificate so the full command would be:
CommerceStoreScaleUnitSetup.exe install --UseSelfHost --TrustSqlServerCertificate --RetailServerCertFullPath "store:///My/LocalMachine?FindByThumbprint=ReplaceWithYourCertsUpperCasedThumbprint"
2. If you see an error indicating the port is taken, specify any available port with the option --port:
CommerceStoreScaleUnitSetup.exe install --UseSelfHost --TrustSqlServerCertificate --port 449 --RetailServerCertFullPath "store:///My/LocalMachine?FindByThumbprint=ReplaceWithYourCertsUpperCasedThumbprint"
If you are getting errors and unable to resolve them yourself yet, enable the verbose logging by adding an option --Verbosity Trace and review the logs again, if you still need an assistance - ask for help.
Deploying in an IIS-Hosted mode leveraging Cloud HQ
Represents a complete On-Prem CSU with all components required for production usage. Prerequisites are outlined in the section IIS-Hosted mode. To deploy use the below command line template where you need to specify parameters' values corresponding to your environment:
CommerceStoreScaleUnitSetup.exe install --port 446 --SslCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourSslCertificateThumbprint" --AsyncClientCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourAsyncClientAadAppCertThumbprint" --RetailServerCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourRsAadAppCertThumbprint" --RetailServerAadClientId "YourRsAadClientId" --RetailServerAadResourceId "YourRsAadResourceId" --CposAadClientId "YourCposAadClientId" --AsyncClientAadClientId "YourAsyncClientAadClientId" --config "C:\CsuDistrib\StoreSystemSetup.xml"
Arguments' description:
install - the verb shared across all installers built on top of the Sealed Installer Framework and instructs to proceed with the installation action.
port - the port number to use while creating IIS Web Site hosting RS and CPOS.
SslCertFullPath - the path to the certificate used for the IIS Web Site hosting RS and CPOS. See the section Certificate for SSL on how to create the certificate for dev environment. It is recommended to use verifiable certificate, instead of self-signed, for production environments.
AsyncClientCertFullPath - the path to the certificate used by Async Client when it acquires a security token from AAD for a sake of communication with HQ. See the section Certificate for AAD applications on how to create one.
RetailServerCertFullPath - the path to the certificate used by RS in scenarios when it needs to issue a security token to be used in C1 (POS) scenarios. See the section Certificate for AAD applications on how to create one.
RetailServerAadClientId - the AAD application Client ID corresponding to the Retail Server. This application will be used to acquire a security token from AAD while Retail Server communicates with HQ's RTS. Follow the #3 here for the instructions on how to create Retail Server AAD application in your tenant. Once the application is created, use its field's value Application (client) ID for this parameter. This App ID should also be registered in the HQ as described in the step #2 here otherwise Health Check will fail at the end of the deployment.
RetailServerAadResourceId - the Resource Identifier (or Application ID URI) of the Retail Server's AAD application. Is used by CPOS along with CposAadClientId to acquire an AAD token. This value should be extracted from the field Application ID URI of the Retail Server application created in the previous step. This App ID should also be registered in the HQ as described in the step #2 here otherwise Health Check will fail at the end of the deployment.
CposAadClientId - the AAD application Client ID corresponding to CPOS. This application will be used in scenarios when CPOS needs to acquire a security token from AAD in such scenarios like Device Activation and Employee Login with AAD. To create this application and extract its Application (client) ID, follow the steps outlined in #4 of the same above link.
AsyncClientAadClientId - the AAD application Client ID corresponding to the Async Client service. This application will be used to acquire a security token from AAD while Async Client communicates with HQ. To create this application, follow the same above steps used to create a Retail Server application with the only difference in the field Name - use anything you want to reflect this is an Async Client, for instance - AsyncClient. This App ID should also be registered in the HQ as described in the step #2 here otherwise Async Client Windows Service will not be able to sync data between the Channel and HQ databases.
config - the Channel Database configuration file downloaded from the HQ. It contains number of configuration parameters required for the Scale Unit operation.
The certificates, created for the parameters AsyncClientCertFullPath and RetailServerCertFullPath, need to be associated with the corresponding AAD applications referenced via the parameters AsyncClientAadClientId and RetailServerAadClientId respectively. To do that, you will need to use Azure Portal to upload the certificates' Public Key to the corresponding application, follow the section Assigning a certificate to an AAD application if you need help with that.
Once completed (the below deployment was done at the not domain joined machine), and if you specified the flag --Verbosity Trace, upon successful deployment you will see the URIs of just deployed RS and CPOS in the logs' step #27 with the indications health-checks have passed:
Deploying in an IIS-Hosted mode leveraging On-Premises HQ
Use the below command line to deploy in IIS-Hosted mode by leveraging on-premises HQ setup with ADFS:
CommerceStoreScaleUnitSetup.exe install --port 446 --sslcertfullpath "store:///My/LocalMachine?FindByThumbprint=YourSslCertificateThumbprint" --asyncclientcertfullpath "store:///My/LocalMachine?FindByThumbprint=YourSslCertificateThumbprint" --retailservercertfullpath "store:///My/LocalMachine?FindByThumbprint=YourSslCertificateThumbprint" --AsyncClientAadClientId "YourAsyncClientAadClientId" --RetailServerAadClientId "YourRsAadClientId" --TrustSqlServerCertificate --Verbosity Trace --config "C:\CsuDistrib\StoreSystemSetup.xml"
Note there are no parameters CposAadClientId
and RetailServerAadResourceId
which are required in case of leveraging cloud hosted HQ.
Updating Certificates
One of the challenges in the Legacy On-Prem CSU Installer was the process of updating secrets/certificates when they about to expire or already expired. Once the expiration should be taken care of, you first need to issue new certificate, update your AAD applications to accept their public keys or secrets. Then, for the Legacy Installer, you had to re-run the installer and go through almost full reinstall process.
This scenario was improved in the Sealed Installer by introducing a verb updateCertificates which performs only absolute minimal set of steps by updating configuration files and IIS metadata to point to the new certificates. Nothing else, like, for instance, binaries belonging to already deployed products, is touched during this process:
CommerceStoreScaleUnitSetup.exe updateCertificates --SslCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourNewSslCertificateThumbprint" --AsyncClientCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourNewAsyncClientAadAppCertThumbprint" --RetailServerCertFullPath "store:///My/LocalMachine?FindByThumbprint=YourNewRsAadAppCertThumbprint"
Reusing certificates and AAD applications
Sometimes there is a question: "May I reuse the same certificate for all 3 parameters - SslCertFullPath, AsyncClientCertFullPath, RetailServerCertFullPath?" The answer is: technically, yes, you can, but it would not necessary be the best decision because your company's policies might enforce different lifetime, and other, requirements for AAD and SSL certificates, in that case - you would need to renew your single cert as often as the shortest lifetime policy requires. In addition, if you have to perform an emergency rotation (let's say your certificate's private key is compromised) for one of the certificates, you can do that in a very targeted way if you use individual certificates - rotate only that one which must be rotated and leave the others not touched by therefore minimizing disturbance to the functionality requiring those certificates.
Given the functionality of the Scale Unit doesn't enforce individual certificates, you might reuse the same certificate in development environment, there are no technical obstacles to do so. Whether or not you may do that in your production environment is up to your company's security guidelines, if in doubt - follow best practices by employing individual certificates.
When a similar question comes into mind regarding AAD applications, the answer is essentially the same as above: it might be OK doing so for development environments but to maintain most secure approach don't reuse single AAD application for different physical services (such as Async Client and Retail Server for instance) at least in production environments. In case anything goes wrong with one application - the "blast radius" will be limited to the functionality relying on that application only. For instance: if the AAD application's configuration, belonging to Async Client, becomes an invalid for any reason - that will affect only synchronization of data between Channel and HQ DBs. Having that issue is not pleasant of course but a worse alternative would be to also have a broken RTS communication between Retail Server and HQ.
Other install options
Above we reviewed most important and frequently used options available for the verb install, let's see what other options and switched are available. To see the full list with descriptions - run:
CommerceStoreScaleUnitSetup.exe install --help
Skip_X - there is a number of Boolean switches (they don't need any additional values - they just need to be supplied via the command line), starting with Skip which instruct installer to skip certain action which is otherwise performed, the action could be a prerequisite check or related to post-installation activity. They were added to simplify troubleshooting in some special cases and they should be avoided in production deployments as they instruct the installer to skip important actions required for fully working CSU. An example of the usages: to temporary skip certain prerequisite to see what other prerequisites should be take care of; if you are absolutely sure the system already has all the prerequisites; in case prerequisite check reports invalid results after, for instance, a system upgrade or certain system configuration which is not ready to be handled by the prerequisite check yet. Let's look at some of the switches:
SkipScaleUnitHealthCheck - towards the end of the deployment the installer initiates a health-check which includes verifying CPOS availability as well as RS's availability and a very basic functionality related to interactions with Channel DB and RTS. You can see the result of the health-check in the logs as highlighted in the above screenshot. If, for instance, by the time you are deploying the installer HQ is not available but you don't want to fail the deployment, you can specify this option and it will skip sending health-check request to RS thus assuming it is in working condition.
SkipCertCheck - will result in absence of checks applied to certain certificates' properties, such as, for instance: certificate's presence at the specified location, a presence of the private key, the key size, usage. This would allow to "jump over" these checks and an installer might complete successfully but the CSU might be experiencing issues at runtime which will be harder to investigate comparing to the proactive prerequisites check performed by the installer.
SkipAadCredentialsCheck - those, discussed in previous sections, AAD related parameters (such as ClientIDs and Certificates corresponding to the AAD applications) are validated to make sure corresponding changes were done at AAD side and given certificate can indeed be used with the given Client ID to acquire a security tokens. This is to mitigate one of the issues frequently taking place in Legacy RSSU Installer when this check was performed too late - at the end of the deployment process. You could supply this switch if you have not associated the certificate with AAD Application yet and planning doing that later.
SkipIisCheck - is applicable to the default IIS hosted mode and instructs to skip checking for number of IIS features
SkipSqlServerCheck - allows skipping availability of the SQL Server as well as number of related prerequisites, for instance: the user running the installer must have an Admin role in the SQL Server; there should be certain minimal version of the SQL Server; Full Text Search must be enabled; Mixed Authentication must be enabled, and so on.
SkipUrlCheck - the installer normally validates that HQ Url, supplied via the configuration file downloaded from the HQ, can be reached out from within the machine running the CSU. This check is performed to fail as soon as possible, with an actionable error, rather than towards the end of the deployment. If your HQ is not available yet (for instance, you have not setup the firewall yet) - you might specify this switch.
SkipTelemetryCheck - can be used to turn off the check verifying availability of the telemetry endpoints. The products being deployed by the installer leverage Application Insights to send the telemetry to Microsoft, the installer by default verifies the corresponding endpoints can be reached from within the machine where the installer is run. If your networking/firewall settings don't allow communicating to those endpoints, you can leverage this switch to temporarily disable the verification until you sort out your networking/firewall settings.
SkipSchannelCheck - this switch allows skipping verification for required TLS versions enabled/disabled. Given this is security feature you might only decide to skip this verification if you really understand and are still willing to accept the risks associated with not following PA-DSS.
SkipSqlFullTextCheck - allows skipping SQL Server Full Text Search requirement check/deployment. This flag might be helpful for development scenarios when the DEV machine has very lightweight version of SQL Server, like SQL Server Express LocalDB, installed and when FTS is not needed at the debug/dev time. It is not recommended for PRODUCTION scenarios unless you indeed don't need Full Text Search for your functionality. If this flag is supplied, then the check will be omitted and also FTS related searches will not work. This switch is supported in all Sealed Installers dealing with the Channel DB, such as RSSU, MPOS, Store Commerce.
LogDirectoryPath - allows changing the default (%PROGRAMDATA%\Microsoft Dynamics 365\10.0\logs) location of the logs.
SqlServerName - both deployment modes (Self and IIS hosted) install a Channel DB, as outlined in the bullet #1 here the easiest way is to have Default Instance of SQL Server deployed on your system, then you don't need to specify any SQL related parameters while running the installer. In case you don't have default instance but instead only Named one, you need to instruct the installer to use specific instance by leveraging this argument.
X_ClientCertThumbprint/X_CertFullPath - the installer requires several certificates to be pre-deployed on the machine. There are 2 ways supplying the certificate location to the installer - by using an option expecting:
- a thumbprint, such as: SslCertThumbprint, AsyncClientCertThumbprint, RetailServerCertThumbprint
- a full path, such as: SslCertFullPath, AsyncClientCertFullPath, RetailServerCertFullPath
The option expecting a thumbprint was mainly added for simplicity and it assumes the certificate is placed in the LocalMachine/My certificate store:
--SslCertThumbprint "06CAD6DB5A9528BBE9E194A528A35DBC1F02CEE0"
The option expecting a full path explicitly outlines the path where the cert is located:
--SslCertFullPath "store:///My/LocalMachine?FindByThumbprint=06CAD6DB5A9528BBE9E194A528A35DBC1F02CEE0"
You can use any of the above 2 methods while supplying the certificate to the installer.
The Full Path flavor is used in Cloud CSU deployments, as you can see this method of supplying the location employs URI format so it has a potential specifying various types of the certificates' locations, such as Key Vault for instance. Despite of the ready-for-the-future-features style of the Full Path parameter, the installer enforces that the path supplied is under LocalMachine/My. In addition to the various location types this flavor supports different search methods - the above example is using FindByThumbprint but future features might also support locating the certificate by a subject name via FindBySubjectName.
In this blog I'm using the Full Path style to be more explicit about the location and to be better prepared for future features.
Deploying an extension
Whether it is IIS or Self hosted modes, an extension is installed the same way. To build your extension either execute the task build-extension in VS Code or directly compile the ScaleUnit.sln. Once built, the file ScaleUnit.Sample.Installer.exe, unless you renamed it, can be found under Installer in bin\Debug\net461.
Run the installer by supplying the verb install:
ScaleUnit.Sample.Installer.exe install
Upon successful installation the output will not contain any errors.
To see just installed extension in action open Cloud POS, you can find its Url in the installer's step #27 which performs Health-Check at the end of the deployment:
CPOS one is close to the bottom.
Open CPOS, Activate Device, Login and then search for any string in the top search box:
You will be redirected to an ExampleView which will display the button Ping Test:
Click it and you will see how POS part of the extension interacts with the extension's Ping actions on Retail Server side:
Uninstallation
Both, the base Product (Commerce Scale Unit) and its extension, once installed, can be found in the App & Features:
In order to uninstall them you can either do that by leveraging the above UI or from a command line by supplying the verb uninstall. If you will try to uninstall a Base Product without uninstalling an extension first - the operation will be blocked so if you want to completely remove all Scale Unit components from the machine, uninstall the extension first and then the Base Installer:
ScaleUnit.Sample.Installer.exe uninstall
CommerceStoreScaleUnitSetup.exe uninstall
In case any issue occurs during the command line initiated uninstall - you will see the execution logs and could analyze the output to understand what went wrong.
If something goes wrong when you are trying to uninstall from the Apps & Features UI - you could see the failed uninstallation log in the folder %PROGRAMDATA%\Microsoft Dynamics 365\10.0\logs - sort by the latest folder there and review the log.
MPOS Installer
Deploying the Base Product
MPOS installation process is also initiated by supplying an install verb:
CommerceModernPosSetup.exe install
If you need to install MPOS with Offline support, you no longer (as was required with the Legacy MPOS Installer) separate package, just supply an option InstallOffline:
CommerceModernPosSetup.exe install --InstallOffline
Similarly as for the CSU installer, you could see available install options by supplying a switch help:
CommerceModernPosSetup.exe install --help
The list of parameters is relatively short and their description reveals their purpose. If I want to deploy MPOS by providing predefined values for the RetailServer/Register/Device, I would run it this way:
CommerceModernPosSetup.exe install --RetailServerUrl "https://DESKTOP-CR045MS:446/RetailServer/Commerce" --register "Houston-1" --Device "Houston-1"
Majority of the other available install options are shared with the CSU Installer and have the same purposes, for instance:
- SqlServerName - may be used used as an additional option when InstallOffline is specified and is ignored otherwise.
- TrustSqlServerCertificate - the same as above, applies to Offline mode only.
- SkipUrlCheck - skip verifying Retail Server's URL
- LogDirectoryPath
- Verbosity
Deploying an extension
Once you generate the extension installer by following the steps, run the file ModernPos.Installer.exe found in ModernPos.Installer\bin\Debug\net461 the same way as you did for the CSU Installer - by supplying the only parameter - the verb install:
ModernPos.Installer.exe install
Once the deployment completed you can verify the extension is successfully registered with MPOS, to do that run MPOS by double-clicking the shortcut "Install or update Retail Modern POS" found at your desktop. It is essential to use that shortcut rather than starting MPOS from Windows Start menu because that shortcut makes sure all deployed extensions are registered with the system.
To see the loaded extension status navigate to the Settings page in MPOS:
If you want to see the extension in action, follow the above section "Deploying an extension" under "On-Prem Scale Unit Installer" where it asks to type in the search box.
Troubleshooting
1. If, while compiling the MPOS Sample, you are getting an error saying "Export-PfxCertificate : Using ProtectTo parameter requires running as a domain" while PowerShell script generate-test-certificate.ps1 is run, this is an indication you are trying to build MPOS sample on the machine which is not joined to any AD Domain, this is the current limitation of the SDK/Sample, until it is rectified make sure you are compiling MPOS on the AD Domain joined machine and logged into the system with an AD Domain account. Alternatively, you can manually generate the certificate as outlined here.
2. If the deployment process failed and you could not figure out what went wrong - re-run the installer and augment the set of parameters with:
--Verbosity Trace
You will have most detailed logging which will reveal all available telemetry for the deployment process. For instance, if the deployment fails indicating there was an error executing
Validate-Prerequisites.ps1
Then, once you supply the above mentioned Verbosity switch you might see an indication that given OS is not supported, if so, find what is supported in Modern POS framework and system requirement changes.
3. If you installed the Base Installer and the Extension and then nothing happens when you double click the icon "Install or update Retail Modern POS", this most likely means the extension could not be installed. To find out the root cause navigate to the folder %USERPROFILE%\AppData\Local\Temp\RetailLogs\ModernPos and then open the latest subfolder - it will contain the actual deployment log. If you see there a message similar to "The root certificate of the signature in the app package or bundle must be trusted." - this means the machine, where you installed MPOS, doesn't trust the certificate used to sign your MPOS's Extension package. If you used default MPOS Sample's settings, then the certificate file MPOS_Extension_Certificate.pfx is located in the ModernPos\bld\x86\Debug folder. Add that certificate to the LocalMachine's Trusted Certificate Store Root to eliminate the issue.
4. If the extension installation process when with no errors but you are seeing an error loading the extension in MPOS (under Settings):
This might indicate an incompatibility between Retail Server's part of the extension and MPOS. To troubleshoot:
a) Open Windows Event Viewer under Applications and Services Logs->Microsoft Dynamics->Commerce-ModernPos->Operational and filter for Warning/Error/Critical
b) See if there are events with IDs 46623 and 51257 and if present, analyze their content as well as other, Informational/Verbose messages before/after those 2 to better understand the flow
c) Compare the package name seen in 51257 (it could be, for instance: Extension package named 'Contoso.Commerce' installed but not configured (no package definition found).) with the URL at the bottom of the error screen in MPOS. In my case it shows URL://POS.
d) If you do see different package names in the MPOS UI and in the log, this means that the extension name is different on Retail Server and MPOS sides. The POS's UI displays the extension name provided to MPOS by the Retail Server (which is a source for the MPOS extension loading process) API GetExtensionPackageDefinitions, the content returned by that method could be seen if you intercept the HTTPS traffic, note the value POS in the field Name:
That value comes from the property extensionPackageDefinition.Name so if you changed it (default is Contoso.Commerce), to, for instance POS but you have not changed the extension's package name in MPOS Extension Installer (the default value is also Contoso.Commerce), that above error will take place because Retail Server instructs MPOS to load the extension's package with name POS but instead MPOS got installed the package with the name Contoso.Commerce as seen in the previously described POS screenshot and the log.
e) If you indeed have package name mismatch, then modify the assignment of the property extensionPackageDefinition.Name with the value corresponding to the MPOS Extension Package, in case of this example, replace the POS with Contoso.Commerce
Hardware Station Installer
Once the Hardware Station Installer is downloaded from LCS, run it supplying required arguments:
CommerceHardwareStationSetup.exe install --CsuUrl https://desktop-inl4ctf:446/RetailServer/Commerce --CertFullPath "store:///My/LocalMachine?FindByThumbprint=ReplaceWithYourThumbprint" --port 450
CsuUrl - The Url to the Commerce Scale Unit (Retail Server) to be used with this Hardware Station. It must include /Commerce at the end.
CertFullPath - The path to the SSL certificate to be used by the Hardware Station's web site
port - the port number to use while creating IIS Web Site hosting the Hardware Station.
If you don't plan to use devices requiring CCO OPOS driver, you can supply the switch SkipOposCheck to avoid otherwise required prerequisite check validating a presence of the CCO OPOS.
If you don't want the installer to create a firewall rule to allow the traffic via the above mentioned port, supply the switch SkipFirewallUpdate
Deploying and configuration an extension
The extension's installer is built once you compile HardwareStation.Samples.sln . To install, run HardwareStation.Installer.exe found under src\HardwareStationSample\HardwareStation.Installer\bin\Debug\net461:
HardwareStation.Installer install
The versions older than 10.0.25 contains an issue around extensions in the Sealed Hardware Station so few temporary manual steps need to be done if you are using a version older than 10.0.24. To workaround those issues a couple of manual steps are required (if you are using 10.0.25 or newer - ignore the below 2 steps):
1. Copy into the clipboard the file Contoso.HardwareStation.Peripherals.PaymentDevice.dll found in the folder
%ProgramFiles%\Microsoft Dynamics 365\10.0\Commerce hardware station\Extensions\HardwareStation.Installer
and paste it into
%ProgramFiles%\Microsoft Dynamics 365\10.0\Commerce hardware station\Microsoft\Webroot\bin
2. Modify the file
%ProgramFiles%\Microsoft Dynamics 365\10.0\Commerce hardware station\Microsoft\Webroot\HardwareStation.Extension.config
by adding there the line highlighted in green:
Now the Hardware Station is configured with the extension and is ready to use.
Adding a custom Web API Controller
The sample contains a code to demonstrate how to create a PaymentDevice, below I will show how to create a custom Web Api Controller with an Action which can be verified in a very simple way once the extension is configured - you will only need a browser. The steps assume the Base Hardware Station Installer was already run:
1. Use a Visual Studio to open HardwareStation.Samples.sln
2. Add new empty file to the project Contoso.PaymentDeviceSample, name it, for instance, ExtensionPingController.cs, add the below content to the file:
using System;
using System.Threading.Tasks;
using Microsoft.Dynamics.Commerce.Runtime.Hosting.Contracts;
namespace Contoso.HardwareStation.Peripherals.PaymentDevice
{
[RoutePrefix("ExtensionPing")]
public class ExtensionPingController : IController
{
[HttpGet]
public Task<string> GetCurrentTime(IEndpointContext context)
{
return Task.FromResult(DateTimeOffset.Now.ToString());
}
}
}
3. Recompile the solution and redeploy the extension as outlined in the section Deploying and configuration an extension (in case you are using a version older than 10.0.24, you don't have to modify the file HardwareStation.Extension.config again, for a sake of working around the issue in that version, if you didn't reinstall the Base Installer). Open a browser and direct it to:
https://ReplaceWithYourFullMachineName:450/HardwareStation/ExtensionPing/GetCurrentTime
You should see the result of just created action GetCurrentTime displaying current time:
Note that if you have difficulties figuring out the base Url of the Hardware Station, you can grab it from the Base Installer's output (assuming you still have the corresponding CMD window opened) at the step #18:
It has Ping at the end.
Assigning a certificate to an AAD application
1. Export the certificate's public key: Assuming you have already created the certificate(s) and installed it in the certificate store by following the section Creating a self-signed certificate, export the public key as below:
Launch mmc.exe
Click File->Add/Remove Snap-in...
Double-click Certificates in the list of available Snap-ins
In the pop-up opened, select Computer account and hit Finish
In the next window select, if not already selected, the Local computer and hit Finish.
hit OK. Another window will open, in its middle pane double-click the Certificates:
Double-click Personal->Certificates.
Locate the certificate you created previously, then right-click it and select All Tasks->Export->Next->NO, do not export the private key->DER encoded binary x.509 (.CER)->Next
Click Browse and type any file name you want, for instance, AsyncClientCertPublicKey, then click Save and notice the full path to the file. then click Next and Finish. There should be a message indicating the export went successfully.
2. Navigate to https://aad.portal.azure.com/, click Azure Active Directory->App registrations and locate the AAD application you created earlier, start with, for instance, the one corresponding to the Async Client
3. Click Certificates & secrets under the section Manage.
4. Click Upload certificate under the section Certificates and proceed uploading the certificate's public key you exported earlier at the step #1. Once you are done the application will look similar to this one:
5. Repeat the above steps for the 2nd pair of the Certificate/AAD application - those which belong to the Retail Server.
Creating a self-signed certificate
Certificate for SSL
For a sake of development/testing I will use a Self Signed Certificate:
1. Open IIS -> Server Certificates -> Create Self-Signed Certificate...
2. In the field asking for a friendly name provide full machine name which must include a domain if machine is joined into one
3. For certificate store keep default value Personal. You should have a screen similar to the below but with the machine/domain name specific to you (my machine is joined in the domain, that is why I specified it, but if your machine is not part of any domain than you only need to specify the machine name):
Hit OK to finish creating the certificate.
4. Double-click just created certificate, navigate to the tab Details and make a note of the Thumbprint - you will need it at the deployment time, note that the installer requires providing it in UPPERCASED format.
Certificate for AAD applications
The process creating this type of the certificate is identical to the above set with the only difference: you can specify anything you want in the friendly name field.
An alternative way supplying arguments
As was shown in the Scale Unit Installer there is a possibility to supply certain parameters via a configuration file, given this is Installer Framework feature, rather than specific installer, the same way supplying arguments can be used to MPOS (and Hardware Station) installers as well. For instance, if I want to supply RetailServerUrl, Device and Register via the configuration file while deploying MPOS, I would create an XML file, let's say settings.xml
and specify it during the deployment:
CommerceModernPosSetup.exe install --config "settings.xml"
Note the casing of the keys in the configuration file, as of current versions it is important to use correct casing otherwise the keys will be ignored when specified via the configuration file.
Troubleshooting
1. Follow the section Troubleshooting
2. In case you initiate the uninstall from the Apps & Features Windows UI and something goes wrong, you can find the logs of the failed attempt under
%PROGRAMDATA%\Microsoft Dynamics 365\10.0\logs - sort its content by the latest folder and review the log.
Comments
-
Introduction to Commerce Sealed InstallersHi,What is the process of installing a SQL in one box and application in another box using sealed installer ? There is no way to skip the application installation on SQL box and skip the application installation on SQL box. If you can help with some insights then it would be helpful.
*This post is locked for comments