You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell 5.1中使用Measure-Object对自定义对象数组做聚合统计的问题

PowerShell 5.1下按分组统计TimeSpan类型属性的问题与解决方案

所有操作均在Windows PowerShell 5.1环境中执行。


背景

多轮执行的脚本运行过程中会创建文件并统计耗时,结果存储在PSCustomObject类型的数组$ResultsCreate中,数据样例如下:

> $ResultsCreate | Select-Object -First 10 | ft

Run Folder                                 File                                                       Size Create
--- ------                                 ----                                                       ---- ------
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_1.bin   304087,04 00:00:00.1377073
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_2.bin   608174,08 00:00:00.0776793
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_3.bin      524288 00:00:00.0780064
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_4.bin   922746,88 00:00:00.0759425
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_5.bin   503316,48 00:00:00.0842039
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_6.bin   178257,92 00:00:00.0610860
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_7.bin  1038090,24 00:00:00.0916000
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_8.bin   660602,88 00:00:00.0782461
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_9.bin   293601,28 00:00:00.0612056
  1 \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv \\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_10.bin  744488,96 00:00:00.0758247

该PSCustomObject的成员定义如下:

> $ResultsCreate | Get-Member

   TypeName: Selected.System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Create      NoteProperty timespan Create=00:00:00.1377073
File        NoteProperty string File=\\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv\file_1_1.bin
Folder      NoteProperty string Folder=\\opidt660-vxzv\PB-VW_NKB$\Lmneom\vxzv
Run         NoteProperty int Run=1
Size        NoteProperty double Size=304087,04

需求是按Run字段分组,统计每轮下所有文件Create时间字段的平均值、最小值、最大值。


遇到的问题

使用Measure-Object执行统计时始终无法得到预期结果:

错误尝试1:分组后遍历统计

将$ResultsCreate按Run分组为哈希表后遍历计算平均值,最终得到的$stat哈希表仅存在键,对应值为空:

> $($ResultsCreate |
    Group-Object -Property Run -AsHashTable).GetEnumerator() |
    ForEach-Object -Begin {$stat = @{}} -Process { $stat[$_.Key] = $(Measure-Object -Property $_.Value.Duration -Average) }

> $stat

Name                           Value
----                           -----
2
1

问题原因:一是属性名拼写错误,对象的时间属性为Create而非Duration;二是PowerShell 5.1的Measure-Object不支持直接访问嵌套属性。

错误尝试2:直接统计嵌套属性

忽略分组直接调用统计命令,报错提示Property参数为空:

> $ResultsCreate |  Measure-Object -Property $_.Create.TotalSeconds

Measure-Object : Cannot validate argument on parameter 'Property'. The argument is null or empty. Provide an argument that is not null or empty, and th
en try the command again.
At line:1 char:44
+ $ResultsCreate |  Measure-Object -Property $_.Create.TotalSeconds
+                                            ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Measure-Object], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.MeasureObjectCommand

问题原因:Measure-Object的-Property参数要求传入属性名的字符串,此处传入的$_.Create.TotalSeconds中的$_在参数解析阶段没有对应的管道上下文,取值为空导致参数校验失败。


解决方案

核心思路是先通过计算属性将$_.Create.TotalSeconds扩展为独立的顶级列TotalSeconds,再进行分组统计,代码如下:

> $($ResultsCreate |
    select-object -Property *,@{ Name = 'TotalSeconds'; Expression = {  $_.Create.TotalSeconds }} | 
    Group-Object -Property Run -AsHashTable).GetEnumerator() |
    ForEach-Object -Begin {$stat = @{}} -Process { $stat[$_.Key] = $_.Value | Measure-Object -Property TotalSeconds -Average -Minimum -Maximum }

> $stat

Name                           Value                                                                                                                   
----                           -----                                                                                                                   
2                              Microsoft.PowerShell.Commands.GenericMeasureInfo                                                                        
1                              Microsoft.PowerShell.Commands.GenericMeasureInfo                                                                        

补充说明:

PowerShell 6之前的版本中,Measure-Object对哈希表输入的支持存在缺陷,从PowerShell 6开始,Measure-Object才支持对哈希表输入执行统计操作。


内容的提问来源于stack exchange,提问作者DocZerø

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:24:07