O cmdlet Where-Object é uma das ferramentas mais importantes no PowerShell para filtrar objetos dentro de um pipeline. Ele permite selecionar apenas os itens que atendem a uma ou mais condições, tornando possível processar dados de forma seletiva e eficiente.

Entender o Where-Object é fundamental para manipular coleções, como listas de processos, serviços, arquivos ou qualquer saída de cmdlet. Nesta aula, exploraremos sua sintaxe, tanto a tradicional quanto a simplificada, e veremos como aplicar filtros complexos.

Filtragem

A filtragem com Where-Object funciona avaliando uma condição booleana para cada objeto que passa pelo pipeline. Apenas os objetos para os quais a condição retorna $true são passados adiante. A sintaxe básica é:

Get-Process | Where-Object { $_.CPU -gt 10 }

Nesse exemplo, $_ representa o objeto atual (um processo). A condição verifica se o valor da propriedade CPU é maior que 10. Apenas processos com CPU acima de 10 são exibidos.

Sintaxe de bloco e simplificada

A sintaxe de bloco usa chaves { } e a variável automática $_ para se referir ao objeto corrente. É a forma mais flexível, permitindo qualquer expressão PowerShell. Exemplo:

Get-Service | Where-Object { $_.Status -eq 'Running' }

A partir do PowerShell 3.0, foi introduzida uma sintaxe simplificada que elimina a necessidade das chaves e do $_. Nela, você escreve a propriedade e o operador diretamente. O exemplo anterior fica:

Get-Service | Where-Object Status -eq 'Running'

Essa sintaxe é mais concisa e legível para condições simples. No entanto, para expressões complexas (como usar operadores lógicos ou chamar métodos), a sintaxe de bloco ainda é necessária.

Múltiplas condições

Para filtrar com mais de uma condição, você pode usar operadores lógicos como -and, -or e -not. Na sintaxe de bloco, combine as condições dentro das chaves:

Get-Process | Where-Object { $_.CPU -gt 10 -and $_.Name -like '*chrome*' }

Na sintaxe simplificada, você pode encadear múltiplas condições usando o operador -and (ou -or) após a primeira condição. Contudo, a sintaxe simplificada não suporta agrupamentos complexos; para isso, volte à sintaxe de bloco. Exemplo com sintaxe simplificada (apenas duas condições simples):

Get-Process | Where-Object CPU -gt 10 -and Name -like '*chrome*'

Na prática, para múltiplas condições, a sintaxe de bloco é mais clara e poderosa.

Exemplos

Exemplo 1: Filtrar serviços que estão parados.

Get-Service | Where-Object { $_.Status -eq 'Stopped' }

Exemplo 2: Usando sintaxe simplificada para listar arquivos com mais de 1 MB.

Get-ChildItem -Path C:\Temp | Where-Object Length -gt 1MB

Exemplo 3: Múltiplas condições: processos com mais de 100 MB de memória e que não são do sistema.

Get-Process | Where-Object { $_.WorkingSet -gt 100MB -and $_.Name -notlike 'svchost*' }

Exemplo 4: Uso do operador -contains para filtrar objetos cujo nome está em uma lista.

$nomes = 'notepad', 'calc', 'explorer'
Get-Process | Where-Object { $nomes -contains $_.Name }

Boas práticas: Prefira a sintaxe simplificada para condições simples (uma propriedade e um operador). Use a sintaxe de bloco para expressões que exigem lógica combinada ou chamadas de método. Sempre teste o filtro em um subconjunto pequeno antes de aplicar em produção.

Referências

Exercícios

  1. Crie um comando que liste todos os processos cujo nome contenha "explorer" (use -like).

    ✓ Resposta:
    Get-Process | Where-Object Name -like '*explorer*'
  2. Filtre todos os serviços que estão em estado 'Running' e cujo nome começa com 'W'.

    ✓ Resposta:
    Get-Service | Where-Object { $_.Status -eq 'Running' -and $_.Name -like 'W*' }
  3. Use a sintaxe simplificada para listar arquivos (em C:\) com extensão .txt e tamanho maior que 0 bytes.

    ✓ Resposta:
    Get-ChildItem -Path C:\ -Filter *.txt | Where-Object Length -gt 0
  4. Filtre processos que tenham mais de 50 threads (propriedade Threads é uma coleção; use $_.Threads.Count).

    ✓ Resposta:
    Get-Process | Where-Object { $_.Threads.Count -gt 50 }
  5. Usando uma lista de nomes de serviços ($servicos = 'Spooler', 'WSearch'), filtre apenas os serviços que estão nessa lista.

    ✓ Resposta:
    $servicos = 'Spooler', 'WSearch'
    Get-Service | Where-Object { $servicos -contains $_.Name }