用'label'重命名标题,我想过滤最后一个'SpaceLeft'。但是它不能正常工作。例如:
Get-WmiObject win32_logicaldisk -ComputerName sfuslt167 -Filter "drivetype=3" |
Format-Table -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}
结果:
deviceID freespace(GB) Size(GB) SpaceLeft
-------- ------------- -------- ---------
C: 130 237 54.8893461475826
这应该什么都不会返回,因为'SpaceLeft'中的值大于WHERE语句中指定的10,但是返回结果。为什么会这样?
答案 0 :(得分:1)
Lee Dailey在评论中提供了关键指针:
要转换数据以进行进一步的编程处理,请使用Select-Object
或其他数据转换方法,例如通过ForEach-Object
。
仅使用Format-*
cmdlet来按其名称所示,格式化数据以显示 。 >
Format-Table
之类的Format-*
cmdlet也会发出对象,这些对象不再表示数据,而是表示PowerShell's output-formatting system的格式化说明-它们没有其他用途。因此,只需将Format-Table
替换为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的共同点在于,可以接受基于哈希表的calculated properties(@{ label = '...'; expression = { ... } }
),就像您的问题一样。
关于您尝试中的实际发生的情况:
这是一个简化的示例,使用Format-Table
:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Format-Table @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}}
SpaceLeft
---------
10
这个看起来很好-的确是这样做的目的-产生一个很好的 display 表示形式。
实际上,用Select-Object
代替Format-Table
会得到相同的显示:
PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{ label='SpaceLeft'; expression={$_.freespace / $_.size * 100} }
SpaceLeft
---------
10
原因是当命令输出转到 display 时, PowerShell 隐式地在幕后调用适当的 {{ 1}} cmdlet ,在这种情况下为Format-*
。
换句话说,上面的命令等效于以下命令:
Format-Table
有关在何时选择PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-Table
SpaceLeft
---------
10
cmdlet的后面的逻辑,请参阅this answer。
但是,您可以选择(格式化)cmdlet,例如Format-*
,而不是(隐式地)应用Format-Table
,以列表样式显示在每个行上的每个属性:>
Format-List
但是,在进行进一步处理时, 不是PS> [pscustomobject] @{ freespace = 100; size = 1000 } |
Select-Object @{label='SpaceLeft'; expression={$_.freespace / $_.size * 100}} |
Format-List
SpaceLeft : 10
和Select-Object
创建的,因此仅Format-Table
是合适的:
首先使用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
而不是Format-Table
讲述了一个不同的故事:
Select-Object
这些部分隐晦地命名的属性具体代表什么并不重要-重要的是:
它们的唯一目的是由PowerShell的输出格式系统解释。
传递给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-Table
调用无法按预期进行的原因:Where-Object
引用了一个不存在的属性,因此该表达式的值为$_.SpaceLeft
,而$null
为< em>总是 $null -lt 10
。 $true
cmdlet输出Microsoft.PowerShell.Commands.Internal.Format.*
类型的实例,它们代表格式化指令。