gpt4 book ai didi

validation - PowerShell : GetNewClosure() and Cmdlets with validation

转载 作者:行者123 更新时间:2023-12-03 21:11:32 25 4
gpt4 key购买 nike

我试图了解 .GetNewClosure() 如何在 PowerShell 2 中的脚本 cmdlet 的上下文中工作。

本质上,我有一个返回对象的函数,如下所示:

function Get-AnObject {
param(
[CmdletBinding()]
[Parameter(....)]
[String[]]$Id
..
[ValidateSet('Option1','Option2')]
[String[]]$Options
)

...

$T = New-Object PSCustomObject -Property @{ ..... }
$T | Add-Member -MemberType ScriptProperty -Name ExpensiveScriptProperty -Value {
$this | Get-ExpensiveStuff
}.GetNewClosure()

..
}

如果我没有验证集选项,则关闭似乎可以正常工作。但是,如果包含它,则新的闭包将失败并出现以下错误。

使用“0”参数调用“GetNewClosure”的异常:“无法添加属性,因为它会导致具有值的变量选项变得无效。”

据推测,闭包正试图捕获对 Cmdlet 的调用的上下文。由于参数“Options”根本没有绑定(bind),这与参数验证不太好。

我想可以通过将验证作为代码放置在 Cmdlet 的主体中而不是使用 [Validate*()] 装饰器来避免这种情况——但这看起来很讨厌而且很模糊。有没有办法融合这两个想法?

最佳答案

“无法添加属性”消息是(或曾经是)PowerShell 错误,我已使用 this bug report 将其提交给 Microsoft .该特定问题似乎已得到解决(可能在 V5.1 左右。但任何对 Powershell 闭包感兴趣的人可能仍然会发现以下有趣的信息。

有一个在早期版本中有效的解决方法,但首先这里有一个简化的重现案例,它会产生相同的错误:

function Test-ClosureWithValidation {
[CmdletBinding()]
param(
[Parameter()]
[ValidateSet('Option1','Option2')]
[String[]]$Options
)
[scriptblock] $closure = {"OK"}.GetNewClosure();
$closure.Invoke()
}

Test-ClosureWithValidation -Options Option1

解决方法取决于 GetNewClosure() 通过迭代 来工作。局部变量 在调用脚本的上下文中,将这些局部变量绑定(bind)到脚本的上下文中。出现该错误是因为它复制了包含验证属性的 $Options 变量。您可以通过仅使用所需的局部变量创建新上下文来解决该错误。在上面的简单复制中,它是一种单行解决方法:
    [scriptblock] $closure = &{ {"OK"}.GetNewClosure();}

上面的行现在创建了一个没有局部变量的作用域。对于您的情况,这可能太简单了;如果您需要外部范围的一些值,您可以将它们复制到新范围内的局部变量中,例如:
    [scriptblock] $closure = &{ 
$options = $options;
{"OK $options"}.GetNewClosure();
}

请注意,上面的第二行创建了一个新的 $options 变量,将外部变量的值分配给它,属性不会传播。

最后,我不确定在你的例子中为什么你需要调用 GetNewClosure 。变量 $this 不是普通的局部变量,无论您是否创建闭包,它都将在您的脚本属性中可用。例子:
function Test-ScriptPropertyWithoutClosure {
[CmdletBinding()]
param(
[Parameter()]
[ValidateSet('Option1','Option2')]
[String[]]$Options
)
[pscustomobject]@{ Timestamp= Get-Date} |
Add-Member ScriptProperty ExpensiveScriptProperty {
$this | get-member -MemberType Properties| % Name
} -PassThru
}

Test-ScriptPropertyWithoutClosure -Options Option1 | fl

关于validation - PowerShell : GetNewClosure() and Cmdlets with validation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19775779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com