ForEach-Object în PowerShell

Rulează un bloc de cod pentru fiecare obiect din pipeline; din PowerShell 7.0 poate rula blocurile în paralel cu -Parallel.

Sintaxă
ForEach-Object [-Begin <ScriptBlock>] [-Process] <ScriptBlock[]> [-End <ScriptBlock>]
ForEach-Object [-MemberName] <string> [-ArgumentList <Object[]>]
ForEach-Object -Parallel <ScriptBlock> [-ThrottleLimit <int>] [-TimeoutSeconds <int>] [-AsJob]

Ce face ForEach-Object

ForEach-Object (aliasuri foreach și %) execută blocul -Process o dată pentru fiecare obiect primit, cu obiectul curent în $_. Opțional, -Begin rulează o singură dată înainte de primul obiect, iar -End o dată după ultimul, ceea ce e util pentru totaluri. Sintaxa simplificată ForEach-Object ToUpper citește o proprietate sau apelează o metodă (din Windows PowerShell 3.0).

Spre deosebire de instrucțiunea foreach ($x in $lista), cmdlet-ul lucrează în flux: prelucrează fiecare obiect imediat ce vine prin pipeline, fără să aștepte toată colecția.

Din PowerShell 7.0, -Parallel rulează blocul în paralel, în runspace-uri separate, câte -ThrottleLimit o dată (implicit 5). Variabilele din afara blocului se citesc cu $using:nume. Din 7.1 runspace-urile sunt refolosite (-UseNewRunspace creează unul nou la fiecare iterație). Ordinea rezultatelor nu e garantată, iar pentru operații scurte paralelismul poate fi mai lent decât varianta obișnuită.

Parametri

Parametru Descriere
-Process Blocul rulat pentru fiecare obiect (poziția 0).
-Begin Bloc rulat o dată, înainte de primul obiect.
-End Bloc rulat o dată, după ultimul obiect.
-MemberName Numele proprietății citite sau al metodei apelate (sintaxa simplificată).
-ArgumentList Argumentele pentru metoda dată în -MemberName.
-Parallel Bloc rulat în paralel pentru fiecare obiect (PowerShell 7.0+).
-ThrottleLimit Câte blocuri rulează simultan cu -Parallel; implicit 5.
-TimeoutSeconds Oprește execuția paralelă după numărul dat de secunde; 0 (implicit) înseamnă fără limită.
-AsJob Cu -Parallel, întoarce un job în loc de rezultate.

Ce returnează

Ce produce blocul de script pentru fiecare obiect (sau valoarea proprietății / metodei la -MemberName).

Exemple

Exemplul 1: Bloc de script și sintaxa simplificată

Primul rând construiește un mesaj pentru fiecare elev; al doilea apelează metoda ToUpper() pe fiecare șir.

$elevi = @(
    [pscustomobject]@{ Nume = 'Ana'; Nota = 9 }
    [pscustomobject]@{ Nume = 'Mihai'; Nota = 7 }
)
$elevi | ForEach-Object { "$($_.Nume) are nota $($_.Nota)" }
'ana', 'mihai' | ForEach-Object ToUpper

Ieșire în terminal

Ana are nota 9
Mihai are nota 7
ANA
MIHAI

Exemplul 2: -Begin, -Process și -End pentru un total

Totalul pornește de la 0, crește la fiecare comandă și se afișează la final.

$comenzi = 120, 75, 40
$comenzi | ForEach-Object -Begin { $total = 0 } -Process { $total += $_ } -End { "Total: $total lei" }

Ieșire în terminal

Total: 235 lei

Exemplul 3: -Parallel cu $using: (PowerShell 7.0+)

Cele trei blocuri rulează simultan, deci durează aproximativ o secundă, nu trei. Sortăm la final, pentru că ordinea rezultatelor paralele poate varia.

$domeniu = 'exemplu.ro'
$adrese = 'ana', 'mihai', 'ioana' | ForEach-Object -Parallel {
    Start-Sleep -Seconds 1
    "$_@$using:domeniu"
} -ThrottleLimit 3
$adrese | Sort-Object

Ieșire în terminal

ana@exemplu.ro
ioana@exemplu.ro
mihai@exemplu.ro

Greșeli frecvente

  • În blocul -Parallel, variabilele din script nu sunt vizibile direct: $domeniu e gol acolo. Folosește $using:domeniu.
  • Modificarea aceluiași obiect din blocuri paralele (de exemplu adăugarea, prin $using:, în aceeași listă obișnuită) nu e sigură; folosește tipuri thread-safe din System.Collections.Concurrent sau colectează rezultatele din ieșirea comenzii.
  • Confuzia dintre aliasul foreach (cmdlet-ul, în pipeline) și instrucțiunea foreach ($x in $lista) { }: instrucțiunea nu primește date prin |.
  • -Parallel nu există în Windows PowerShell 5.1: acolo comanda dă eroare de parametru.

Comenzi înrudite

  • Where-Object: Filtrează obiectele din pipeline și le lasă să treacă doar pe cele care îndeplinesc o condiție.
  • foreach: Buclele foreach, for, while și do-while repetă un bloc de cod; foreach parcurge o colecție din memorie, ForEach-Object lucrează în pipeline.
  • Pipeline (|): Operatorul | trimite obiectele unei comenzi, unul câte unul, comenzii următoare; $_ este obiectul curent, iar && și || înlănțuie comenzi.
  • Measure-Object: Numără obiectele și calculează suma, media, minimul și maximul unei proprietăți, sau numără rândurile, cuvintele și caracterele unui text.
  • Select-Object: Alege doar anumite proprietăți ale obiectelor, adaugă proprietăți calculate sau păstrează primele, ultimele ori unicele elemente.
Comunitate & Schimb de cunoștințe

Întrebări & Exemple de Cod: ForEach-Object

Ai o nelămurire despre utilizarea comenzii ForEach-Object sau ai descoperit un truc / fragment de cod util? Distribuie-l cu ceilalți programatori!

💬

Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!

Nu au fost adăugate încă întrebări sau exemple de cod pentru această pagină. Dacă ai întâlnit o problemă sau ai un snippet util, adaugă-l mai jos pentru a-i ajuta pe ceilalți.

Comunitate Adaugă o întrebare sau distribuie un cod

Moderare & Siguranță:

Pentru a menține calitatea și securitatea informațiilor, fiecare întrebare sau fragment de cod/prompt este analizat (manual sau prin moderare asistată de AI) înainte de publicare.