首页 > 解决方案 > Powershell splatting 运算符仅适用于接受的参数?

问题描述

当哈希表包含函数接受的更多条目时,是否可以使用 PowerShell 从哈希表中使用飞溅?

我的用例是让配置对象从一个函数传递到另一个函数。但是,并非所有函数都需要相同的参数。

前任:

function Process-Something{
    param(
        [Parameter()]
        [string]$Owner
    )


}

function Process-SomethingElse{
    param(
        [Parameter()]
        [string]$Owner,
        [Parameter()]
        [int]$x,
        [Parameter()]
        [int]$y

    )
}


$config = @{
    "Owner" = "Bart Simpson"
    "X" = 10
    "Y" = 20
}

Process-Something @config
Process-SomethingElse @config

它失败并出现以下错误:

Process-Something : Cannot find a matching parameter « Y ».

这个想法是避免为每个函数指定单独的属性。

标签: powershell

解决方案


正如@Ansgar 在评论中所说,定义参数的整个想法是获得验证。当您向函数添加参数时,您是在将它们强制添加到函数中。因此,如果您的哈希表的给定属性不作为参数存在,您将收到错误 - 就像它预期的那样。

可以做的是进入 PSCustomObject 并使用管道。如果您使用属性名称 () 将所有参数设置为接受来自管道的值ValueFromPipelineByPropertyName = $true,那么您实际上可以获得所需的行为。

首先,我正在重新定义您的不同功能,以ValueFromPipelineByPropertyName = $true配置参数属性。

function Process-Something{
    param(
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [string]$Owner
    )

    $PSBoundParameters
}

function Process-SomethingElse{
    param(
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [string]$Owner,
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]$x,
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]$y

    )

    $PSBoundParameters
}    

有了这个,我就可以像你的例子一样创建一个哈希表,将它转换为一个 PSCustomObject,现在我可以将该新对象通过管道传递给不同的方法,让它们只获取他们需要的属性。

我包括PSBoundParameters展示他们得到他们期望的东西。测试是这样完成的:

$config = @{
    "Owner" = "Bart Simpson"
    "X" = 10
    "Y" = 20
}

$psConfig = [PSCustomObject]$config

$psConfig | Process-Something

$psConfig | Process-SomethingElse

在此处输入图像描述


推荐阅读