我经常从数据库中获取数据并调整datarow对象的类型名称集合,以反映该行所代表的数据的“类型”。例如,如果我正在查看代表计算机对象的数据行,我可能会在TypeNames集合的末尾添加“MDS__COMPUTER”。我使用New-Object创建的PSObjects做同样的事情。
我过去曾使用PowerShell的扩展类型系统(ETS)来帮助格式化和添加类型级别的成员而不是使用add-member,但我真的希望能够将参数限制为函数和脚本通过指定这些“元类型”作为参数类型。
根据我上面给出的例子,我希望能够做到这一点:
Param([MDS__COMPUTER]$comp)
并让PowerShell检查传入的$ comp对象是否在其TypeNames集合中具有该值。
这有可能吗?我想避免生成真正的C#类并将数据从数据对象(或PSObjects)复制到新对象。
我应该提一下,使用不存在的类型会导致错误。
答案 0 :(得分:2)
您可以在参数声明中使用ValidateScript来检查TypeNames集合是否具有我们正在寻找的TypeName。我就是这样做的:
function MyFunction
{
Param
(
# Parameter that accepts custom TypeName
[Parameter(Mandatory=$false,
Position=0)]
[ValidateScript({$_.PSObject.TypeNames -contains 'MyType'})]
[ValidateNotNullOrEmpty()]
$Comp
)
# YOUR CODE HERE
return $comp
}
答案 1 :(得分:1)
从here开始,以下解决方案似乎有效(不确定需要哪个版本的PowerShell)。将PSTypeName的属性添加到PSCustomObject会导致它被识别为该类型:
$widget = [pscustomobject]@{
PSTypeName = 'Widget'
Color = $null
Size = $null
}
function Get-Something
{
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[PSTypeName('Widget')]$Widget
)
$Widget
}
感谢Kirk Munro和Adam Bertram
事实证明,如果你调整现有对象上的TypeNames()数组(我正在寻找),这可以正常工作:
$x=get-service BITS
$x.PSObject.TypeNames.Insert(0,'Widget')
Get-Something $x