【问题标题】:PowerShell Param ValidateSet values with Spaces and Tab completion带有空格和制表符完成的 PowerShell 参数 ValidateSet 值
【发布时间】:2015-08-18 10:20:08
【问题描述】:

首先,对于发布有关 PowerShell 和选项卡补全的另一个问题,我深表歉意。 StackOverflow 系统确定了几个与这个主题相关的优秀问题的答案,但它们似乎都太麻烦了,无法在这个简单的New-ADComputer 脚本中实现。

参数将进入Splat 以保持脚本可读。以下代码在 ISE 中正确完成制表符,但必须用双引号括起来。

PowerShell 中是否有任何本机方法允许包含空格的参数集的制表符完成?

Param(
  [Parameter(Mandatory=$true)]
  [string]$Server,
  [Parameter(Mandatory=$true)]
  [ValidateSet('Env1','Env 2','Env 3')]
  [string]$Environment,
  [Parameter(Mandatory=$true)]
  [ValidateSet('Application','Database','File and Print','Web Server')]
  [string]$Type
)
$NewADitems = @{
  Name        = $server
  Path        = "OU=$Type,OU=$Environment,OU=Smaller DN string"
  Location    ='MySite'
  Description = "Test Description"
  ManagedBy   = "Huge Distingushed Name string"
  WhatIf      = $true
}
Write-Host @NewADitems

使用的命令和收到的错误:

PS C:\Scripts> .\ADComputer-ParamTest.ps1 -Server ThisTest -Environment Env 3 -Type File and Print
C:\Scripts\ADComputer-ParamTest.ps1 : Cannot validate argument on parameter
'Environment'. The argument "Env" does not belong to the set "Env1,Env 2,Env3"
specified by the ValidateSet attribute. Supply an argument that is in the
set and then try the command again.At line:1 char:58
+ .\ADComputer-ParamTest.ps1 -Server ThisTest -Environment Env 3 -Type File and Pr ...
+                                                          ~~~

编辑:更多信息。如果您在我的示例脚本中为参数Environment 省略单引号/双引号,则制表符补全将不适用于最终参数Type。将第二组用引号括起来可以纠正这种情况,但这是一种密切注意这种行为的方法。

【问题讨论】:

  • 引用要求非常严格,可能与制表符补全问题最相关。我可以建议将此问题的范围限制为选项卡完成吗?我认为保持隔离已经足够不同了。它向我展示了关于带有空格的制表符完成的新事物,我认为这是不可能的。将 New-ADComputer splatting 问题分解为一个单独的问题可能会带来更多的观点/答案。
  • P.S.包含指向此原始问题的链接以显示相关代码和已完成的故障排除可能会有所帮助。我很想看到这个问题得到了解决问题的可靠答案。
  • 公平点,我为 New-ADComputer 所做的每一次搜索和喷溅都会在这里结束!!!我猜这个脚本需要两个函数,第一个启动选项卡完成字符串,然后传递给带有开关参数的第二个函数,该参数将允许一个空间然后执行工作。

标签: powershell active-directory


【解决方案1】:

不,至少到 Powershell 5.0 2015 年 4 月预览版为止。选项卡完成按您的描述工作。它仍然需要集合周围的引号才能实际工作而不会引发错误。对于它的价值,当您使用引号开始制表符完成时,它确实添加了匹配类型的结束引号。例如,按“f then Tab”将完成“文件和打印”(不确定何时将其添加为功能)。

我尝试寻找将引号自动包含在 ValidateSet 中的方法,包括参数集周围的额外双引号以及其他转义引号的尝试。所有尝试都导致选项卡完成无法以各种方式工作。

一些尝试,以防有人可能会尝试该途径:

[ValidateSet('Env1','"Env 2"','"Env 3"')]
[ValidateSet('Env1',"'Env 2'","'Env 3'")]
[ValidateSet('Env1','`"Env 2`"',"`'Env 3`'")]
[ValidateSet('Env1','\"Env 2\"',"\'Env 3\'")]

【讨论】:

  • 也遇到了这个问题,将集合括在双引号和单引号中会导致字符串在制表符完成后被引用,但仍然会导致奇怪的问题。我还注意到 Powershell 开发人员提供了一些附加组件,但我的目标是让这个脚本尽可能简单。
  • 我遇到了这个,stackoverflow.com/questions/22129621/…,还没有时间尝试使用它,但它可能会有所帮助
【解决方案2】:

这是自 2013 年以来作为错误输入的。根据Auto-completed parameter values, with spaces, do not have quotes around them 中列出的解决方法,您可以更新 Powershell 用于自动完成的TabExpansion2 函数。为此,只需运行以下代码:

function TabExpansion2
{
    [CmdletBinding(DefaultParameterSetName = 'ScriptInputSet')]
    Param(
        [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 0)]
        [string] $inputScript,

        [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 1)]
        [int] $cursorColumn,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 0)]
        [System.Management.Automation.Language.Ast] $ast,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 1)]
        [System.Management.Automation.Language.Token[]] $tokens,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 2)]
        [System.Management.Automation.Language.IScriptPosition] $positionOfCursor,

        [Parameter(ParameterSetName = 'ScriptInputSet', Position = 2)]
        [Parameter(ParameterSetName = 'AstInputSet', Position = 3)]
        [Hashtable] $options = $null
    )

    End
    {
        if ($psCmdlet.ParameterSetName -eq 'ScriptInputSet')
        {
            $completion = [System.Management.Automation.CommandCompletion]::CompleteInput(
                $inputScript,
                $cursorColumn,
                $options)
        }
        else
        {
            $completion = [System.Management.Automation.CommandCompletion]::CompleteInput(
                $ast,
                $tokens,
                $positionOfCursor,
                $options)
        }

        $count = $completion.CompletionMatches.Count
        for ($i = 0; $i -lt $count; $i++)
        {
            $result = $completion.CompletionMatches[$i]

            if ($result.CompletionText -match '\s')
            {
                $completion.CompletionMatches[$i] = New-Object System.Management.Automation.CompletionResult(
                    "'$($result.CompletionText)'",
                    $result.ListItemText,
                    $result.ResultType,
                    $result.ToolTip
                )
            }
        }

        return $completion
    }
}

值得注意的是,字符串插入对于像 Get-EventLog -LogName 这样的本机 cmdlet 可以正常工作,它可以正确封装 'Internet Explorer'。虽然如果您将look at the source 用于Get-EventLog,您会看到$LogName 实际上并没有使用ValidateSet,因此必须通过另一种机制提供智能感知。


其他实例

【讨论】:

    猜你喜欢
    • 2014-09-28
    • 2021-07-16
    • 2017-06-05
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2018-10-25
    • 1970-01-01
    相关资源
    最近更新 更多