首页 > 解决方案 > 如何在不破坏 Param 的情况下定义用于 Powershell 中的 Param 定义的类?

问题描述

我正在尝试在 Powershell 中实现动态 validateSet。根据高级功能文档,我应该能够定义一个类,例如:

Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator {
[String[]] GetValidValues() {
    $SoundPaths = '/System/Library/Sounds/',
        '/Library/Sounds','~/Library/Sounds'
    $SoundNames = ForEach ($SoundPath in $SoundPaths) {
        If (Test-Path $SoundPath) {
            (Get-ChildItem $SoundPath).BaseName
        }
    }
    return [String[]] $SoundNames
}

然后在我的 validateSet 中使用它,如下所示:

Param(
  [ValidateSet([SoundNames])]
  [String]$Sound
)
Write-Host $Sound

但是,当我在同一个脚本文件中包含这两个块时,我得到了错误

线 | 5 | Param( | ~~~~~ | 术语“Param”未被识别为 cmdlet、函数、脚本文件或可运行的 | 程序的名称。请检查名称的拼写,或者如果包含路径,请验证路径正确 | 再试一次。

我知道 Param 需要成为脚本中的第一个参数,但是如果我还没有声明该类,我该如何在 Param 定义中使用该类?

我需要在单独的文件中声明该类吗?我将如何在此脚本中包含该课程?

标签: powershell

解决方案


您可以使用动态参数,但它们没有很好的文档记录。这是一个示例脚本:

[CmdletBinding()]
Param()
DynamicParam {
    $ParameterName = 'SoundPath'
    $ValidValueSet = Get-ChildItem -Path . -Directory | Select-Object -ExpandProperty FullName 
    $RuntimeParameterDictionary = New-Object Management.Automation.RuntimeDefinedParameterDictionary
    $RuntimeParameterDictionary.Add($ParameterName, (New-Object Management.Automation.RuntimeDefinedParameter($ParameterName, [string], @( #attributes
            (New-Object Management.Automation.ParameterAttribute -Property @{Mandatory = $true; Position = 1}),
            (New-Object Management.Automation.ValidateSetAttribute($ValidValueSet))
    ))))
    return $RuntimeParameterDictionary
}
begin {
    $MyPath = $PsBoundParameters[$ParameterName] # Bind the parameter to a friendly variable
}
process {# Your code goes here
    Write-Host "Getting directory of $MyPath"
    Get-ChildItem -Path $MyPath 
}

在有子文件夹的文件夹中将其另存为 GetValidSoundPath.ps1,然后 .\GetValidSoundPath.ps1 -在 Powershell 提示符下键入。您会看到它自动填充-SoundPath并提示输入有效的子文件夹。


推荐阅读