1

我有这段代码,我在其中加载了一个管理单元(在这种情况下来自 MS Dynamics NAV):

            using (Runspace runspace = RunspaceFactory.CreateRunspace())
        {
            runspace.Open();

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = runspace;

                ps.AddScript("Add-PSSnapin Microsoft.Dynamics.Nav.Management")
                  .AddScript("Get-NAVServerInstance");

                //This does not work. Says unknown cmdlet Get-NAVServerInstance
                //ps.AddCommand("Add-PSSnapin").AddArgument("Microsoft.Dynamics.Nav.Management")
                //  .AddCommand("Get-NAVServerInstance");

                var output = ps.Invoke();
            }
        }

当我使用代码中所示的 AddScript 方法时,此代码有效。但是为什么 AddCommand 方法不起作用(参见注释代码)?似乎未加载管理单元,因为错误表明 Get-NAVServerInstance cmdlet 未知。这应该如何工作?

我知道我可以使用在其上导入管理单元的 InitialSessionState 创建运行空间。然后 ps.AddCommand("Get-NAVServerInstance") 正在工作。但是当我想创建一个远程运行空间会话(使用 WSManConnectionInfo)时,我找不到提供初始会话状态的方法。

更新:所以似乎 AddCommand 只能用于在运行空间打开(或创建?)时可用的 cmdlet。将 InitialSessionState 或 RunspaceConfiguration 实例与 RunspaceFactory.CreateRunspace(...) 一起使用即可。所以这段代码有效:

    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-NAVServerInstance");
            var output = ps.Invoke();
        }
    }

但我的问题是在这种情况下,我无法指定 WSManConnectionInfo 实例。

那么,如何使用加载了 snapin(安装在远程机器上)的远程连接创建运行空间?如何为远程连接提供配置?

4

2 回答 2

4

我终于找到了如何配置远程会话的提示(请参阅https://superuser.com/a/518567)。

您需要在远程计算机上注册会话配置

Register-PSSessionConfiguration -Name MyShell -StartupScript 'MyInitScript.ps1'

然后可以将 WSManConnectionInfo 的 shellUri 参数设置为http://schemas.microsoft.com/powershell/MyShell

您以这种方式创建的运行空间将具有由 MyInitScript.ps1 启动脚本导入的可用命令。

所以现在这段代码可以工作了:

        string shell = "http://schemas.microsoft.com/powershell/MyShell";
        var target = new Uri("https://myserver:port/wsman");
        var secured = new SecureString();
        foreach (char letter in "password")
        {
            secured.AppendChar(letter);
        }
        secured.MakeReadOnly();

        var credential = new PSCredential("username", secured);
        var connectionInfo = new WSManConnectionInfo(target, shell, credential);

        using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
        {
            runspace.Open();

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = runspace;
                ps.AddCommand("Get-NAVServerInstance");
                var output = ps.Invoke();
            }
        }
于 2013-08-21T11:26:39.830 回答
0

尝试像这样调用 AddScript:

.AddScript("...", false)

这将在全局范围内执行命令,而不是在新的本地范围内执行。

我认为正确的方法是使用 RunspaceConfiguration 类。它有一个AddPSSnapin方法。

于 2013-08-20T18:21:29.947 回答