李戴利在评论中提供了关键指针:
-
To 转换数据为进一步的程序化处理, use Select-Object或其他数据转换方法,例如通过ForEach-Object.
-
只曾经使用过Format-*
cmdlet 至format data 用于展示,正如他们的名字所暗示的。
- PowerShell 的伟大进化飞跃是发送objects而不是text通过管道,同时
Format-*
cmdlet 例如Format-Table也会发出对象,这些对象不再代表data, but 格式说明 for PowerShell 的输出格式化系统- 它们没有其他目的。
因此,只需更换Format-Table
with Select-Object
解决你的问题:
Get-WmiObject win32_logicaldisk -ComputerName sfuslt167 -Filter "drivetype=3" |
Select-Object -Property deviceID,
@{label='freespace(GB)';expression={$_.freespace / 1GB -as [int]}},
@{label='Size(GB)';expression={$_.size / 1GB -as [int]}},
@{label='SpaceLeft';expression={$_.freespace / $_.size * 100}} |
Where-Object {$_.SpaceLeft -lt 10}
然而,这两个 cmdlet 的共同点是能够接受基于哈希表的计算属性 (@{ label = '...'; expression = { ... } }
),就像你的问题一样。
As for 到底发生了什么在你的尝试中:
这是一个简化的示例,使用Format-Table
:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Format-Table @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}}
SpaceLeft
---------
10
This looks很好——事实上这就是目的——制作一个好的display表示。
事实上,替代Select-Object
for Format-Table
结果相同display:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{ label='SpaceLeft'; expression={$_.freespace / $_.size * 100} }
SpaceLeft
---------
10
原因是当命令输出到达display, 电源外壳隐秘地,在幕后打电话给合适的 Format-*
cmdlet,在本例中是Format-Table
。
换句话说,上面的命令相当于下面的命令:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-Table
SpaceLeft
---------
10
For the 背后的逻辑which Format-*
选择了 cmdletwhen, see 这个答案.
然而,而不是(隐式)应用Format-Table
,您可以选择不同的格式化 cmdlet,例如Format-List
对于列表样式显示,在其自己的行上显示每个属性:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-List
SpaceLeft : 10
然而,当谈到进一步处理, Select-Object
and Format-Table
are not只创造平等Select-Object
适合:
让我们看看输出对象拥有哪些属性,使用Get-Member -Type Properties
,首先与Select-Object
:
PS> ([pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Get-Member -Type Properties).Name
SpaceLeft
正如预期的那样,输出有一个属性,名为SpaceLeft
,这就是你的Where-Object
调用即可操作。
Using Format-Table
代替Select-Object
讲述了一个不同的故事:
PS> ([pscustomobject] @{ freespace = 100; size = 1000 } |
Format-Table @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Get-Member -Type Properties).Name
autosizeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
pageFooterEntry
pageHeaderEntry
shapeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
shapeInfo
ClassId2e4f51ef21dd47e99d3c952918aff9cd
formatEntryInfo
outOfBand
writeStream
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
ClassId2e4f51ef21dd47e99d3c952918aff9cd
groupingEntry
这些部分模糊命名的属性具体代表什么并不重要 - 重要的是:
无论他们的输入如何,Format-*
cmdlet 输出实例Microsoft.PowerShell.Commands.Internal.Format.*代表的类型格式说明.