如何对集合本身而非集合元素应用ValidateScript验证?
解决PowerShell中ValidateScript验证集合本身而非元素的问题
当ValidateScript特性应用于实现了IEnumerable接口的类型(如数组)或被[psobject]包装的集合时,PowerShell会默认对集合中的每个元素单独执行验证脚本,而非验证集合对象本身。以下是几种可行的解决方法:
方法1:修改参数类型为[object]
将参数的类型约束从[psobject]改为[object],PowerShell不会自动枚举集合元素,ValidateScript会接收整个集合对象作为验证目标:
function testme { param( [ValidateScript({ $_ -is [array] -or $_ -is [hashtable] }, ErrorMessage = "The item '{0}' did not pass validation of script '{1}'")] [object]$args ) } $arr = [psobject]@("aaa", "bbb") $arr -is [array] # 返回 True testme -args $arr # 验证通过
方法2:通过$PSCmdlet获取原始参数值
如果必须保留[psobject]类型约束,可在验证脚本块中使用$PSCmdlet.GetUnboundParameterValue()获取完整的参数对象,绕过元素枚举:
function testme { param( [ValidateScript({ $originalParam = $PSCmdlet.GetUnboundParameterValue('args') $originalParam -is [array] -or $originalParam -is [hashtable] }, ErrorMessage = "The item '{0}' did not pass validation of script '{1}'")] [psobject]$args ) } $arr = [psobject]@("aaa", "bbb") testme -args $arr # 验证通过
方法3:直接使用类型约束(推荐)
如果仅需验证参数类型为数组或哈希表,无需使用ValidateScript,直接通过类型约束即可实现更简洁的验证:
function testme { param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateScript({ $_ -is [array] -or $_ -is [hashtable] })] [object]$args ) }
原理说明
PowerShell对IEnumerable类型(除字符串外)的参数会自动启用元素级验证,而[psobject]包装的集合会被展开枚举元素。修改参数类型为[object]或通过$PSCmdlet获取原始值,能强制验证逻辑作用于整个集合对象。
内容的提问来源于stack exchange,提问作者Tilman Koester
相关产品推荐
相关产品推荐

