PowerShell 对象 returns 空
PowerShell Object returns null
我有以下命令,它return是我的空对象。当我 运行 在 PowerShell window 中单独执行命令时,我得到了正确的结果。下面是我调用命令的 PowerShell 方法以及我定义的 PowerShell 命令。我基本上是在寻找 return 一个字符串值。请让我知道我做错了什么?
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()
/ AddArgument()
, 使用 .AddCommand()
, 而不是 .AddScript()
.AddScript()
用于传递作为 脚本块 执行的任意 PowerShell 代码 ,其中添加了参数.AddParameters()
通过。
也就是说,您的调用等同于 & { Get-RowAndPartitionKey } <your-parameters>
,如您所见,您的 Get-RowAndPartitionKey
命令因此不会接收参数值。
参见 this answer 或更多信息。
注意:作为调用自定义 Get-RowAndPartitionKey
cmdlet 的 先决条件,您可能必须显式 导入包含它的模块 (DLL) ,你可以这样做:
或者:在之前执行一个单独的同步Import-Module
调用(为简单起见,我在这里使用.AddArgument()
, with 传递参数 positionally,它绑定到 -Name
参数(它也接受 paths):
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>"
指的是包含 Get-RowAndPartitionKey
cmdlet 的模块的完整文件系统路径;根据该模块的实现方式,它要么是模块 目录 、.psd1
模块清单的路径,要么是 .dll
的路径,如果它是独立程序集。
替代导入方法,使用 PowerShell SDK 的专用 .ImportPSModule()
方法:
此方法无需会话中 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
中的初始会话状态,但在概念上 只读 属性;棘手的部分是它技术上仍然可以修改,因此错误的修改它的尝试会被悄悄忽略而不是导致异常。
要排除 这些调用的故障:
在 .Invoke()
/ .EndInvoke()
之后检查 ps.HadErrors
以查看 PowerShell 命令是否报告任何(非终止)错误。
枚举 ps.Streams.Errors
以检查发生的具体错误。
请参阅 this answer 后续问题,了解演示这些技术的独立示例代码。
我有以下命令,它return是我的空对象。当我 运行 在 PowerShell window 中单独执行命令时,我得到了正确的结果。下面是我调用命令的 PowerShell 方法以及我定义的 PowerShell 命令。我基本上是在寻找 return 一个字符串值。请让我知道我做错了什么?
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()
/ AddArgument()
, 使用 .AddCommand()
, 而不是 .AddScript()
.AddScript()
用于传递作为 脚本块 执行的任意 PowerShell 代码 ,其中添加了参数.AddParameters()
通过。
也就是说,您的调用等同于 & { Get-RowAndPartitionKey } <your-parameters>
,如您所见,您的 Get-RowAndPartitionKey
命令因此不会接收参数值。
参见 this answer 或更多信息。
注意:作为调用自定义 Get-RowAndPartitionKey
cmdlet 的 先决条件,您可能必须显式 导入包含它的模块 (DLL) ,你可以这样做:
或者:在之前执行一个单独的同步
Import-Module
调用(为简单起见,我在这里使用.AddArgument()
, with 传递参数 positionally,它绑定到-Name
参数(它也接受 paths):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>"
指的是包含 Get-RowAndPartitionKey
cmdlet 的模块的完整文件系统路径;根据该模块的实现方式,它要么是模块 目录 、.psd1
模块清单的路径,要么是 .dll
的路径,如果它是独立程序集。
替代导入方法,使用 PowerShell SDK 的专用 .ImportPSModule()
方法:
此方法无需会话中 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
中的初始会话状态,但在概念上 只读 属性;棘手的部分是它技术上仍然可以修改,因此错误的修改它的尝试会被悄悄忽略而不是导致异常。
要排除 这些调用的故障:
在
.Invoke()
/.EndInvoke()
之后检查ps.HadErrors
以查看 PowerShell 命令是否报告任何(非终止)错误。枚举
ps.Streams.Errors
以检查发生的具体错误。
请参阅 this answer 后续问题,了解演示这些技术的独立示例代码。