MyTNT Missing Pending Shipment Menu item fixed

Pending Shipment Menu Item Missing from MyTNT web application

For some users the Pending Shipment Menu item was found to be missing when the logged into the MyTNT website. This was found to be a cross browser issue, also using another login credentials or clearing cookies and cache didn't clear the issue. It was not user rights related in the MyTNT application either. 

This was found to be linked to specific users in a particular Active Directory group policy group applied to the users. This policy was blocking internet access, except for certain domains. This policy was the immediate clue as to what might be happening. 

If you look in the image below, pending shipments does not exist in Domain User A web browser, but does for Domain User B. Also note the hamburger menu is added on B too. 

After investigating in the developer tools of the internet browser to see what page objects were failing to load, one set of requests became prime suspect -requests to https://cdn.optimizely.com/js/5435521705.js

Blocking this domain (optimizely) on a machine that was not affected, caused the pending shipments menu option to vanish after clearing caches on the previously working machine -aha! 

Thus group policy was adjusted to allow this content distribution network, and all was well again. 

 

 

 

Dynamics GP 2015 email–”Word experienced an error trying to open the file error sending email” when using Word Templates

When attempting to send a document that utilises word templates, even using PDF format, the following error may occur, due to a tightening in security with in the Microsoft Office product, “Word experienced an error trying to open the file”.

Word experienced an error trying to open the file. Try these suggestions Check the file permissions for the doucment or drve


Information about this issue can be found here: Word Templates will not Email/Print after Office Update

As I understand it the XML generated by Dynamics GP is not compliant and causes office versions with the patch to fail to load it. This is true also if you send the word document as a word document to someone, that was generated in Dynamics GP. If they have patched office, the document will not open.  When Dynamics GP sends a PDF/Word email it saves the document into a temp directory first then sends it, turning it into a PDF as required. This is why even PDF documents are affected too.

Solution for GP versions after 2016

The solution is to update with the latest GP patches if you are on supported version of GP 2016 and above (at time of writing).

Those updates found here:

Microsoft Dynamics GP U.S. Year-End Update 2020 RELEASED!!


Bodge solution for GP version 2015 – maybe previous version too, I’ve not tested

If you are running unsupported GP2015, then you are stuck without a solution, other than the correct one, that you really should be upgrading to a supported version of GP f9or these exact kind of reasons). In the real world there are many reasons why this may not be possible quite yet and you don’t want to postpone rolling out office updates, as for security reasons, you really shouldn’t hold back on updates.

There is a totally unsupported bodge you can use that may give you some time to upgrade whilst still benefiting from the latest office updates.  Please note this action should be considered carefully as it has not been talked about by Microsoft as an option.


Fix Dynamics GP 2015 Word experienced an error issue

To fix this issue for Dynamics 2015, in a totally unsupported way – this is at your own risk!

Download GP2016, more importantly, Download the latest GP 2016 cumulative update and install the client only, obviously you don’t want to upgrade your GP install yet, and have no need for the database components, perhaps do this on another machine for peace of mind. You must have the release that contains the bug fix, follow the link above. It must be the 2016 version of GP, this will not work if you do this with the 2018 version!


Download for GP2016 patch


In the Dynamics GP Program files folder of the 2016 install locate the following two files :

Microsoft.Dynamics.GP.BusinessIntelligence.Office.dll

Microsoft.Dynamics.GP.BusinessIntelligence.Office.dll 
Microsoft.Dynamics.GP.BusinessIntelligence.TemplateProcessing.dll

  • Ensure Dynamics GP is closed on the machine that you are working on
  • Also find the same files in the GP2015 install folder, take a copy of them onto your desktop or somewhere safe, so you have a way to go back if you need to
  • Now replace only these two files in the Dynamics GP2015 folder with those from the GP2016 folder.

You may now launch GP2015. You should find that the ability to send emails of Word Template based reports has now been restored. Roll these two files out to your other workstations that use word template reports.

These were the version numbers on those files from the attempt I made:

version 16.0.865.0 Microsoft.Dynamics.Gp.BusinessIntelligence.TemplateProcessing.dll

version 16.0.865.0 Microsoft.Dynamics.Gp.BusinessIntelligence.TemplateProcessing.dll


