Jeroen Mostert在对该问题的评论中提供了关键的指示:
不幸的是,从 PowerShell 7.0 开始,Measure-Object
总是将其、、和操作的输入数字[1]转换为( )并将结果报告为该类型,这可能会导致精度损失。-Sum
-Maximum
-Minimum
-Average
-StandardDeviation
[double]
System.Double
您的输入数字是 type [long]
,并且它们的值超过了可以在 a 中精确表示的最大整数,[double]
即9007199254740991
(您可以使用 计算它[bigint]::pow(2, 53) - 1
)
一种有效的解决方法是使用 LINQ ( System.Linq.Enumerable.Max
):
[Linq.Enumerable]::Max(
[long[]] $UserDeets.lastLogon
)
请注意,[long[]]
为了使 PowerShell 能够.Max()
使用具体类型调用泛型方法,需要显式转换。
另一种效率较低但更符合 PowerShell 习惯的解决方法是使用排序,类似于OP 自己的答案:
# Sort the LastLogon property values, then grab the *last* one,
# which is the largest value.
($UserDeets.LastLogon | Sort-Object)[-1]
仅对值数组.lastLogon
而不是完整的输入对象进行排序,可以最大限度地减少创建重复的排序数组的概念上不必要的开销,从而达到最大值。值可以确定。
[1] 请注意,for-Min
和-Max
非数字输入也被接受,只要它们实现System.IComparable
接口,在这种情况下,输入保持原样并且不会发生精度损失;例如,'c', 'b', 'a' | Measure-Object -Minimum
并且[datetime]::now, [datetime]::now.AddDays(1) | Measure-Object -Maximum
工作正常,因为类型[string]
和[datetime]
两者都实现IComparable
.