【问题标题】:Powershell: Dynamic Param that references a Static Param Errors when using Get-Help. How to Suppress error?Powershell:使用 Get-Help 时引用静态参数错误的动态参数。如何抑制错误?
【发布时间】:2020-07-08 16:35:02
【问题描述】:

模块变量

$ModVar = @{Value = Key}

使用静态参数-Name 作为关键引用时出错。

PS> help Test-Function

InvalidOperation: 
Line |
 214 |              $ModItem = $ModVar[$Name]
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Index operation failed; the array index evaluated to null.

我相信这是因为参数-Name 直到执行时才存在。该功能在使用时正常工作,仅在使用Get-Help时发生此错误。

是否有规避错误的方法?

我试过了:

If (!$Name) {$Name = "A_Key_in_ModVar"}

试图在未检测到-Name 中的值时提供一个虚拟值,但这会导致函数始终覆盖-Name 的值,即使参数-Name 提供了一个来自终端的显式值。

要点示例:GitHub to Get-KeyAndPeeleSchoolName

代码片段(上面的完整示例):

DynamicParam {

        $ParameterName = 'School'

        $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        Write-Error $Name
        $attSet = $Table[$Name]
        Write-Error $attSet
        $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($attSet)
        $ValidateSetAttribute.ErrorMessage = "Value must be $attSet"
        $AttributeCollection.Add($ValidateSetAttribute)

    $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
    $ParameterAttribute.ParameterSetName = "ParamSet1"
    $AttributeCollection.Add($ParameterAttribute)

        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
        $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)

        $RuntimeParameterDictionary
    }

编辑 1:我注意到的其他问题。

包含空格的 -Name 值会阻止包含 -School 的动态参数块工作。

此外,当在 -Names 上使用 ArgumentCompleter 时,具有复杂标点的可能值无法完全自动完成。这可能是因为匹配行为,但任何关于如何使其行为的建议都会很棒。

在参数值周围使用“”引号也会阻止参数完成器工作,对此的任何建议也很好。

【问题讨论】:

  • 这个问题我不清楚。 !您使用的是实际的动态参数块吗?如果是这样,ArgumentCompleter 通常在所有方面都做得更好。如果您通过“我在函数中使用模块变量”来表示“动态”,那么这不是问题。我觉得很奇怪,尽管求助电话有错误。你能完全发布这个函数吗(也许把它减少到最小的可重现样本)
  • 见要点。有关其他问题,请参阅编辑 1。
  • 为什么不删除动态参数并使用第二个参数完成器?除了在所有级别上更好地工作之外,唯一的区别是您的结果集不会是验证集。因此,如果值无效,则必须添加额外的行以引发错误。
  • 我会留下一个更有知识的人回答如何专门用动态参数解决问题。
  • 请记住这是我创建的示例,不是我正在使用的实际代码,但错误是完全相同的,使用参数完成器的动态参数的实现也是相同的.我想让他们只能从动态参数的一组有​​效值中进行选择。我可以在 Begin Block 中处理这个逻辑,但是在参数验证期间完成它是有意义的,所以我想了解如何。

标签: powershell


【解决方案1】:

在 IF 语句中包装 [RuntimeDefinedParameterDictionary] 对象和随附的构造解决了该问题。当-Name 未明确传递值时,-Name 不存在预绑定。当Get-Help运行分析Function的构成时也不可用。

要解决此问题,请检查 DynamicParam 块中引用的参数是否存在以控制其执行。

DynamicParam {

if ($Name) { #If $Name exist create Dynamic Param.

        $ParameterName = 'School'

        $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        
        $attSet = $Table[$Name]
        $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($attSet)
        $ValidateSetAttribute.ErrorMessage = "Value must be $attSet"
        $AttributeCollection.Add($ValidateSetAttribute)

        $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
        $ParameterAttribute.ParameterSetName = "ParamSet1"
        $AttributeCollection.Add($ParameterAttribute)

        $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
        $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)

        $RuntimeParameterDictionary
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 2013-02-28
    • 2018-06-27
    相关资源
    最近更新 更多