Note: This is totally unsupported method and use it at your own risk. However with this just been a reporting and office library dlls, the risk to GP should be low in my opinion. Although this is an unsupported change, if you are such an old version of GP you are running unsupported already to some extent anyway! Also note that this will only work with version 2016->2015. When I tried it with a more modern version of the dll, GP failed to open.

Dynamics GP Web Client is not compatible with Docker due to the Session Central Service not starting

Back in 2017 I attended NAVTechDays and after seeing the benefits the Dynamics NAV community were getting from Docker containers with NAV, I could see similar benefits for Dynamics GP and was also seeing interest in some of the conversations going on out of public within the GP community. I decided to see if I could get a good selection of Dynamics GP versions into Docker. Word of that work spread and brought out more people interested in containers for GP.

I spent a lot of hours attempting to learn Docker and to containerise Dynamics GP. I could build Docker images for the GP server database and add in various of the GP components like eConnect and oData. Sadly I was unable to get the Dynamics GP Web Client working – I really was just a cat's whisker away from success too. I was defeated by the Domain Account the Web Client runs under and its use of System.DirectoryServices.AccountManagement .  The following is a record of what I found when investigating that issue.

Although I can create a Docker container for the database and test company and even things like eConnect, there is a big problem. You see, there is no GUI with Docker containers, you can’t just remote desktop into one, you really need the Web Client running in order to make a self contained system to allow the host to interact with the Dynamics GP application in the container. If you can't access it from a browser, then you end up having to install the GP client on a non-docker machine (host) and connect using it to the running Docker container. Although this works its not really in the spirit of what I was trying to achieve, which was a fully self contained container for GP to allow multiple versions of GP to be easily spun up for testing and demo purposes. 

Why I failed?

After the Docker image has installed GP and the the web client product features are installed, one of these, the Session Central Service fails to start within the container. The Session Central Service is the component of the Dynamics GP web client installation that creates and tracks individual web client sessions as users connect and disconnect via web browsers. It is essential to getting web client to work.

At this point let me jump tight to the core issue, essentially the problem is that the “Lanman” windows service can’t be started in a Windows container. The Lanman service provides things like SMB file share services and is also referred to as the “Sever Service”, as that is how it appears, named in the services control panel list of services.

Containers are supposed to be stateless isolated single-app process groups, not mini virtual machines, so running Lanman would break that philosophy, hence it is not appropriate for it to be supported in Windows Docker containers as it doesn't make sense. Containers are supposed to be created and torn down at the drop of a hat, participating in active directory goes against the grain. This is why, along with a few other Windows features that are inappropriate for containers, we find the Lanman service just isn’t supported in a Windows Container.

So why is this a problem?

You find that the session central service, checks for the user running, see (2) in the following screenshot, and it does this using a call to the following method:

Dynamics.GP.Web.Foundation.DirectoryServices.PrincipalManager.GetPrincipal

This method in turn calls .NET method:

System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext  context, Type principalType, IdentityType identityType, String identityValue)

It is the above call that fails, and looking in the event log we see it reporting as indicated by (1) in the screenshot below that:

Exception message:
                      The Server service is not started.

Possible Root cause sml

Hey? - "The Server service is not started" – a confusing message as it means that the Lanman Service (aka server service) is not started. Yes this was super confusing error at the start of this investigation, not realising there was a "server service", so I assumed it was just a poor error message that wasn't telling me the service that had failed. So once I realised what it meant, I found out that, indeed if you go into the Docker container with Power Shell you can check that the Server Service is not started and even try to start it, however it will not start,  and this is due to the lack of support in windows containers, as previously stated. Lanman service can't be run on a windows container, thus preventing the use of .NETs System.DirectoryServices.AccountManagement. Microsoft in the past also confirm there are no plans for this to ever change, as it is fundamentally at odds with container philosophy to have this service running.

Without a small change to the Session Central Service code I was not going to get anywhere with this until…

Docker and Group Managed Service Account (gMSAs)

