是否有一种简洁的方法将一些现有变量作为参数传递给Powershell函数?

是否有一种简洁的方法将一些现有变量作为参数传递给Powershell函数?,powershell,Powershell,我似乎经常发现自己处于这样一种情况:我设置了一组变量,并且我想将它们传递给一个函数(例如,在不修改的情况下将参数传递给另一个函数)。现在我做的事情是这样的: Get-RelatedThing -CompanyTag $CompanyTag -ProjectTag $ProjectTag -EnvName $EnvName 这似乎冗长,可读性不强。我可以使用位置参数,但这会牺牲清晰度和兼容性。预先创建一个数组和散乱只会产生垂直的混乱,而不是水平的混乱(除非在不寻常的情况下,我可以做一些事情,比如

我似乎经常发现自己处于这样一种情况:我设置了一组变量,并且我想将它们传递给一个函数(例如,在不修改的情况下将参数传递给另一个函数)。现在我做的事情是这样的:

Get-RelatedThing -CompanyTag $CompanyTag -ProjectTag $ProjectTag -EnvName $EnvName
这似乎冗长,可读性不强。我可以使用位置参数,但这会牺牲清晰度和兼容性。预先创建一个数组和散乱只会产生垂直的混乱,而不是水平的混乱(除非在不寻常的情况下,我可以做一些事情,比如Get RelatedThing@PSBoundParameters,但这有陷阱)

我真正想要的是能够做一些事情,比如:

Get-RelatedThing @(Get-Variable CompanyTag,ProjectTag,EnvName)
但是Get变量返回一个Object[],splatting操作符只能解析一个命名参数的哈希表(或一个位置参数数组)。我需要一个函数来解决这个问题:

function Get-VariablesAsHashtable {

[CmdletBinding()]
param
(
    [Parameter(Position=0)]
    [string[]] $Name
)

$ObjectArray = Get-Variable -Name @($Name)

$Hashtable = @{}
$ObjectArray | Foreach { $Hashtable[$_.Name] = $_.Value }

return $Hashtable

}
“提前”运行时有效:

但在运行“内联”时不是:


我是否遗漏了一些可以修复这种方法的东西?或者有更好的方法吗?

看看这是否有效:

Get-RelatedThing @($(Get-Variable CompanyTag,ProjectTag,EnvName))
你可以用一个不同的函数来简化它。这显示了散列表的效果:

$Params = @{
CompanyTag = 'Company1'
ProjectTag = 'Project1'
EnvName    = 'Env1'
}

[Scriptblock]::Create("$(&{$args}@Params)")

-EnvName: Env1 -CompanyTag: Company1 -ProjectTag: Project1
修改原始函数以复制该函数:

function Get-VariablesAsParameters {

[CmdletBinding()]
param
(
    [Parameter(Position=0)]
    [string[]] $Name
)

$ObjectArray = Get-Variable -Name @($Name)
[string]($ObjectArray | Foreach { '-{0}: {1}' -f $_.Name,$_.Value})

}

function Get-RelatedThing {$args}

Get-RelatedThing $(Get-VariablesAsParameters CompanyTag,ProjectTag,EnvName)
-CompanyTag: Company1 -ProjectTag: Project1 -EnvName: Env1

实际上,您错误地认为Splating只适用于哈希表。它也可以很好地处理数组,但它使用数组的每个元素作为位置参数来调用命令。如果首先确定所有值都存在,则可以简单地显示数组:

function Test-Binding {
param (
    $Foo,
    $Bar
)
    "Foo: $Foo"
    "Bar: $Bar"
}

$Foo = 'first value'
$Bar = 'other value'

$Splat = @(Get-Variable -ValueOnly Foo, Bar)

Test-Binding @Splat
您尝试的内联语法失败的原因很简单:在这种情况下,您没有浪费时间。你在这一行真正做的是:

(Get-RelatedThing @(Get-VariablesAsHashtable ProjectTag,EnvName,ComponentTag));
。。。传递一个参数,强制它成为一个数组(在本例中,
@()
代表该数组),一个哈希表数组(函数生成的数组)。无法将您正在构建的哈希表显示为“临时”。您需要首先构建它,存储在变量x中,然后使用
@x
文本而不是通常的
$x
将此变量作为“splat”传递


我听到有人建议填补这一空白(使用类似于:
command@@@foo='bar}
),但直到那时,您必须首先构建哈希表/数组,并使用变量名和
@
前缀来显示它。

Get RelatedThing@($(Get variable CompanyTag,ProjectTag,EnvName))
Get RelatedThing@(Get variableshashtable ProjectTag、EnvName、ComponentTag)的工作原理没有任何区别。
对于我来说……Get Variable返回PSVariable的对象类型。函数需要字符串。如果您想使用get variable只传递变量的值,则必须使用get variable | select-expandproperty value或(get variable)。value谢谢,这正是我想要的。编辑我的问题以反映将数组用作splat输入的可能性。
function Test-Binding {
param (
    $Foo,
    $Bar
)
    "Foo: $Foo"
    "Bar: $Bar"
}

$Foo = 'first value'
$Bar = 'other value'

$Splat = @(Get-Variable -ValueOnly Foo, Bar)

Test-Binding @Splat
(Get-RelatedThing @(Get-VariablesAsHashtable ProjectTag,EnvName,ComponentTag));