PowerShell 对象返回 null

问题描述

我有以下命令,它返回给我 null object 。当我在 PowerShell 窗口中单独运行命令时,我得到了正确的结果。下面是我的 PowerShell 方法,它调用命令以及我定义的 PowerShell 命令。我基本上希望返回一个字符串值。请让我知道我做错了什么?

C# 方法

     public string RunScript( string contentScript,Dictionary<string,EntityProperty> parameters)
            {
                List<string> parameterList = new List<string>();
                foreach( var item in parameters )
                {
                    parameterList.Add( item.Value.ToString() );
                }
               
                using( PowerShell ps = PowerShell.Create() )
                {
                    ps.AddScript( contentScript );
// in ContentScript I get "Get-RowAndPartitionKey" on debugging
                    ps.AddParameters( parameterList );//I get list of strings
                   
                    IAsyncResult async = ps.BeginInvoke();
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach( PSObject result in ps.EndInvoke( async ) )
// here i get result empty in ps.EndInvoke(async)
                    {
                        stringBuilder.AppendLine( result.ToString() );
                    }
                    return stringBuilder.ToString();
                }
            }
        }

我的 Powershell GetRowAndPartitionKey cmdlet 定义,上面的代码试图调用它:

public abstract class GetRowAndPartitionKey : PSCmdlet
    {
        [Parameter]
        public List<string> Properties { get; set; } = new List<string>();
    }

    [Cmdlet( VerbsCommon.Get,"RowAndPartitionKey" )]
    public class GetRowAndPartitionKeyCmd : GetRowAndPartitionKey

    {
        protected override void ProcessRecord()
        {
            string rowKey = string.Join( "_",Properties );
            string pKey = string.Empty;
            
            WriteObject( new
            {
                RowKey = rowKey,PartitionKey = pKey
            } );
        }
    }
}

解决方法

使用 PowerShell SDK 时,如果您想使用 .AddParameter() / .AddParameters() / {{1} 将参数传递给单个命令 },使用.AddCommand(),而不是AddArgument()

.AddScript() 用于传递任意段 PowerShell 代码,这些代码作为 脚本块 执行,添加了 .AddScript() 的参数将传递给该代码块.

也就是说,您的调用等效于 .AddParameters(),正如您所见,您的 & { Get-RowAndPartitionKey } <your-parameters> 命令因此不会接收参数值。

查看 this answer 或更多信息。


注意:作为调用自定义 Get-RowAndPartitionKey cmdlet 的先决条件,您可能必须显式导入包含它的模块 (DLL),可以做:

  • 任一:使用一个单独的同步 Get-RowAndPartitionKey 调用 预先执行(为简单起见,我在这里使用 Import-Module,并传递一个参数 位置,它绑定到 .AddArgument() 参数(也接受路径)):

    -Name
  • 或:作为单个(在本例中为异步)调用的一部分 - 请注意分隔两个命令所需的 ps.AddCommand("Import-Module").AddArgument(@"<your-module-path-here>").Invoke(); 调用:

    .AddStatement()

IAsyncResult async = ps.AddCommand("Import-Module").AddArgument(@"<your-module-path-here>") .AddStatement() .AddCommand("GetRowAndPartitionKey").AddParameter("Properties",parameterList) .BeginInvoke(); 是指包含 "<your-module-path-here>" cmdlet 的模块的完整文件系统路径;根据该模块的实现方式,它可以是模块的目录、其 Get-RowAndPartitionKey 模块清单的路径,或者是其 .psd1(如果它是独立的)组装。

替代导入方法,使用 PowerShell SDK 的专用 .ImportPSModule() 方法

此方法无需在会话中调用 .dll,但需要额外设置:

  • 创建默认会话状态。
  • 在其上调用 Import-Module 以导入模块。
  • 将此会话状态传递给 .ImportPSModule()
PowerShell.Create()

警告var iss = InitialSessionState.CreateDefault(); iss.ImportPSModule(new string[] { @"<your-module-path-here>" }); var ps = PowerShell.Create(iss); // Now the PowerShell commands submitted to the `ps` instance // will see the module's exported commands. 实例在 PowerShell 中反映其初始会话状态,但作为概念上的只读属性;棘手的部分是它技术上仍然可以修改,因此修改它的错误尝试被悄悄地忽略而不是导致异常。


解决这些调用:

  • 检查 .Runspace.InitialSessionState / ps.HadErrors 之后的 .Invoke() 以查看 PowerShell 命令是否报告了任何(非终止)错误。

  • 枚举 .EndInvoke() 以检查发生的特定错误。

有关演示这些技术的自包含示例代码的后续问题,请参阅 this answer

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...