1

I'm trying to run a powershell script within my C# web application.

When i run the following in powershell, it works fine.

Import-Module 'C:\\Program Files\\Microsoft Dynamics NAV\\80\\Service\\NavAdminTool.ps1'

Get-NAVTenant -ServerInstance DynamicsHost

But when i'm running it using my web application, it tells me

The term 'Get-NAVTenant -ServerInstance DynamicsHost' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

Here is my c# code:

InitialSessionState initial = InitialSessionState.CreateDefault();
    initial.ImportPSModule(new string[] { "C:\\Program Files\\Microsoft Dynamics NAV\\80\\Service\\NavAdminTool.ps1" });
    Runspace runspace = RunspaceFactory.CreateRunspace(initial);
    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;
    ps.Commands.AddCommand("Get-NAVTenant -ServerInstance DynamicsHost");

    foreach (PSObject result in ps.Invoke())
    {
        Console.WriteLine(result.ToString());
    }

Can someone point me in the right direction??

UPDATE:

Using runspace.SessionStateProxy.PSVariable.GetValue("Error") i could see the following error:

Cannot bind argument to parameter 'Name' because it is null.

Cannot bind argument to parameter 'Path' because it is null.

Cannot find path 'HKLM:\SOFTWARE\Microsoft\Microsoft Dynamics NAV\80\Service' because it does not exist.

A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows.

A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows.

A command that prompts the user failed because the host program or the command type does not support user interaction. Try a host program that supports user interaction, such as the Windows PowerShell Console or Windows PowerShell ISE, and remove prompt-related commands from command types that do not support user interaction, such as Windows PowerShell workflows.

Community
  • 1
  • 1
Jesper TP
  • 137
  • 2
  • 11
  • [This](http://stackoverflow.com/a/13935680/517852) may help you troubleshoot. You can get the module import errors from `runspace.SessionStateProxy.PSVariable.GetValue("Error")`. – Mike Zboray May 13 '15 at 06:31
  • 1
    You have to add the cmdlet and its args separately. – 1.618 May 13 '15 at 07:10

3 Answers3

1

The error message suggests that your entire command string is interpreted as the name of a (non-existent) cmdlet. According to the documentation the AddCommand() method expects the name of a cmdlet, while parameters should be added via AddParameter().

Try changing this:

ps.Commands.AddCommand("Get-NAVTenant -ServerInstance DynamicsHost");

into this:

ps.Commands.AddCommand("Get-NAVTenant");
ps.Commands.AddParameter("-ServerInstance", "DynamicsHost");

or this:

ps.AddCommand("Get-NAVTenant");
ps.AddParameter("-ServerInstance", "DynamicsHost");
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
1

I can verify the following code works, posted from above: the following code will return the DatabaseServer name of the specified Dynamics NAV service tier

        InitialSessionState initial = InitialSessionState.CreateDefault();
        initial.ImportPSModule(new string[] { "C:\\Program Files\\Microsoft Dynamics NAV\\80\\Service\\NavAdminTool.ps1" });
        Runspace runspace = RunspaceFactory.CreateRunspace(initial);
        runspace.Open();
        PowerShell ps = PowerShell.Create();
        ps.Runspace = runspace;
        ps.Commands.AddCommand("Get-NAVTenant");
        ps.Commands.AddParameter("-ServerInstance", "objectupgrade");                        

        foreach (PSObject result in ps.Invoke())
        {
            Console.WriteLine(result.Properties["DatabaseServer"].Value);
        }
        Console.Read();
        Console.ReadKey();

A better and a much quicker method is to use the Microsoft.Dynamics.Nav.Management snap-in directly. Significant performance improvement can be seen by using this method. Please see following code found here: Why does PowerShell class not load a snapin

        var config = RunspaceConfiguration.Create();
        PSSnapInException warning;
        config.AddPSSnapIn("Microsoft.Dynamics.Nav.Management", out warning);

        using (Runspace runspace = RunspaceFactory.CreateRunspace(config))
        {
            runspace.Open();
            using (var ps = PowerShell.Create())
            {
                ps.Runspace = runspace;
                ps.AddCommand("Get-NAVTenant");
                ps.AddParameter("ServerInstance", "ObjectUpgrade");
                Collection<PSObject> results = ps.Invoke();
                foreach (PSObject obj in results)
                {
                    Console.WriteLine(obj.Properties["DatabaseServer"].Value);                            
                }
                Console.Read();
                Console.ReadKey();
            }
        }
Community
  • 1
  • 1
watto
  • 11
  • 1
  • The first code you posted still returns: {"The term 'Get-NAVTenant' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."} – Jesper TP May 13 '15 at 08:47
  • The second cannot find Microsoft.Dynamics.Nav.Management.. I gues that I need to install the management package? – Jesper TP May 13 '15 at 08:48
  • Sorry, yes I assumed that you had already Dynamics NAV already installed. – watto May 15 '15 at 14:14
  • Interesting though ... none of the above mentioned code works in a .Net application, specifically in an API. If you have any ideas why not i'd love to hear them. – watto May 15 '15 at 14:34
  • Maybe i should have read your comment at the beginning. I've just described your issue as well. . – watto May 15 '15 at 14:41
  • The reason why it did not work was, that the developper webserver that comes with visual studio can't use the modules.. When I ran the exact same code on the IIS 8.0 it worked fine.. – Jesper TP May 18 '15 at 06:29
0

It turned out to be that the developer web server could't handle the request. Switching to IIS as developer server solved the problem. Now both of watto's examples works.

Jesper TP
  • 137
  • 2
  • 11