PowerShell中Get-SPWebTemplate数组验证用户输入失效的原因及解决方法
PowerShell中使用Get-SPWebTemplate结果进行-in验证失败的原因及修复方案
你遇到的这个问题我之前也碰到过类似的坑,咱们先把问题场景再理清楚:
原本你用值类型数组@(1,2,3)和用户输入做-in验证是正常的,但换成@(Get-SPWebTemplate | Select-Object Name)之后,明明输入的名称确实存在,却始终返回'not valid'。
问题核心原因
两种数组的元素类型完全不同,这是导致验证失败的关键:
- 最初的
@(1,2,3)是值类型数组,每个元素都是单纯的整数,和用户输入的字符串(PowerShell会自动做隐式类型转换)可以直接比较。 - 而
Get-SPWebTemplate | Select-Object Name返回的是PSObject对象数组——每个元素并不是单纯的字符串,而是一个带有Name属性的对象。当你用用户输入的字符串和这些对象做-in比较时,PowerShell是在判断「这个字符串是否等于整个对象」,显然永远不成立,所以会返回'not valid'。
你可以运行$InputArray | Get-Member验证这一点,输出会显示元素是Selected.Microsoft.SharePoint.PowerShell.SPWebTemplate类型,而非字符串类型。
修复方案
有几种简单的修复方式,根据你的需求选择即可:
方案1:用-ExpandProperty生成纯字符串数组
修改数组生成逻辑,直接提取Name属性的字符串值,得到纯字符串数组:
$InputArray = @(Get-SPWebTemplate | Select-Object -ExpandProperty Name) $UserInput = Read-Host 'Choose your template code' if ($UserInput -in $InputArray) { 'valid' } else { 'not valid' }
-ExpandProperty会把指定属性的值直接展开,而非包装成对象,这样数组元素就是纯字符串,和用户输入的字符串可以正常用-in比较。
方案2:比较时直接引用对象的Name属性
如果需要保留原对象数组(比如后续还要用到其他属性),可以在比较时遍历对象的Name属性集合:
$InputArray = @(Get-SPWebTemplate | Select-Object Name) $UserInput = Read-Host 'Choose your template code' if ($UserInput -in $InputArray.Name) { 'valid' } else { 'not valid' }
这里$InputArray.Name会自动遍历数组中的每个对象,提取它们的Name属性值形成字符串集合,再和用户输入做比较。
方案3:用Where-Object做精准匹配
如果需要更灵活的匹配逻辑(比如忽略大小写),可以用Where-Object查找匹配对象:
$InputArray = @(Get-SPWebTemplate | Select-Object Name) $UserInput = Read-Host 'Choose your template code' if ($InputArray | Where-Object { $_.Name -ieq $UserInput }) { 'valid' } else { 'not valid' }
这种方式可读性更强,把-eq改成-ieq还能实现不区分大小写的匹配。
内容的提问来源于stack exchange,提问作者RJ96
相关产品推荐
相关产品推荐

