Where-Object

Filtruje obiekty z potoku według warunku.

Where-Object to sitko potoku w PowerShellu. Bierze obiekty, które lecą do niego przez pipe (|), sprawdza każdy pod kątem warunku i przepuszcza dalej tylko te, które go spełniają. Reszta wypada. To odpowiednik grep ze świata Uniksa, tyle że filtrujesz nie tekst, a właściwości obiektów — zamiast dłubać w stringach patrzysz wprost na $_.Status czy $_.Length. Masz listę procesów, plików albo usług i chcesz zostawić tylko te pasujące — Where-Object jest do tego.

Składnia i najważniejsze opcje

Klasyczna forma to blok skryptu ze zmienną $_ (bieżący obiekt):

| Where-Object { $_.Wlasciwosc -operator wartosc }

Od PowerShell 3.0 działa też forma uproszczona, bez klamer:

| Where-Object Wlasciwosc -operator wartosc

  • -FilterScript — blok skryptu z warunkiem (domyślny, nazwy zwykle się nie pisze). Tu używasz $_.
  • -Property — nazwa właściwości w składni uproszczonej.
  • -Value — wartość, z którą porównujesz w składni uproszczonej.
  • -eq / -ne — równe / różne. Uwaga: domyślnie nie rozróżnia wielkości liter.
  • -gt / -ge / -lt / -le — większe / większe lub równe / mniejsze / mniejsze lub równe.
  • -like — dopasowanie z wildcardami (*, ?).
  • -match — dopasowanie wyrażeniem regularnym.
  • -contains / -in — sprawdza, czy kolekcja zawiera element / czy element jest w kolekcji.

Przykłady użycia

Get-Process | Where-Object { $_.CPU -gt 100 } — pokazuje procesy, które zużyły ponad 100 sekund czasu procesora.

Get-Service | Where-Object Status -eq 'Running' — składnia uproszczona: same działające usługi.

Get-ChildItem | Where-Object { $_.Length -gt 1MB -and $_.Extension -eq '.log' } — pliki logów większe niż 1 MB (-and działa tylko w bloku).

Get-ChildItem | Where-Object Name -like '*.tmp' — wszystkie pliki i katalogi z rozszerzeniem .tmp.

Get-Process | Where-Object { $_.Name -match '^chrome' } — procesy, których nazwa zaczyna się od „chrome” (regex).

Częste błędy i pułapki

Najczęstsza wpadka to używanie = zamiast -eq. W PowerShellu = to przypisanie, a porównanie robisz operatorem z myślnikiem — = w warunku nie zadziała tak, jak myślisz.

Uwaga na $_ w składni uproszczonej. Forma bez klamer sama podstawia bieżący obiekt, więc pisanie tam $_.Name to błąd — używasz gołej nazwy właściwości (Name). $_ stawiasz tylko w bloku { }.

Operatory logiczne tylko w bloku skryptu. -and, -or i -not działają wyłącznie w formie z klamrami. Chcesz łączyć dwa warunki — wróć do { }.

Wielkość liter. Domyślnie porównania ją ignorują. Gdy naprawdę zależy Ci na rozróżnieniu, użyj wariantów z c, np. -ceq albo -clike.

I jeszcze wydajność: Where-Object filtruje po pobraniu wszystkich obiektów, więc na dużych zbiorach bywa wolny. Jeśli źródło ma własny parametr -Filter (np. Get-ChildItem, Get-ADUser), filtruj u źródła.

Powiązane komendy: Select-Object (wybór właściwości), ForEach-Object (działanie na każdym obiekcie), Sort-Object, Group-Object, Select-String (odpowiednik grep dla tekstu).