【问题标题】:Import-Module won't work when launched from .net从 .net 启动时,导入模块不起作用
【发布时间】:2015-05-13 06:11:25
【问题描述】:

我正在尝试在我的 C# Web 应用程序中运行一个 powershell 脚本。

当我在 powershell 中运行以下命令时,它工作正常。

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

Get-NAVTenant -ServerInstance DynamicsHost

但是当我使用我的网络应用程序运行它时,它会告诉我

“Get-NAVTenant -ServerInstance DynamicsHost”一词未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。检查名称的拼写,如果包含路径,请验证路径是否正确,然后重试。

这是我的 C# 代码:

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());
    }

有人能指出我正确的方向吗?

更新:

使用 runspace.SessionStateProxy.PSVariable.GetValue("Error") 我可以看到以下错误:

无法将参数绑定到参数“名称”,因为它为空。

无法将参数绑定到参数“路径”,因为它为空。

找不到路径“HKLM:\SOFTWARE\Microsoft\Microsoft Dynamics NAV\80\Service”,因为它不存在。

提示用户的命令失败,因为主机程序或命令类型不支持用户交互。尝试支持用户交互的主机程序,例如 Windows PowerShell 控制台或 Windows PowerShell ISE,并从不支持用户交互的命令类型(例如 Windows PowerShell 工作流)中删除与提示相关的命令。

提示用户的命令失败,因为主机程序或命令类型不支持用户交互。尝试支持用户交互的主机程序,例如 Windows PowerShell 控制台或 Windows PowerShell ISE,并从不支持用户交互的命令类型(例如 Windows PowerShell 工作流)中删除与提示相关的命令。

提示用户的命令失败,因为主机程序或命令类型不支持用户交互。尝试支持用户交互的主机程序,例如 Windows PowerShell 控制台或 Windows PowerShell ISE,并从不支持用户交互的命令类型(例如 Windows PowerShell 工作流)中删除与提示相关的命令。

【问题讨论】:

  • This 可以帮助您解决问题。您可以从runspace.SessionStateProxy.PSVariable.GetValue("Error") 获取模块导入错误。
  • 您必须单独添加 cmdlet 及其参数。

标签: c# .net powershell


【解决方案1】:

错误消息表明您的整个命令字符串被解释为(不存在的)cmdlet 的名称。根据documentationAddCommand() 方法需要 cmdlet 的名称,而参数应通过 AddParameter() 添加。

尝试改变这个:

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

进入这个:

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

或者这个:

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

【讨论】:

    【解决方案2】:

    我可以验证上面发布的以下代码是否有效:以下代码将返回指定 Dynamics NAV 服务层的 DatabaseServer 名称

            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();
    

    更好更快的方法是直接使用 Microsoft.Dynamics.Nav.Management 管理单元。使用这种方法可以看到显着的性能提升。请在此处查看以下代码: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();
                }
            }
    

    【讨论】:

    • 您发布的第一个代码仍然返回:{“术语 'Get-NAVTenant' 未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,或者如果包含路径,请验证路径是否正确,然后重试。"}
    • 第二个找不到Microsoft.Dynamics.Nav.Management..我猜我需要安装管理包?
    • 抱歉,我假设您已经安装了 Dynamics NAV。
    • 虽然很有趣......上述代码都不能在 .Net 应用程序中工作,特别是在 API 中。如果您有任何想法,我很想听听。
    • 也许我应该在一开始就阅读您的评论。我刚刚也描述了你的问题。 .
    【解决方案3】:

    原来是开发者网络服务器无法处理请求。切换到 IIS 作为开发者服务器解决了这个问题。现在watto的两个例子都有效。

    【讨论】:

      猜你喜欢
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多