Tampilkan postingan dengan label Troubleshooting. Tampilkan semua postingan
Tampilkan postingan dengan label Troubleshooting. Tampilkan semua postingan

Kamis, 16 Februari 2017

Web Client: HTTP Error 500.0 - Internal Server Error

Just recently I was assisting a partner on the Dynamics GP Partner forum with an error they were receiving when attempting to log into the Microsoft Dynamics GP web client.

Summary

The partner reported they could log into web client just fine from the SQL Server. However, when they launched web client from the Web Server that host the Dynamics GP web application, they received:

HTTP Error 500.0 - Internal Server Error



Now, this error is a pretty generic error. In addition to not being able to log in, the landing page would not display the Microsoft Dynamics GP logo.

Troubleshooting the Issue

The partner had tried the following troubleshooting techniques:
  1. Repaired Microsoft Dynamics GP web components
  2. Uninstalled and reinstalled web components
  3. Rebooted the server
In addition, I recommended my article Microsoft Dynamics GP 2016 web client UI not displaying icons to ensure static content had been enabled during Internet Information Services (IIS) configuration. Typically, when static content is not enabled, the web client image resources do not get displayed.

Usually, after trying options 1 and 2, if you are still experiencing issues not allowing you to bypass the login window, you know you are facing a pre-requisite configuration issue.

Reading the Detailed Error Information section, you will notice that the error was caused by an authentication request, trying to access an image resource file using Anonymous Authentication by an Anonymous user. In simple terms, this is a permissions issue.

Upon inspecting the GP website authentication setting, the partner noticed the credentials for the anonymous user identity were set to IUSR.



So what's the big deal?

Anonymous authentication gives users access to the public areas of your website without prompting them for a user name or password. When a user attempts to connect to your public Web site, your Web server assigns the user to the Windows user account called IUSR.

By default, the IUSR account is included in the IIS_USRS built-in group. This group has security restrictions, imposed by NTFS permissions that designate the level of access and the type of content available to public users. With that said, websites such as the GP web belong in the private domain and most organizations disable anonymous authentication totally for the GP websites and revoke access to the IUSR account or IIS_USRS group to the website folder to prevent unauthorized access.

If you are running IIS 7.5 on Windows Server 2008 R2, or a later version of IIS, for every application pool you create, the Identity property of the new application pool is set to ApplicationPoolIdentity by default. The IIS Admin Process (WAS) will create a virtual account with the name of the new application pool and run the application pool's worker processes under this account by default.

By setting the ApplicationPoolIdentity as the anonymous user account for a site, you can isolate content and configuration for that site so that no other sites on the same IIS web server can access it, even if you have enabled anonymous authentication. GP web client installation allows you to specify a domain account as the identity for the Web Management Console and GP web application pools. The installer in turn will ensure the proper permissions are given to the folders hosting the web site and the GP web components.

This is particularly useful if you are a hosting provider running multiple customer websites on a single IIS server. Having the ability to control the website access and the content that is displayed is very important.

For a primer on IUSR vs application pool identity, take a look at the following article by Tristan K.

IUSR vs Application Pool Identity – Why use either?

The fix

In this particular case, switching the Anonymous Authentication credentials from IUSR to ApplicationPoolIdentity fixed the issue, although, keep in mind that the GP web client does not require anonymous authentication to be enabled.

Until next post!

MG.-
Mariano Gomez, MVP

Rabu, 15 Februari 2017

VST: An error occurred while loading or initializing an addin

As I mentioned before, I am now the Lead Software Engineer at Mekorma. I love it here as I get to work with some really talented software engineers and developers, all of which challenge me everyday. One of the cool new products we are working on, Mekorma Multi-Batch Management, allows you to build payment batches, print and post payments, and generate electronic funds transfer (EFT) and positive pay (Safe Pay) files, across companies, and across multiple checkbooks, with some minor configuration and just the click of a button. You can see an in-depth video on the product here.


Part of the challenges of building Multi-Batch Management were its extensive interfacing with both our own Mekorma MICR product and Microsoft Dynamics GP, and in particular, the Safe Pay module - Multi-Batch Management is designed to drive the Microsoft Dynamics GP user interface, thus eliminating the need for invasive code.

If you have worked on integrating code for Microsoft Dynamics GP, you are certainly familiar with the challenges surrounding the response to Dexterity modal dialogs. This is true for Microsoft Dexterity service enabled procedures as much as it is true for standard applications like ours, that simply try to drive the user interface.

NOTE: Dexterity does not have a programmatic mechanism to respond to modal dialogs. As it stands, only Visual Basic for Applications (VBA) and Visual Studio Tools for Microsoft Dynamics GP (VST) provide event handlers for modal dialogs.

