Where-Object
Nesta aula, exploramos o cmdlet Where-Object do PowerShell, essencial para filtrar objetos no pipeline. Aprendemos sua sintaxe de bloco e simplificada, como combinar múltiplas condições e vimos exemplos práticos para aplicar em scripts do dia a dia.
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
- Documentação oficial do Where-Object (Microsoft)
- Tudo sobre Where-Object (PowerShell Deep Dive)
- Trabalhando com coleções no PowerShell
- Where-Object no SS64
- Sintaxe do Where-Object (PDQ)
Exercícios
- Escreva um comando que liste todos os serviços que estão com status 'Running' e tipo de inicialização 'Automatic'.
- Usando a sintaxe simplificada, liste todos os processos que estão usando mais de 50 MB de memória (WorkingSet).
- Liste todos os arquivos no diretório C:\Windows\System32 que têm extensão .dll e tamanho maior que 10 MB.
- Encontre todos os processos cujo nome começa com 'sql' (use o operador -like).
- Liste os serviços que estão parados ou com tipo de inicialização manual.
Get-Service | Where-Object { $_.Status -eq 'Running' -and $_.StartType -eq 'Automatic' }
Get-Process | Where-Object WorkingSet -gt 50MB
Get-ChildItem -Path C:\Windows\System32 -Filter *.dll | Where-Object { $_.Length -gt 10MB }
Get-Process | Where-Object { $_.Name -like 'sql*' }
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.