Chcesz szybko porównać pliki, foldery (ich liczbę oraz zawartość), usługi czy właściwości obiektów? Dobrym rozwiązaniem, będzie zaprzyjaźnienie się bliżej z Compare-Object w PowerShell.
Do przeprowadzenia tych ćwiczeń potrzebny będzie PowerShell w wersji min. 5.1, aby sprawdzić obecną wersję wystarczy w konsoli PowerShell wydać jedno z dwóch poleceń:
- $PSVersionTable.PSVersion
- Get-Host
Porównanie zawartości plików
Wyobraź sobie, że przechowujesz dwa różne pliki o tej samej zawartości. Skąd możesz wiedzieć, czy oba pliki zachowują tę samą zawartość? Rozwiązaniem może być uruchomienie polecenia Get-Content. Polecenie Get-Content pobiera zawartość pliku z określonej lokalizacji.
Otwórz PowerShell i uruchom poniższe polecenia, aby pobrać zawartość (Get-Content) określonych plików do zmiennych ($file1 i $file2). Zastąp poniższą ścieżkę własną prowadzącą do właściwych plików, które chcesz porównać.
1 2 |
$file1 = Get-Content C:\Test1\File1.txt $file2 = Get-Content C:\Test2\File2.txt |
Teraz uruchom poniższe polecenie Compare-Object, aby porównać zawartość $file1 (-ReferenceObject) z $file2 (-DifferenceObject).
1 2 |
$compare1 = Compare-Object -ReferenceObject $file1 -DifferenceObject $file2 -IncludeEqual echo $compare1 |
W celu wyświetlenia wyników porównania zawartości plików należy wywołać w konsoli PowerShell echo $compare1.
Z poniższych danych wyjściowych SideIndicator informuje, czy oba pliki mają tę samą zawartość (w wierszu), czy nie, poniżej opis możliwych oznaczeń, które wskazują na to, który z plików (prawy czy lewy) ma określoną wartość w wierszu:
- == wskazuje, że zawartość jest obecna w obu plikach ($file1 i $file2).
- => wskazuje, że zawartość istnieje tylko w pliku -DifferenceObject ($file2).
- <= wskazuje, że zawartość istnieje tylko w pliku -ReferenceObject ($file1).
Być może wolisz porównywać ciągi z uwzględnieniem wielkości liter. Jeśli tak, dołącz parametr -CaseSensitive, ponieważ w poleceniu Compare-Object domyślnie nie jest rozróżniana wielkość liter.
Uruchom poniższe polecenia, aby porównać $file1 z $file2, zarówno z rozróżnianiem wielkości liter, jak i bez. W plikach dodałem odpowiednio: Jeden, Dwa oraz jeden, Dwa.
1 2 |
$compare1 = Compare-Object $file1 $file2 -CaseSensitive echo $compare1 |
Zapewne zastanwiasz się z jakiego powodu nie pojawiło się porównanie Dwa == Dwa? Otóż domyślnie wartości równe (w tym przypadku identyczne) są pomijane, ponieważ nie został dodany parametr -IncludeEqual (jak w poprzednim przykładzie).
Porównywanie ciągów znaków również działa podobnie do porównywania zawartości pliku, w którym można określić ciągi lub użyć zmiennych do reprezentacji ciągów do porównania. Należy pamiętać, że polecenie Compare-Object porównuje łańcuchy źródłowe, a nie znaki.
Porównanie listy plików z różnych lokalizacji
Teraz, gdy wiesz, jak porównywać zawartość plików, dlaczego nie porównać rzeczywistych plików z różnych lokalizacji? Porównanie list plików przydaje się, gdy zarządzasz dwoma różnymi serwerami, na których przechowujesz ten sam folder dla usługi zawierającej te same pliki.
Tym razem użyj polecenia Get-ChildItem, aby uzyskać listę plików w folderze w celu porównania z listą plików w innym folderze.
Uruchom poniższe polecenia, aby pobrać listy plików z folderów C:\Test1\ i C:\Test2\ i zapisz listy plików w zmiennych $FolderList1 i $FolderList2.
1 2 3 4 |
$FolderList1 = Get-ChildItem C:\Test1\ $FolderList2 = Get-ChildItem C:\Test2\ $compare2 = Compare-Object $FolderList1 $FolderList2 -IncludeEqual echo $compare2 |
Możesz także użyć parametru -Recurse w poleceniu Get-Childitem (dodaj go na końcu tego polecenia), aby rekurencyjnie pobrać listę plików w podfolderach.
Porównanie właściowości obiektów w PowerShell
Właśnie porównałeś pliki w różnych lokalizacjach, ale możesz chcieć dodać kolejną opcję porównywania plików według właściwości. W tym przykładzie porównasz pliki według czasu ostatniego dostępu.
Uruchom następujące polecenia, aby porównać pliki z różnych folderów ($Folder1 i $Folder2) według czasu ostatniego dostępu.
1 2 3 4 |
$Folder1 = Get-ChildItem C:\Test1\ -Recurse $Folder2 = Get-ChildItem C:\Test2\ -Recurse $compare3 = Compare-Object $Folder1 $Folder2 -Property name,lastaccesstime echo $compare3 |
W wyniku tego polecenia otrzymasz nazwę pliku, czas ostatniego dostępu oraz jak zawsze miejsce występowania (Folder1 lub Folder2).
Porównanie usług i procesów
Możliwości polecenia Compare-Object nie ograniczają się tylko do porównywania ciągów znaków lub zawartości plików. Możesz także porównywać procesy, usługi i tak dalej.
Być może chcesz przechwytywać usługi między dwoma serwerami. Jeśli tak, możesz przechowywać usługi w zmiennych i porównywać usługi.
Dla ułatwienia takich działań należy wyłączyć firewall oraz z poziomu PowerShell uruchomić polecenie: Enable-PSRemoting. Dzięki temu możliwy będzie zdalny dostęp do maszyny.
Uruchom następujące polecenia, aby porównać usługi między dwoma różnymi serwerami ($server1 i $server2).
1 |
$server1 = Get-Service -ComputerName ClientW10GPO<br>$server2 = Get-Service -ComputerName DC2019GPO<br>$compare4 = Compare-Object $server1 $server2 -PassThru | sort name| select name,status,machinename<br>echo $compare4 |
Do zmiennych $server1 oraz $server2 zostaną przekierowane listy zawierające usługi z dwóch różnych maszyn (zdalnych, lokalnych). Parametr -PassThru pozwoli na wyświetlenie zwróconych usług z obydwu maszyn, które zostały przekazane jako parametry. Do tego usługi zostaną posortowane po nazwie (sort name), na koniec polecenie pokaże jedynie 3 kolumny: name, status,machinename. Zarówno sort jak i select wywoływane są przy pomocy potoku (pipeline), którego symbolem jest „|”.
Podobnie możliwe jest porównanie działających procesów w systemie. W tym celu użyj polecenia Get-Process. Dodatkowo sideindicator, pozwoli wyswietlić z ktorej maszyny pochodza procesy.
1 2 3 4 |
$server1 = Get-Process -ComputerName ClientW10GPO $server2 = Get-Process -ComputerName DC2019GPO $compare4 = Compare-Object $server1 $server2 -PassThru | sort name | processname,machinename,sideindicator echo $compare4 |
Porównanie list procesów
Polecenie cmdlet Compare-Object jest również pomocne w niektórych scenariuszach rozwiązywania problemów. Jak? Możesz przechwycić aktualnie uruchomione procesy do zmiennej. Następnie przechwytujesz działające procesy do nowej zmiennej i porównujesz nowe procesy.
1 |
$Old_Process = Get-Process<br>notepad<br>$New_Process = Get-Process<br>Compare-Object $Old_Process $New_Process -PassThru | select processname,sideindicator |
Porównanie użytkowników między różnymi grupami Active Directory
Jeśli zarządzasz tym samym zestawem użytkowników z różnych grup AD, przydatne będzie porównanie listy użytkowników za pomocą polecenia Compare-Object. Dzięki temu możesz uważnie obserwować, czy brakuje użytkownika w jednej z dwóch różnych grup AD.
Uruchom poniższe polecenia, aby porównać użytkowników między dwiema różnymi grupami AD (Group1 i Group2). Do każdej z grupy został dodane testowy użytkownik odpowiednio user1 oraz user2.
1 |
Import-Module ActiveDirectory<br>$FirstGroup = Get-ADGroup Group1 -Properties Member |Select-Object -ExpandProperty Member | Get-ADUser<br>$SecondGroup = Get-ADGroup Group2 -Properties Member |Select-Object -ExpandProperty Member | Get-ADUser<br>Compare-Object ($FirstGroup) ($SecondGroup) -Property 'SamAccountName' -IncludeEqual |
Podsumowanie
W tymwpisie nauczyłeś się, jak porównywać obiekty z PowerShell na wiele sposobów, od zawartości plików po użytkowników w grupach AD. Compare-Object to szybkie rozwiązanie do porównywania plików, usług, procesów etc.
Dziękuję Ci, za poświęcony czas na przeczytanie tego artykułu. Jeśli był on dla Ciebie przydatny, to gorąco zachęcam Cię do zapisania się na mój newsletter, jeżeli jeszcze Cię tam nie ma. Proszę Cię także o “polubienie” mojego bloga na Facebooku oraz kanału na YouTube – pomoże mi to dotrzeć do nowych odbiorców. Raz w tygodniu (niedziela punkt 17.00) otrzymasz powiadomienia o nowych artykułach / projektach zanim staną się publiczne. Możesz również pozostawić całkowicie anonimowy pomysł na wpis/nagranie.
Link do formularza tutaj: https://beitadmin.pl/pomysly
Pozostaw również komentarz lub napisz do mnie wiadomość odpisuję na każdą, jeżeli Masz jakieś pytania:).