VST aids in responding to Dexterity modal dialogs by allowing a developer to define form or window level modal event handlers. Because our code needed to respond to dialogs in Safe Pay only when our process was running, it was necessary to create an application assembly for our dictionary, that we could then reference in a Visual Studio Tools project. In addition, we needed to reference the Safe Pay application assembly as well. The project reference looks something like this:


Project References

Once references are added to the project, the tendency is to immediately add all event handlers to the Initialize() method within the GPAddIn class, as shown below:


public void Initialize()
{
Dynamics.Forms.SyErrorMessage.SyErrorMessage.OpenBeforeOriginal +=
Dynamics_SyErrorMessage_OpenBeforeOriginal;
Dynamics.Forms.CmTransactionEntry.CmTransactionEntry.BeforeModalDialog +=
Dynamics_BeforeModalDialog;
Dynamics.Forms.CmEftGenerateFiles.CmEftGenerateFiles.BeforeModalDialog +=
Dynamics_BeforeModalDialog;
SafePay.Forms.MePpTransactions.MePpTransactions.BeforeModalDialog +=
new EventHandler(SafePay_Transactions_BeforeModalDialog);
}


Unfortunately, this approach has a problem: let's assume Safe Pay is not installed, therefore, the Safe Pay application dictionary and application assembly are missing from the Dynamics GP installation folder. Since the Initialize() method is the entry point to your VST application, when the runtime engine attempts to load your assembly, your application would contain a reference to a non-existing assembly. This in turn will cause the runtime engine to produce the following error:

"An error occurred while loading or initializing an addin. As your administrator to check the Windows event log for more details. Dynamics will now close."


This is always been accepted as "the way things work". Unfortunately, we couldn't live with the status quo as it meant that customers who did not require the Safe Pay module would have to install it just for the sake of our assembly not failing.

We then attempted to move our event handler registration into it's own method, enveloping the call in a try..catch block:


public void Initialize()
{
Dynamics.Forms.SyErrorMessage.SyErrorMessage.OpenBeforeOriginal +=
Dynamics_SyErrorMessage_OpenBeforeOriginal;
Dynamics.Forms.CmTransactionEntry.CmTransactionEntry.BeforeModalDialog +=
Dynamics_BeforeModalDialog;
Dynamics.Forms.CmEftGenerateFiles.CmEftGenerateFiles.BeforeModalDialog +=
Dynamics_BeforeModalDialog;

try
{
InitializeSafePay();
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}

public void InitializeSafePay()
{
SafePay.Forms.MePpTransactions.MePpTransactions.BeforeModalDialog +=
new EventHandler(SafePay_Transactions_BeforeModalDialog);
}


The above produced virtually the same results. That is, the exception was still being displayed. Now, quite clearly, if we commented out the throw statement, the exception would no longer present itself and the message would not appear, precisely what we needed since we did not want to alert of the missing assembly and prevent the user from login into Dynamics GP.

NOTE: Alternatively, we implemented tracing capabilities for our assembly, so now all exceptions are recorded in a log file.

Special thanks to my Sr. Software Engineer, Lee Butenhoff for researching and providing a solution to this long standing issue.

Until next post!

MG.-
Mariano Gomez, MVP

Senin, 13 Februari 2017

You receive "Unhandled Script Exception: Invalid Product ID 258" when attempting drill-down into an invoice from Purchasing All-In-One view

Just recently, I was helping someone on a forum with a question regarding the Purchasing All-In-One view. The consultant could not get the view to show the receipts and invoices for some vendor POs. In order to assist with the issue, I had to try and recreate the issue myself. Needless to say, I could not recreate the specific problem reported by the consultant. However, in an attempt to drill-down on a specific invoice voucher, I received the following error message:

Unhandled script exception:
Invalid Product ID 258.

EXCEPTION_CLASS_SCRIPT_OUT_OF_RANGE
SCRIPT_CMD_CALL




Product 258 corresponds to Project Accounting. Suffice to say, there isn't any validation in place to determine if the Project Accounting dictionary is present, before attempting to display the invoice. The workaround, of course, is to install Project Accounting even if you don't need it, until a fix is in place from Microsoft.

This issue is present in Microsoft Dynamics GP 2015 R2 YE (14.00.1016) and Microsoft Dynamics GP 2016 RTM (16.00.0404). I have not tested GP 2016 R2, but see no specific reason to believe this is been fixed, given the fact that this condition only occurs if Project Accounting is not installed.


Until next post!

MG.-
Mariano Gomez, MVP

Senin, 23 Januari 2017

"Get-Content : Cannot find path 'C:\en-US\Welcome.txt' because it does not exist" error when running GPPowerShellStart.ps1

Lately, I have been dabbing into PowerShell. The truth is, I had been wanting to do this for the past 3 years now, to switch from DOS batch files and VBScript to a more robust, developer-like task automation alternative. So I thought myself PowerShell over the past few days and, in doing so, I decided I'd look into the GP PowerShell feature, so off I went installing it.

Summary

Directly from the PowerShell TechNet page, "Windows PowerShell® is a task-based command-line shell and scripting language designed especially for system administration. Built on the .NET Framework, Windows PowerShell helps IT professionals and power users control and automate the administration of the Windows operating system and applications that run on Windows." More on PowerShell here.

GP PowerShell is available for Microsoft Dynamics GP 2013 and above and can be found on the main application setup page.

Setup page
A couple clicks and you are ready to go.

The Problem

The GP PowerShell components install under the Microsoft Dynamics GP folder which contains a startup script, GPPowerShellStartupScript.ps1. A quick look at the code in Windows PowerShell ISE (or Notepad) quickly points out that this script is supposed to retrieve the path from where the script is being launched, concatenate said path with the locale, obtained from the .NET culture (in my case en-US, English United States) and the name of the file, Welcome.txt, to then show its content.

$ScriptRoot = $MyInvocation.PSScriptRoot


$GPPowerShellConfig = "$ScriptRoot\GPPowerShell.dll.config"
[appdomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $GPPowerShellConfig)
Add-Type -AssemblyName System.Configuration

$Locale = (Get-UICulture).Name
if (Test-Path "$ScriptRoot\$Locale\Welcome.txt")
{
    Get-Content "$ScriptRoot\$Locale\Welcome.txt"
}
else
{
    Get-Content "$ScriptRoot\en-US\Welcome.txt"
}


However, when this script is executed, I immediately get the error:

Get-Content : Cannot find path 'C:\en-US\Welcome.txt' because it does not exist.
At C:\Program Files (x86)\Microsoft Dynamics\GPPowerShell\GP2015\GPPowerShellStartupScript.ps1:14 char:5
+        Get-Content "$ScriptRoot\en-US\Welcome.txt"
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          + CategoryInfo : ObjectNotFound: (C:\en-US\Welcome.txt:String) [Get-Content], ItemNotFoundException
          + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand


The Solution

One thing I like about PowerShell is, the errors are pretty clear and concise as to what the problem is, in this case the path to the welcome.txt file is incorrect, and based on the result, the culprit can only be the $MyInvocation.PSScriptRoot not returning the path corresponding to the script's launch location.

In doing some research, I found that the method of obtaining the path of the current running script depends on the version of PowerShell and .NET Framework you are running. For more information on PowerShell scripting engine requirements click here.

For PowerShell 3+, you can simple use the global variable $PSScriptRoot. For all version of PowerShell, the below method works well:

Split-Path $MyInvocation.MyCommand.Path -Parent

This led me to think that perhaps this problem could have been easily taken care of by providing a universal function that could be called within the script, but we will address the issue with the previous method, as follows:


$ScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
# $ScriptRoot = $MyInvocation.PSScriptRoot

$GPPowerShellConfig = "$ScriptRoot\GPPowerShell.dll.config"
[appdomain]::CurrentDomain.SetData("APP_CONFIG_FILE", $GPPowerShellConfig)
Add-Type -AssemblyName System.Configuration

$Locale = (Get-UICulture).Name
if (Test-Path "$ScriptRoot\$Locale\Welcome.txt")
{
    Get-Content "$ScriptRoot\$Locale\Welcome.txt"
}
else
{
    Get-Content "$ScriptRoot\en-US\Welcome.txt"
}


After making these adjustments, the script produces the expected result:

Welcome to the Microsoft Dynamics GP 2015 PowerShell module.
For a list of GP cmdlets type 'Get-Command -module GP2015'.
Use 'Set-GPSessionCentralAddress' to connect to your GP Session Central Service before executing any other GP cmdlet.

After all, what would be of this world without a warm welcome ;-)

Until next post!

MG.-
Mariano Gomez, MVP

Rabu, 23 November 2016

Google Chrome Penalizes Websites Using SHA-1 SSL Certificates

Just recently, I was working with the Microsoft Dynamics GP 2016 web client and, as is customary, I run my tests on Google Chrome and Microsoft Internet Explorer and Edge browsers. When I brought up the web client website on Internet Explorer and Edge, nothing out of the ordinary seem to happen and effectively, the address bar is squeaky clean, as shown below:

Microsoft Edge address bar

Internet Explorer address bar

However, when you bring up the same site in Google Chrome, you are greeted with a site configuration warning and struck-out https prefix, as shown below

Chrome address bar

If you further click on the warning sign, you get additional information stating:

