Select-Object表达式导致PSCustomObject属性类型显示异常的咨询
PowerShell Select-Object计算属性的类型显示问题解答
1. 为何计算属性会显示System.String而非string?
这是PowerShell处理属性元数据的机制差异导致的:
- 通过
[pscustomobject]@{...}创建的对象,其NoteProperty属性会被PowerShell自动关联PowerShell类型别名(如string对应.NET的System.String),因此Get-Member输出的Definition会显示简化的别名。 - 使用
Select-Object的计算属性时,Select-Object会基于表达式返回的.NET对象直接创建新的NoteProperty,此时它会使用.NET类型的完整名称记录属性类型,不会自动映射PowerShell的别名,所以Get-Member显示System.String。
而ConvertTo-Json | ConvertFrom-Json或Add-Member能恢复string显示的原因:
- JSON转换过程会丢失原有的.NET类型元数据,重建后的PSCustomObject属性会重新应用PowerShell的类型别名规则。
- 直接给原生PSCustomObject用
Add-Member添加属性时,PowerShell同样会自动处理类型别名映射,因此显示为string。
2. 能否让计算属性生成显示为string的类型?
可以,以下两种方法能满足需求:
方法1:直接构造PSCustomObject
绕过Select-Object的计算属性,用[pscustomobject]直接构建新对象,让PowerShell自动处理类型别名:
$WhatHappensToText = [pscustomobject]@{ Text = $object.Text } $WhatHappensToText | Get-Member # 输出中Text的Definition为`string Text=This is a string`
方法2:JSON转换修复元数据
如果需要批量处理多个属性,先通过Select-Object生成对象,再用JSON转换重建属性元数据:
$WhatHappensToText = $object | Select-Object @{Name='Text'; Expression={$_.Text}} | ConvertTo-Json | ConvertFrom-Json $WhatHappensToText | Get-Member # 同样会显示`string Text=This is a string`
注意:两种方式的属性实际类型都是
System.String,差异仅在于Get-Member的显示名称。如果你的工作流依赖于Definition字段的格式,上述方法可以解决问题。
内容的提问来源于stack exchange,提问作者Axel Andersen
相关产品推荐
相关产品推荐