Hope then followed when I then discovered about the existence of Group Managed Service Account (gMSA), that I thought may provide a route to get around the lack of Lanman support. Using it we can authenticate to Active Directory resources from Windows container which is not part of your domain (remember the container is not part of domain), using gMSA. gMSA is a special account that can be used to (over simplifying it) allow passing over a domain account for the purposes of running a service. This could be perfect for replacing the user running the session central service, instead it can ran using a gMSA account for authentication. That in turn would bypass Lanman. When you run a container with a gMSA, the container host retrieves the gMSA password from an Active Directory domain controller and gives it to the container instance. The container will use the gMSA credentials whenever its computer account (SYSTEM) needs to access network resources. In our case, when building the Docker container we can use Power Shell to change the Session Central service to use the SYSTEM account having prepared the plumbing required for gMSA to authenticate against AD. SYSTEM become a kind of proxy for the AD account behind the gMSA account. For this to work certain prerequisites needs to be met, there is quite a bit of learning that is more than I want to get into here. I built this up in Docker to test.

Sadly on testing this thoroughly for a few days, it turns out there is another a problem. A docker container can access AD using the gMSAsaccount, allowing FindByIdentity to work WHEN the constructor for PrincipalContext is created with “ContextType.Domain” and specifying an accessible AD. The group managed service account technique does not work when the context type of “ContextType.Machine” is used to create the PrincipalContext.  

If we look at what is going on in the class in the screen shot– we find that the class is created with a constructor specifying machine as the context, stumping our attempts to use the gMSA to get around the lack of Lanman. This is due to no user name getting passed to the isMachineContext function (see last screen shot). I'm guessing that using the built in NETWORK user means no user name is passed into this method thus resulting in the highlighted code (1) being ran in the following screen shot.  This was upsetting to find as I thought I had it cracked at this point.

Not all that learning is a loss as it was interesting to learn about gMSA as it is an important container and enterprise computing concept to understand.

The following screenshot shows the code causing our issue (1) in the Microsoft.Dynamics.GP.Web.Foundation.DirectoryServices.PrincipalManager.

 

GetPrincipal2

 

User name being blank when calling the following IsMachineContext method then means the split in the logic in the above screen shot causes it to create the PrincipalContext using the wrong context type to use gMSA.

ismachinecontext

Finally


We can create containers with the database and test company but sadly we end up having to install the GP client on the host to access the container, that was not really my objective.

 Would be amazing if the code could be updated by Microsoft but I don’t see this happening. I need to refresh myself on the exact details of this issue and check again that nothing has changed in the years since I was trying as Docker is getting constantly improved with new features. 

SSMS Registered Servers–Key not valid for use in specified state

After exporting the registered servers from SQL Server Management Studio’s “Registered Servers window” and then importing the exported list into a new machine. You may encounter the following error if passwords were stored against the servers…

Registered Servers    Key not valid for use in specified state. (System.Security)
Registered Servers - Key Not Valid for use in specified state.


This is due to the encryption key used to encrypt the passwords being specific to the machine the server details were exported from and it not existing on the new machine.

Even more annoying, this message will pop up once for each server with an issue. Those servers will be absent from the registered servers window in the new machine SSMS.


When I got around to fixing this, the original machine was long gone, so re-exporting the server list without passwords and re-importing it was no longer an option (this would have also have worked).

To solve this problem needed to remove the password from the affected registered servers, once the registered server list is properly populated again I can then simply edit the server properties to put the password back in for each server affected.


This registered server list is populated from an xml file found in the following location on your machine:

C:\Users\{username}\AppData\Roaming\Microsoft\Microsoft SQL Server\{sql version}\Tools\Shell\RegSrvr.xml


On opening this file and examining the XML, the snag was that some servers had been added since the server import. Some of those servers were named the same as the ones causing the error. Scrolling through the XML in Notepad, it was not easy to tell which was which.

To help I went back into the registered server list in SSMS and added a distinct comment to all the servers I could see and exited again to updated the XML file. On opening the file again, I searched for “Password=” in the file and removed the section Password=”jdsalkfjdalksjd”; – where the random text is the password and the xml node was of type ConnectionStringWithEncryptedPassword. I removed the whole password parameter as shown by highlighting.

Note that the password property of the connection string was only removed if the description node shown below did not appear, or was present but had another value not containing the unique text we entered earlier in description fields (in this case the unique text was “**MyMarkerText**”).

<RegisteredServers:Description type="string">**MyMarkerText**</RegisteredServers:Description>

Save the file and launch SSMS. The error will not appear and the missing registered servers will be available again. You must now right click and edit the properties of each to manually restore the passwords.