"This site uses a weak security configuration (SHA-1 signatures), so your connection may not be private."


The Details link is further more descriptive by opening the Chrome Security pane, where you get additional information stating the certificate expiration date is approaching soon and that the page is insecure.


So, I figured, an SSL certificate is an SSL certificate and SHA-1 is by far better than HTTP or no certificate at all (which is not supported by the web client). However, I started digging a bit more and, as it turned out, Google began phasing out support for SHA-1 certificates since version 42 of Chrome. The phase out has happened slowly. In version 42, users received a simple yellow warning triangle with a padlock to indicate the site used a weak SSL encryption, IF their certificate expired in 2016. If the certificate expires past 2016 -- like in the case of my certificate -- the user would receive a "broken https" indication.

However, at this point, it seems Google is not planning on blocking connection to sites with SHA-1 certificates, but this is not assurance that it won't happen. So what do you need to do? If you have third party certificates in place, you probably have already been contacted by your Certificate Authority company and they probably have issued you a SHA-256 certificate. If you are using Active Directory Certificate Store certificates, you can read up the Technet article on Implementing SHA-2 in Active Directory Certificate Services.

If you are using Self-Signed certificates, you may want to use these only in a development environment and forego their use in production.

If you are unsure of what type of encryption you are running, you can check your SLL certificates at:

Qualys SSL LABS

Note that the Qualys test can only be run on port 443.

Until next post!

MG.-
Mariano Gomez, MVP

Kamis, 03 November 2016

Microsoft Dynamics GP 2016 web client UI not displaying icons

Just today, I ran into a community forum post requesting an answer on why Microsoft Dynamics GP 2016 web client UI does not display icons. Since I had ran into this same issue before, I though I would I create this article to address the topic.

The Problem

Most users reporting this issue, experience things like the images shown below, where the Microsoft Dynamics GP logo and upper left corner application splash image are missing.

Microsoft Dynamics GP Sign In page (Sessions)

Furthermore, if you are able to access the application, mind you, sometimes this is not possible due to static content restrictions, you may find that your navigation bar and other areas of the application are missing the respective icons.

It is worth noting that in most cases, the missing icons do not negate the events of the buttons or objects they are associated with.

The theory

In web development, static content are files that don't change based on user input, and they consist of things like JavaScript, Cascading Style Sheets, Images, and HTML files. As you would expect, the Microsoft Dynamics GP web client icons and images fall within the category of static content. However, it is necessary to instruct the web server, in this case Internet Information Services (IIS), that it must publish any such content when identified.

Static Content is a feature that is turned on by default when IIS is deployed bare bones, this is, accepting all the default features - this is also known as deploying a static content IIS web server, which is the most basic of web servers.

The solution

Below, you will find instructions for Windows 10 and Windows Server 2012 and above.

Installing IIS Features on Windows 8 and Windows 10: Static Content

1. Right-click on Start and choose Program and Features



2. In the Windows Features window, locate and expand Internet Information Services.


3. Expand World Wide Web Services and Common HTTP Features.


4. Click on Static Content, to enable this feature.


5. Click the OK button. Windows 8 and Windows 10 will proceed to apply the selected changes. When finished, click the Close button to exit.


At this stage, a reboot may or may not be required. Follow any instructions provided after closing the window.

Installing IIS Features on Windows Server 2012 R2: Static Content

1. Open Server Manager by clicking the Server Manager icon on the task bar

2. In the Server Manager window, with the Dashboard and Quick Start selected, click Add roles and features, or click the Manage menu, and then click Add Roles and Features. The Add Roles and Features Wizard will start with a Before You Begin page. The wizard asks for verification of the following:

  • The administrator account has a strong password. 
  • The network settings, such as IP addresses, are configured. 
  • The most current security updates from Windows® Update are installed.
3. On the Before You Begin page, click Next.
4. On the Installation Type page, select Role-based or feature-based installation to configure a single server. Click Next.



5. On the Server Selection page, select Select a server from the server pool, and then select a server.


6. On the Server Roles page, expand Web Server (IIS).


7. Click Next twice to bypass the Features page and the Web Server Role (IIS) page.

8. On the Role Services page, expand Web Server and Common HTTP Features. Click to enable Static Content.


9. After you have added the role services that you need on the Role Services page, click Next.

10. On the Confirmation page, verify the role services and features that are selected. Select Restart the destination server automatically if required to restart the destination server if the settings need to take immediate effect. To save the configuration information to an XML-based file that you can use for unattended installations with Windows PowerShell, select Export configuration settings, move to the appropriate path in the Save As dialog box, enter a file name, and then click Save.

When you are ready to start the installation process on the Confirmation page, click Install.

Until next post!

MG.-
Mariano Gomez, MVP