Nesta aula, vamos explorar dois dos laços mais importantes no PowerShell: for e foreach. O laço for é ideal quando você precisa controlar explicitamente o número de iterações, enquanto o foreach simplifica a iteração sobre coleções de objetos. Entender essas estruturas é fundamental para escrever scripts eficientes e legíveis.

for

O laço for no PowerShell segue a mesma sintaxe de outras linguagens: for (inicialização; condição; incremento) { bloco de comandos }. Ele é útil quando você precisa iterar um número conhecido de vezes, especialmente quando precisa de um contador.

A inicialização é executada uma vez antes do laço. A condição é testada antes de cada iteração; se for verdadeira, o bloco é executado. Após cada iteração, o incremento é executado. O laço termina quando a condição se torna falsa.

Exemplo: exibir números de 1 a 5.

for ($i = 1; $i -le 5; $i++) {
    Write-Host "Número: $i"
}

Saída:

Número: 1
Número: 2
Número: 3
Número: 4
Número: 5

foreach (statement)

O comando foreach é usado para iterar sobre uma coleção de itens, como uma lista, array ou saída de cmdlet. Sua sintaxe é: foreach ($item in $coleção) { bloco de comandos }. Ele é mais legível que o for quando você não precisa de um contador.

Exemplo: exibir cada elemento de um array.

$frutas = @('Maçã', 'Banana', 'Laranja')
foreach ($fruta in $frutas) {
    Write-Host "Fruta: $fruta"
}

Saída:

Fruta: Maçã
Fruta: Banana
Fruta: Laranja

Diferença para ForEach-Object

ForEach-Object é um cmdlet que processa objetos do pipeline, enquanto foreach é uma instrução de linguagem. A principal diferença é que foreach carrega toda a coleção na memória antes de iterar, enquanto ForEach-Object processa cada objeto conforme ele passa pelo pipeline (streaming), economizando memória para grandes conjuntos de dados.

Exemplo com ForEach-Object:

1..5 | ForEach-Object { Write-Host "Número: $_" }

Saída:

Número: 1
Número: 2
Número: 3
Número: 4
Número: 5

Já o foreach faria:

foreach ($n in 1..5) { Write-Host "Número: $n" }

Para pipelines muito grandes, prefira ForEach-Object para evitar consumo excessivo de memória.

Exemplos

Exemplo 1: Calcular a soma dos números de 1 a 100 com for.

$soma = 0
for ($i = 1; $i -le 100; $i++) {
    $soma += $i
}
Write-Host "Soma: $soma"

Exemplo 2: Listar todos os processos em execução com foreach.

$processos = Get-Process
foreach ($proc in $processos) {
    Write-Host "Processo: $($proc.Name) - PID: $($proc.Id)"
}

Exemplo 3: Usar ForEach-Object para filtrar e exibir apenas processos com mais de 10 MB de memória.

Get-Process | Where-Object { $_.WorkingSet -gt 10MB } | ForEach-Object {
    Write-Host "$($_.Name) está usando $($_.WorkingSet / 1MB) MB"
}

Boas Práticas

  • Use for quando precisar de um contador ou iteração com índice.
  • Use foreach para iterar coleções completas de forma legível.
  • Use ForEach-Object em pipelines para processamento streaming.
  • Evite modificar a coleção dentro de um foreach; isso pode causar erros.
  • Prefira ForEach-Object com -Parallel (PowerShell 7+) para paralelismo.

Referências

Exercícios

  1. Escreva um script que exiba os números pares de 0 a 20 usando o laço for.

    ✓ Resposta:
    for ($i = 0; $i -le 20; $i += 2) {
        Write-Host $i
    }
  2. Dado o array $nomes = @('Ana', 'Beto', 'Carla'), use foreach para exibir cada nome em maiúsculas.

    ✓ Resposta:
    $nomes = @('Ana', 'Beto', 'Carla')
    foreach ($nome in $nomes) {
        Write-Host $nome.ToUpper()
    }
  3. Use ForEach-Object para exibir o nome de cada serviço que está em execução (status Running).

    ✓ Resposta:
    Get-Service | Where-Object { $_.Status -eq 'Running' } | ForEach-Object { $_.Name }
  4. Escreva um laço for que calcule o fatorial de 5 (5!).

    ✓ Resposta:
    $fatorial = 1
    for ($i = 1; $i -le 5; $i++) {
        $fatorial *= $i
    }
    Write-Host "5! = $fatorial"
  5. Converta o seguinte uso de ForEach-Object para um laço foreach:

    1..10 | ForEach-Object { $_ * $_ }

    ✓ Resposta:
    foreach ($n in 1..10) {
        $n * $n
    }