在PowerShell脚本中,我想要读取包含以下内容的CSV文件:
Type Title Param1 Param2
---- ----- ------ ------
Type1 Foo type 1 ValueForType1
Type2 Foo type 2 ValueForType2
当type为Type1
时,我必须调用名为New-FooType1
的函数,当type为Type2
时,函数名为New-FooType2
,依此类推:
function New-FooType1{
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Title,
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Param1
)
Write-Host "New-FooType1 $Title with $Param1"
}
function New-FooType2{
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Title,
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Param2
)
Write-Host "New-FooType2 $Title with $Param2"
}
我正在尝试使用动态调用路由对任一函数的调用:
$csv | % {
$cmdName = "New-Foo$($_.Type)"
Invoke-Command (gcm $cmdName) -InputObject $_
}
但是,我总是收到错误:
无法使用指定的命名参数
解析参数集
如您所见,不同的类型意味着设置不同的参数。
我该如何解决这个问题?我想避免手动操作属性,因为在我的现实生活中,我有十几种不同的类型,最多有6个参数。
以下是该问题的完整重复示例:
$csvData = "Type;Title;Param1;Param2`nType1;Foo type 1;ValueForType1;;`nType2;Foo type 2;;ValueForType2"
$csv = ConvertFrom-csv $csvData -Delimiter ';'
$csv | ft -AutoSize
function New-FooType1{
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Title,
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Param1
)
Write-Host "New-FooType1 $Title with $Param1"
}
function New-FooType2{
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Title,
[Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$Param2
)
Write-Host "New-FooType2 $Title with $Param2"
}
$csv | % {
$cmdName = "New-Foo$($_.Type)"
Invoke-Command (gcm $cmdName) -InputObject $_
}
此脚本的预期输出为:
New-FooType1 Foo type 1 with ValueForType1
New-FooType2 Foo type 2 with ValueForType2
答案 0 :(得分:4)
使用呼叫运营商thread.last_message
:
&
如果您希望参数绑定到特定的命名参数,则调用运算符也支持splatting:
$CmdName = "New-FooType1"
$Arguments = "type1"
& $CmdName $Arguments
答案 1 :(得分:2)
要按名称调用命令,您应该使用调用操作符&
。 Invoke-Command
cmdlet仅支持ScriptBlock
和文件调用,并且仅支持远程调用的文件调用。
对于动态参数绑定,您可以使用spatting,但在这种情况下,您必须将PSCustomObject
cmdlet返回的ConvertFrom-Csv
转换为Hashtable
。您还必须从Hashtable
中删除任何额外的参数,因为如果您尝试绑定不存在的参数,则splatting将失败。
动态参数绑定的另一种方法是使用来自管道对象的绑定。它看起来就像你想要做的那样,因为你用ValueFromPipelineByPropertyName
选项标记了所有参数。而这种方法只会忽略它无法绑定到参数的任何额外属性。我建议你删除ValueFromPipeline
选项,因为如果没有带参数名称的属性,使用此选项PowerShell只会将PSCustomObject
转换为字符串(或用于参数的任何类型)并将其作为参数传递给参数值。
因此,您只需要通过管道传递对象并使用invoke运算符来调用具有动态名称的命令:
$_ | & "New-Foo$($_.Type)"
答案 2 :(得分:-2)
不知道你想要做什么,但是 Invoke-Command(gcm $ cmdName)?
尝试使用invoke-expression $ cmdname