O cmdlet ForEach-Object utiliza blocos de script e o descritor $_ do objeto atual no pipeline para permitir que você execute um comando em cada objeto do pipeline. Ele pode ser usado para executar algumas tarefas complicadas.
Uma situação em que seu uso é interessante é na manipulação de dados para que se tornem mais úteis. Por exemplo, a classe Win32_LogicalDisk do WMI pode ser usada para retornar informações sobre espaço livre em cada disco local. Os dados são retornados em bytes, mas dessa forma são difíceis de ler:
PS> Get-WmiObject -Class Win32_LogicalDisk DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 50665070592 Size : 203912880128 VolumeName : Local Disk
Podemos converter o valor de FreeSpace para megabytes dividindo cada valor por 1024 duas vezes; após a primeira divisão, os dados estarão em kilobytes e após a segunda estarão em megabytes. Você pode fazer isso em um bloco de script ForEach-Object digitando:
Get-WmiObject -Class Win32_LogicalDisk | ForEach-Object -Process {($_.FreeSpace)/1024.0/1024.0} 48318.01171875
Infelizmente, a saída agora apresenta dados sem um rótulo associado a eles. Como as propriedades WMI como essa são somente leitura, você não pode converter FreeSpace diretamente. Se você digitar isto:
Get-WmiObject -Class Win32_LogicalDisk | ForEach-Object -Process {$_.FreeSpace = ($_.FreeSpace)/1024.0/1024.0}
Obterá uma mensagem de erro:
"FreeSpace" is a ReadOnly property. At line:1 char:70 + Get-WmiObject -Class Win32_LogicalDisk | ForEach-Object -Process {$_.F <<<< r eeSpace = ($_.FreeSpace)/1024.0/1024.0}
Você pode reorganizar os dados usando algumas técnicas avançadas, mas uma abordagem mais simples para criar um novo objeto, através de Select-Object.