"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

Comments

Popular posts from this blog

Power Apps - Application Monitoring with Azure Application Insights

DBMS: 12 Microsoft Dynamics GP: 0 error when updating to Microsoft Dynamics GP 2013 R2

eConnect Integration Service for Microsoft Dynamics GP 2010