我有一个cmdlet,我在其中接受字符串列表作为参数,该字符串在c#类中定义如下:
[Parameter(Mandatory = true)]
public List<string> AllowedScopes;
因此,当我调用名为Add-Client
的命令时,如何在PowerPhell中提供字符串列表?我已经尝试过了(每行是一种不同的方法):
-AllowedScopes scope1, scope2, scope3
-AllowedScopes [scope1, scope2, scope3]
-AllowedScopes {scope1, scope2, scope3}
-AllowedScopes {"scope1", "scope2", "scope3"}
但是我总是只在列表“ AllowedScopes”中获得一个条目,其中包含在AllowedScopes参数名称之后输入的完整字符串。
我对此一无所获,所以我想我问错了问题。
我当然可以将AllowedScopes参数设置为简单的字符串,然后执行以下操作:
var AllowedScopesAsList = this.AllowedScopes.Split(',').ToList();
但是我认为这应该是powershell提供的(因为它提供了许多其他有用的功能,使我无法实现cmdlet的整个用户交互部分)
编辑:这是我的cmdlet C#类的全部内容:
using System.Collections.Generic;
using System.Management.Automation;
namespace MyCmdlets
{
[Cmdlet("Add", "Client")]
public class AddClient : Cmdlet
{
[Parameter(Mandatory = true)]
public List<string> AllowedScopes;
protected override void ProcessRecord()
{
AllowedScopes.ForEach(a => WriteObject(a));
}
}
}
有了这个,如果我尝试像回答之一那样输入列表:
Add-Client -AllowedScopes @('scope1', 'scope2')
我得到以下输出:
<pre>
scope1
scope2
</pre>
符合预期。
但是,如果我在PowerShell询问时提供参数,则无法使用它,如下所示:
<pre>
PS> <b>Add-Client</b> <kbd>Enter</kbd>
Cmdlet Add-Client at CommandPipelineposition 1
Enter the values for the following parameter:
AllowedScopes[0]: <b>@('scope1','scope2')</b> <kbd>Enter</kbd>
AllowedScopes[1]: <kbd>Enter</kbd>
</pre>
现在的输出是这样:
@('scope1','scope2')
即使我在其中一一输入范围,它仍然会导致列表仅接收一个孩子:
<pre>
AllowedScopes[0]: <b>'scope1'</b>
AllowedScopes[1]: <b>'scope2'</b>
AllowedScopes[2]:
</pre>
输出:
<pre>
'scope1' 'scope2'
</pre>
/ edit2: 我上传了一个视频,因此您可以了解Powershell的行为是否与预期不符(至少我认为不这样):
答案 0 :(得分:5)
您似乎遇到了 bug ,这会影响Windows PowerShell(从v5.1开始)和PowerShell Core(从v6.1.0开始)
PowerShell的自动提示意外地将单独输入的元素作为单个字符串绑定到参数-AllowedScopes
,该字符串是单个元素的串联,并用空格分隔。
相比之下,从命令行传递值数组-例如,
-AllowedScopes scope1, scope2, scope3
-正常工作。
错误是由您将参数定义为List<string>
而不是string[]
触发的。
可以说,在这种情况下,string[]
还是更好的选择,因此解决方法是将-AllowedScopes
参数声明为string[]
(数组):
Add-Type -TypeDefinition @'
using System.Collections.Generic;
using System.Management.Automation;
namespace MyCmdlets
{
[Cmdlet("Add", "Client")]
public class AddClient : Cmdlet
{
[Parameter(Mandatory = true)]
// Use string[] instead of List<string>
public string[] AllowedScopes;
protected override void ProcessRecord()
{
foreach (var scope in AllowedScopes) {
WriteObject(scope);
}
}
}
}
'@ -PassThru | ForEach-Object Assembly | Import-Module
# Let PowerShell prompt for -AllowedScopes
# Due to use of string[] rather than List<string>, the individually entered
# elements are now correctly passed as an array.
Add-Client
请注意,如果将string
以外的类型用于通用列表,则错误不会出现。
带有一般信息的原始答案:
您的代码按设计工作,-AllowedScopes scope1, scope2, scope3
确实是传递多个列表元素的方式:
scope1, scope2, scope3
使用数组构造运算符,
构造一个3元素数组,该数组绑定到-AllowedScopes
参数并转换为List<string>
实例。
PowerShell的强制性参数自动提示机制(在命令行上未传递任何参数)也按设计工作:
对于集合类型的参数,例如-AllowedScopes
:
如果要允许用户使用单个提示符传递所有元素,则必须实现自定义逻辑:
将-AllowedScopes
声明为单个字符串,以便用户可以传递类似
'scope1, scope2, scope3'
将接收到的字符串值拆分为cmdlet内的嵌入式元素。
答案 1 :(得分:0)
尝试-AllowedScopes @('scope1', 'scope2', 'scope3')
@
构造表示一个数组,因此@(item,item,item,..)
组成一个值数组。