*UPDATED
bardzo często korzystam z 'compare-object’ ale ma niestety jedną bardzo, bardzo poważną skazę. pomimo swojej nazwy, wcale nie potrafi porównywać obiektów, a raczej wykrywać różne obiekty w tablicy. oto przykład:
PS C:\Temp> $t1=Get-Process -Name explorer PS C:\Temp> $t2=Get-Process -Name explorer PS C:\Temp> $t1 Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 1264 115 76272 76816 694,25 15372 4 explorer PS C:\Temp> $t2 Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName ------- ------ ----- ----- ------ -- -- ----------- 1264 115 76348 76832 694,25 15372 4 explorer PS C:\Temp> compare $t1 $t2 PS C:\Temp>
$t1 i $t2 są takimi samymi obiektami, różnią się niektórymi wartościami atrybutów – np. Paged Memory [PM(K)]. compare różnicy nie widzi. oczywiście można porównać konkretne atrybuty [properties]:
PS C:\Temp> compare $t1 $t2 -Property PagedMemorySize PagedMemorySize SideIndicator --------------- ------------- 78180352 => 78102528 <=
ale kiedy poda się kilka parametrów, to compare-object traktuje je jako logiczny OR –
„czy którykolwiek z nich się różni?”:
PS C:\Temp> compare $t1 $t2 -Property PagedMemorySize,Name PagedMemorySize Name SideIndicator --------------- ---- ------------- 78180352 explorer => 78102528 explorer <=
moje odczucie jest takie, że compare-object został napisany z myślą o tabelach, gdzie dla kolejnych wierszy pokazuje różnice w kolumnach. w przypadq obiektów jest odwrotnie – każdy wiersz jest unikalny i ma wartość. więc albo trzeba byłoby skonwertować to do tablicy i dokonać transpozycji, albo obejść się bez compare-object /: jak się okazuje nawet PowerShell ma wady i nie jest idealny. ten przypadek jest szczególnie bolesny i niezrozumiały, zarówno ze względu na obiektowość PS, jak i zwodniczą nazwę.
jeden ze scenariuszy: szukałem różnic w wartości obiektów po migracji między usługami, żeby wykryć, gdzie była zmiana. dla ułatwienia zrobiłem sobie zrzut obiektu do CSV [ale to nie ma znaczenia]. efekt był dokładnie taki jak opisywany powyżej, czyli nie pokazywał mi różnic. i trzeba było sobie to ręcznie oprogramować:
$t1.Psobject.Properties|%{ if($_.value -ne $t2.$($_.name)) { write-host "$($_.name)-> $($_.value); $($t2.$($_.name)) " } }
PS szybko rozleniwia /:
/UPDATE
okazuje się, że Tatuśkowi też zabrakło takiej funkcjonalności więc napisał piękną funkcję do jej obsługi: Compare-ObjectProperty.
dzięki Kacper za linka (:
eN.