Ответ 1
Не похоже, что синтаксис командлета Group-Object был изменен, так как ниже показано то же определение (вместе с DLL, где определяется метод) для обеих версий:
gcm Group-Object | fl DLL,Definition
DLL : C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.PowerShell.Commands.Utility\v4.0_
3.0.0.0__31bf3856ad364e35\Microsoft.PowerShell.Commands.Utility.dll
Definition :
Group-Object [[-Property] <Object[]>] [-NoElement] [-AsHashTable] [-AsString]
[-InputObject <psobject>] [-Culture <string>] [-CaseSensitive] [<CommonParameters>]
Но поскольку PetSerAL упоминается в комментарии, похоже, что 5.0 DLL обрабатывает массивы по-разному, чем 4.0. Например:
$a=[PSCustomObject]@{[email protected](1,2)} #Object with an array for the value of the item property
$b=[PSCustomObject]@{[email protected](3,3)} #Object with a different array for the value of the item property
$a.item.Equals($b.item) #This deep compare is false, as the two objects are not equal
$a.item.GetType().Equals($b.item.GetType()) #This "shallow" compare is true because both are the array type.
$c=[PSCustomObject]@{[email protected]{key='value'}} #Similar but this time the item value is a hashtable
$d=[PSCustomObject]@{[email protected]{anotherkey='anothervalue'}} #again comparing the two items we expect the result to be false if deep compared but true if shallow compared
$e=[PSCustomObject]@{item=get-date} #another test using two datetimes (another common "reference" type)
$f=[PSCustomObject]@{item=[datetime]::MinValue}
$a,$b,$c,$d,$e,$f | group -Property item #now we see what happens when using group-object
#Output in PowerShell 4.0
Count Name Group
----- ---- -----
1 {1, 2} {@{item=System.Object[]}}
1 {3, 3} {@{item=System.Object[]}}
2 {System.Collections.Di... {@{item=System.Collections.Hashtable}, @{item=System.Collections...
1 8/5/2016 9:45:36 PM {@{item=8/5/2016 9:45:36 PM}}
1 1/1/0001 12:00:00 AM {@{item=1/1/0001 12:00:00 AM}}
#Output in PowerShell 5.0
Count Name Group
----- ---- -----
2 {1, 2} {@{item=System.Object[]}, @{item=System.Object[]}}
2 {System.Collections.Di... {@{item=System.Collections.Hashtable}, @{item=System.Collections...
1 8/5/2016 9:45:40 PM {@{item=8/5/2016 9:45:40 PM}}
1 1/1/0001 12:00:00 AM {@{item=1/1/0001 12:00:00 AM}}
Обратите внимание, что в версии 4 значения массива обрабатывались как отдельные группы, но хэш-таблицы рассматриваются как равные группы. Это означает, что массивы имели глубокое сравнение, но hashtables были неглубоким сравнением (все хэш-таблицы рассматриваются как эквивалентные)
Теперь в версии 5 массивы рассматриваются как эквивалентные, что означает, что они являются неглубоким сравнением, аналогичным тому, как работали hashtables.
Если вы хотите просмотреть полную информацию, вам нужно будет использовать ilspy или .Net Reflector для демонстрации DLL и сравнить метод DoGrouping класса Microsoft.PowerShell.Commands.GroupObjectCommand. Трудно сказать, является ли это ошибкой или нет, но это определенно является изменением для командлета group-object.
Обновление: Чем больше я играю с этим, тем больше я думаю, что новый код верен (за исключением того, что отображаемое имя должно быть просто System.Object), и была ошибка в старом коде. Похоже, что v4 выполнял какое-то сравнение на основе строк, так как даже два разных массива с одинаковыми элементами были бы сгруппированы вместе, хотя $a.Equals([PSCustomObject]@{[email protected](1,2)})
всегда false (результаты метода GetHashCode не совпадают). Единственный способ, которым я мог получить 5.0 для группировки подобных массивов, - это использовать group -Property {$_.item -join ','}
, который соответствовал выходному сигналу 4.0, за исключением того, что имя было тогда 1,2 вместо {1, 2}. Кроме того, если вы хотите сгруппировать, используя ключ элемента хэш-таблицы, вы должны использовать group -Property {$_.item.somekey}
(при условии, что все они имеют значение для некоторой клавиши)