O cmdlet Where-Object é uma das ferramentas mais importantes no PowerShell para filtrar objetos que passam pelo pipeline. Ele permite selecionar apenas os itens que atendem a uma determinada condição, tornando seus scripts mais eficientes e direcionados.

Nesta aula, vamos cobrir desde a sintaxe básica até técnicas avançadas de filtragem, incluindo o uso de múltiplas condições e a sintaxe simplificada introduzida no PowerShell 3.0.

Filtragem

O conceito de filtragem no PowerShell está intimamente ligado ao pipeline. Quando você executa um comando que gera uma coleção de objetos, pode usar Where-Object para selecionar apenas aqueles que satisfazem uma expressão booleana. A saída do cmdlet anterior é passada para Where-Object, que avalia cada objeto e o repassa adiante se a condição for verdadeira.

Por exemplo, para listar apenas os processos com mais de 100 MB de uso de memória:

Get-Process | Where-Object { $_.WorkingSet -gt 100MB }

Aqui, $_ representa o objeto atual no pipeline (cada processo), e WorkingSet é uma propriedade. O operador -gt significa "maior que".

Sintaxe de bloco e simplificada

O Where-Object pode ser usado de duas formas principais: com bloco de script (tradicional) e com sintaxe simplificada (mais concisa).

Sintaxe de bloco: utiliza um bloco de script entre chaves { } e requer o uso de $_ para referenciar o objeto atual. É a forma mais flexível, permitindo lógica complexa.

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

Sintaxe simplificada: introduzida no PowerShell 3.0, dispensa o bloco de script e o $_. Você escreve a propriedade diretamente, seguida do operador e do valor. É mais legível para condições simples.

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

Note que na sintaxe simplificada, o operador é escrito sem o prefixo -? Na verdade, na sintaxe simplificada você ainda usa os operadores de comparação do PowerShell (como -eq, -gt), mas a ordem é: Where-Object Propriedade -operador Valor. Exemplo:

Get-ChildItem | Where-Object Length -gt 1KB

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, é direto:

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

Na sintaxe simplificada, não é possível combinar múltiplas condições diretamente. Você precisaria usar a sintaxe de bloco ou encadear vários Where-Object (o que é menos eficiente).

Outra técnica é usar o operador -match para expressões regulares:

Get-Service | Where-Object { $_.Name -match 'sql' -or $_.DisplayName -match 'sql' }

Exemplos

Vamos ver alguns exemplos práticos do uso de Where-Object.

Exemplo 1: Listar arquivos maiores que 1 MB em um diretório:

Get-ChildItem -Path C:\Temp | Where-Object { $_.Length -gt 1MB }

Exemplo 2: Serviços que estão parados e com tipo de inicialização automática:

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

Exemplo 3: Processos com mais de 100 threads:

Get-Process | Where-Object Threads -gt 100

Exemplo 4: Usar -not para excluir processos com nome "svchost":

Get-Process | Where-Object { $_.Name -ne 'svchost' }

Exemplo 5: Combinar Where-Object com Select-Object para exibir apenas propriedades específicas:

Get-Process | Where-Object CPU -gt 10 | Select-Object Name, CPU, ID

Referências

Exercícios

  1. Escreva um comando que liste todos os serviços que estão com status 'Running' e tipo de inicialização 'Automatic'.
  2. ✓ Resposta:
    Get-Service | Where-Object { $_.Status -eq 'Running' -and $_.StartType -eq 'Automatic' }
  3. Usando a sintaxe simplificada, liste todos os processos que estão usando mais de 50 MB de memória (WorkingSet).
  4. ✓ Resposta:
    Get-Process | Where-Object WorkingSet -gt 50MB
  5. Liste todos os arquivos no diretório C:\Windows\System32 que têm extensão .dll e tamanho maior que 10 MB.
  6. ✓ Resposta:
    Get-ChildItem -Path C:\Windows\System32 -Filter *.dll | Where-Object { $_.Length -gt 10MB }
  7. Encontre todos os processos cujo nome começa com 'sql' (use o operador -like).
  8. ✓ Resposta:
    Get-Process | Where-Object { $_.Name -like 'sql*' }
  9. Liste os serviços que estão parados ou com tipo de inicialização manual.
  10. ✓ Resposta:
    Get-Service | Where-Object { $_.Status -eq 'Stopped' -or $_.StartType -eq 'Manual' }

Boas práticas

Sempre que possível, filtre o mais cedo possível no pipeline para reduzir a quantidade de objetos processados. Use a sintaxe simplificada para condições simples e a de bloco para lógicas mais complexas. Evite encadear múltiplos Where-Object quando uma única condição composta resolver.