Sdílet prostřednictvím


ForEach-Object

Provede operaci s každou položkou v kolekci vstupních objektů.

Syntaxe

ForEach-Object
            [-InputObject <PSObject>]
            [-Begin <ScriptBlock>]
            [-Process] <ScriptBlock[]>
            [-End <ScriptBlock>]
            [-RemainingScripts <ScriptBlock[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]
ForEach-Object
            [-InputObject <PSObject>]
            [-MemberName] <String>
            [-ArgumentList <Object[]>]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]
ForEach-Object
            -Parallel <scriptblock>
            [-InputObject <psobject>]
            [-ThrottleLimit <int>]
            [-TimeoutSeconds <int>]
            [-AsJob]
            [-UseNewRunspace]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

Description

Rutina ForEach-Object provádí operaci pro každou položku v kolekci vstupních objektů. Vstupní objekty lze předvést do rutiny nebo zadat pomocí InputObject parametru.

Počínaje windows PowerShellem 3.0 existují dva různé způsoby vytvoření příkazu ForEach-Object.

  • blok skriptu. K určení operace můžete použít blok skriptu. V bloku skriptu použijte proměnnou $_ k reprezentaci aktuálního objektu. Blok skriptu je hodnota parametru Process. Blok skriptu může obsahovat libovolný skript PowerShellu.

    Například následující příkaz získá hodnotu ProcessName vlastnost každého procesu v počítači.

    Get-Process | ForEach-Object {$_.ProcessName}

    ForEach-Object podporuje bloky begin, processa end, jak je popsáno v about_functions.

    Poznámka

    Bloky skriptu se spouštějí v oboru volajícího. Bloky proto mají přístup k proměnným v daném oboru a můžou vytvářet nové proměnné, které se v daném oboru zachovají po dokončení rutiny.

  • příkaz Operation. Můžete také napsat příkaz operace, což je mnohem více jako přirozený jazyk. Příkaz operace můžete použít k určení hodnoty vlastnosti nebo volání metody. Příkazy operací byly zavedeny ve Windows PowerShellu 3.0.

    Například následující příkaz získá také hodnotu ProcessName vlastnost každého procesu v počítači.

    Get-Process | ForEach-Object ProcessName

  • paralelní spuštění bloku skriptu. Počínaje PowerShellem 7.0 je k dispozici třetí sada parametrů, která spouští každý blok skriptu paralelně. Parametr ThrottleLimit omezuje počet paralelních skriptů spuštěných najednou. Stejně jako předtím použijte proměnnou $_ k reprezentaci aktuálního vstupního objektu v bloku skriptu. Pomocí klíčového slova $using: předejte do spuštěného skriptu odkazy na proměnné.

    V PowerShellu 7 se vytvoří nový runspace pro každou iteraci smyčky, aby se zajistila maximální izolace. To může být velký výkon a dosažení prostředků, pokud je práce, kterou děláte, malá ve srovnání s vytvářením nových prostředí runspace nebo pokud existuje velké množství iterací provádějících významnou práci. Od PowerShellu 7.1 se ve výchozím nastavení znovu používají prostory z fondu runspace. Parametr ThrottleLimit nastaví velikost fondu runspace. Výchozí velikost fondu runspace je 5. Pro každou iteraci můžete vytvořit nový runspace pomocí přepínače UseNewRunspace.

    Ve výchozím nastavení používají paralelní bloky skriptů aktuální pracovní adresář volajícího, který spustil paralelní úlohy.

    Další informace najdete v části POZNÁMKY tohoto článku.

Příklady

Příklad 1: Dělení celých čísel v matici

V tomto příkladu se používá pole se třemi celými čísly a každý z nich vydělí číslem 1024.

30000, 56798, 12432 | ForEach-Object -Process {$_/1024}

29.296875
55.466796875
12.140625

Příklad 2: Získání délky všech souborů v adresáři

Tento příklad zpracovává soubory a adresáře v instalačním adresáři PowerShellu $PSHOME.

Get-ChildItem $PSHOME |
  ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}

Pokud objekt není adresář, blok skriptu získá název souboru, vydělí hodnotu jeho Length vlastnost 1024 a přidá mezeru (" ") k oddělení od další položky. Rutina používá vlastnost PSISContainer k určení, zda je objekt adresářem.

Příklad 3: Operace s nejnovějšími událostmi systému

Tento příklad zapíše 1000 nejnovějších událostí z protokolu událostí systému do textového souboru. Aktuální čas se zobrazí před a po zpracování událostí.

Get-EventLog -LogName System -Newest 1000 |
    ForEach-Object -Begin {Get-Date} -Process {
        Out-File -FilePath Events.txt -Append -InputObject $_.Message
    } -End {Get-Date}

Get-EventLog získá 1000 nejnovějších událostí z protokolu událostí systému a předá je do rutiny ForEach-Object. Parametr Begin zobrazuje aktuální datum a čas. Dále parametr Process pomocí rutiny Out-File vytvoří textový soubor s názvem events.txt a uloží vlastnost zprávy jednotlivých událostí v daném souboru. Nakonec se k zobrazení data a času po dokončení veškerého zpracování použije parametr End.

Příklad 4: Změna hodnoty klíče registru

Tento příklad změní hodnotu položky registru RemotePath ve všech podklíčích pod klíčem HKCU:\Network na velká písmena.

Get-ItemProperty -Path HKCU:\Network\* |
  ForEach-Object {
    Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
  }

Tento formát můžete použít ke změně formuláře nebo obsahu hodnoty položky registru.

Každý podklíč v klíči Network představuje namapovanou síťovou jednotku, která se znovu připojí při přihlášení. Položka RemotePath obsahuje cestu UNC připojené jednotky. Pokud například namapujete jednotku E: na \\Server\Share, v HKCU:\Network se vytvoří podklíč E s hodnotou registru RemotePath nastavenou na \\Server\Share.

Příkaz používá rutinu Get-ItemProperty k získání všech podklíčů klíče Network a rutiny Set-ItemProperty ke změně hodnoty položky registru RemotePath v každém klíči. V příkazu Set-ItemProperty je cesta hodnotou vlastnosti PSPath klíče registru. Toto je vlastnost objektu rozhraní Microsoft .NET Framework, který představuje klíč registru, nikoli položku registru. Příkaz používá ToUpper() metodu RemotePath hodnotu, což je řetězec REG_SZ.

Vzhledem k tomu, že Set-ItemProperty mění vlastnost každého klíče, je pro přístup k této vlastnosti nutná rutina ForEach-Object.

Příklad 5: Použití $null automatické proměnné

Tento příklad ukazuje účinek propojení $null automatické proměnné do rutiny ForEach-Object.

1, 2, $null, 4 | ForEach-Object {"Hello"}

Hello
Hello
Hello
Hello

Vzhledem k tomu, že PowerShell považuje $null za explicitní zástupný symbol, rutina ForEach-Object vygeneruje hodnotu pro $null stejně jako pro ostatní objekty předané do něj.

Příklad 6: Získání hodnot vlastností

Tento příklad získá hodnotu vlastnosti Path všech nainstalovaných modulů PowerShellu pomocí parametru MemberName rutiny ForEach-Object.

Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path

Druhý příkaz je ekvivalentní prvnímu příkazu. Používá Foreach alias rutiny ForEach-Object a vynechá název parametru MemberName, který je volitelný.

Rutina ForEach-Object je užitečná pro získání hodnot vlastností, protože získá hodnotu beze změny typu, na rozdíl od rutin Format nebo rutiny Select-Object, která změní typ hodnoty vlastnosti.

Příklad 7: Rozdělení názvů modulů na názvy komponent

Tento příklad ukazuje tři způsoby rozdělení dvou názvů modulů oddělených tečkami na názvy komponent. Příkazy volají metodu Split řetězců. Tyto tři příkazy používají jinou syntaxi, ale jsou ekvivalentní a zaměnitelné. Výstup je stejný pro všechny tři případy.

"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object {$_.Split(".")}
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    ForEach-Object -MemberName Split -ArgumentList "."
"Microsoft.PowerShell.Core", "Microsoft.PowerShell.Host" |
    Foreach Split "."

Microsoft
PowerShell
Core
Microsoft
PowerShell
Host

První příkaz používá tradiční syntaxi, která zahrnuje blok skriptu a aktuální operátor objektu $_. Pomocí syntaxe tečky určuje metodu a závorky k uzavření argumentu oddělovače.

Druhý příkaz pomocí parametru MemberName určuje metodu Split a parametr ArgumentList k identifikaci tečky (.) jako oddělovače rozdělení.

Třetí příkaz používá alias Foreach rutiny ForEach-Object a vynechá názvy parametrů MemberName a ArgumentList, které jsou volitelné.

Příklad 8: Použití ForEach-Object se dvěma bloky skriptu

V tomto příkladu předáme dva bloky skriptu pozičním způsobem. Všechny bloky skriptu se sváže s parametrem Process. Považují se však za to, že byly předány do begin a parametry Process.

1..2 | ForEach-Object { 'begin' } { 'process' }

begin
process
process

Příklad 9: Použití ForEach-Object s více než dvěma bloky skriptu

V tomto příkladu předáváme pozičním způsobem čtyři bloky skriptu. Všechny bloky skriptu se sváže s parametrem Process. Považují se však za to, že byly předány do begin, Processa End parametry.

1..2 | ForEach-Object { 'begin' } { 'process A' }  { 'process B' } { 'end' }

begin
process A
process B
process A
process B
end

Poznámka

První blok skriptu se vždy mapuje na blok begin, poslední blok se mapuje na blok end a oba prostřední bloky se mapují na blok process.

Příklad 10: Spuštění více bloků skriptů pro každou položku kanálu

Jak je znázorněno v předchozím příkladu, několik bloků skriptu předaných pomocí parametru procesu se mapuje na parametry Begin a End. Chcete-li se tomuto mapování vyhnout, je nutné zadat explicitní hodnoty parametrů Begin a End.

1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null

one
two
three
one
two
three

Příklad 11: Spuštění pomalého skriptu v paralelních dávkách

V tomto příkladu se spustí blok skriptu, který vyhodnocuje řetězec a po dobu jedné sekundy spí.

$Message = "Output:"

1..8 | ForEach-Object -Parallel {
    "$using:Message $_"
    Start-Sleep 1
} -ThrottleLimit 4

Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8

Hodnota parametru ThrottleLimit je nastavená na 4, aby se vstup zpracovával v dávkách čtyř. Klíčové slovo $using: slouží k předání proměnné $Message do každého bloku paralelního skriptu.

Příklad 12: Paralelní načtení položek protokolu

Tento příklad načte 50 000 položek protokolu z 5 systémových protokolů na místním počítači s Windows.

$logNames = 'Security', 'Application', 'System', 'Windows PowerShell',
    'Microsoft-Windows-Store/Operational'

$logEntries = $logNames | ForEach-Object -Parallel {
    Get-WinEvent -LogName $_ -MaxEvents 10000
} -ThrottleLimit 5

$logEntries.Count

50000

Parametr Parallel určuje blok skriptu, který se spouští paralelně pro každý název vstupního protokolu. Parametr ThrottleLimit zajišťuje, že se současně spustí všech pět bloků skriptu.

Příklad 13: Paralelní spuštění jako úloha

Tento příklad vytvoří úlohu, která paralelně spustí blok skriptu, dva po druhé.

PS> $job = 1..10 | ForEach-Object -Parallel {
    "Output: $_"
    Start-Sleep 1
} -ThrottleLimit 2 -AsJob

PS> $job

Id     Name            PSJobTypeName   State         HasMoreData     Location      Command
--     ----            -------------   -----         -----------     --------      -------
23     Job23           PSTaskJob       Running       True            PowerShell    …

PS> $job.ChildJobs

Id     Name            PSJobTypeName   State         HasMoreData     Location      Command
--     ----            -------------   -----         -----------     --------      -------
24     Job24           PSTaskChildJob  Completed     True            PowerShell    …
25     Job25           PSTaskChildJob  Completed     True            PowerShell    …
26     Job26           PSTaskChildJob  Running       True            PowerShell    …
27     Job27           PSTaskChildJob  Running       True            PowerShell    …
28     Job28           PSTaskChildJob  NotStarted    False           PowerShell    …
29     Job29           PSTaskChildJob  NotStarted    False           PowerShell    …
30     Job30           PSTaskChildJob  NotStarted    False           PowerShell    …
31     Job31           PSTaskChildJob  NotStarted    False           PowerShell    …
32     Job32           PSTaskChildJob  NotStarted    False           PowerShell    …
33     Job33           PSTaskChildJob  NotStarted    False           PowerShell    …

Parametr ThrottleLimit omezuje počet paralelních bloků skriptů spuštěných najednou. Parametr AsJob způsobí, že rutina ForEach-Object vrátí objekt úlohy místo výstupu streamování do konzoly. Proměnná $job obdrží objekt úlohy, který shromažďuje výstupní data a monitoruje spuštěný stav. Vlastnost $job.ChildJobs obsahuje podřízené úlohy, které spouští bloky paralelních skriptů.

Příklad 14: Použití odkazůnach

Tento příklad vyvolá bloky skriptu paralelně ke shromažďování jedinečných pojmenovaných objektů Process.

$threadSafeDictionary = [System.Collections.Concurrent.ConcurrentDictionary[string,object]]::new()
Get-Process | ForEach-Object -Parallel {
    $dict = $using:threadSafeDictionary
    $dict.TryAdd($_.ProcessName, $_)
}

$threadSafeDictionary["pwsh"]

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     82    82.87     130.85      15.55    2808   2 pwsh

Do každého bloku skriptu se předá jedna instance ConcurrentDictionary objektu ke shromažďování objektů. Vzhledem k tomu, že ConcurrentDictionary je bezpečné pro přístup z více vláken, je bezpečné je upravovat jednotlivými paralelními skripty. Objekt, který není bezpečný pro přístup z více vláken, například System.Collections.Generic.Dictionary, by zde nebyl bezpečný.

Poznámka

Tento příklad představuje neefektivní použití parametru Parallel. Skript přidá vstupní objekt do souběžného objektu slovníku. Je triviální a nestojí za režii při vyvolání jednotlivých skriptů v samostatném vlákně. Spouštění ForEach-Object bez přepínače Parallel je efektivnější a rychlejší. Tento příklad je určen pouze k předvedení použití proměnných bezpečných pro přístup z více vláken.

Příklad 15: Zápis chyb s paralelním spouštěním

Tento příklad zapisuje do datového proudu chyb paralelně, kde pořadí zapsaných chyb je náhodné.

1..3 | ForEach-Object -Parallel {
    Write-Error "Error: $_"
}

Write-Error: Error: 1
Write-Error: Error: 3
Write-Error: Error: 2

Příklad 16: Ukončení chyb při paralelním spuštění

Tento příklad ukazuje ukončující chybu v jednom paralelním spuštění skriptublock.

1..5 | ForEach-Object -Parallel {
    if ($_ -eq 3)
    {
        throw "Terminating Error: $_"
    }

    Write-Output "Output: $_"
}

Exception: Terminating Error: 3
Output: 1
Output: 4
Output: 2
Output: 5

Output: 3 se nikdy nezapisuje, protože paralelní skriptblock pro tuto iteraci byl ukončen.

Poznámka

běžné proměnné parametrů PipelineVariable nejsou podporované ve scénářích Foreach-Object -Parallel ani s klíčovým slovem $using:.

Příklad 17: Předávání proměnných ve vnořeném paralelním skriptu ScriptBlockSet

Můžete vytvořit proměnnou mimo Foreach-Object -Parallel blok skriptu s vymezeným oborem a použít ji uvnitř skriptublock s klíčovým slovem $using.

$test1 = 'TestA'
1..2 | Foreach-Object -Parallel {
    $using:test1
}

TestA
TestA

# You CANNOT create a variable inside a scoped scriptblock
# to be used in a nested foreach parallel scriptblock.
$test1 = 'TestA'
1..2 | Foreach-Object -Parallel {
    $using:test1
    $test2 = 'TestB'
    1..2 | Foreach-Object -Parallel {
        $using:test2
    }
}

Line |
   2 |  1..2 | Foreach-Object -Parallel {
     |         ~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The value of the using variable '$using:test2' can't be retrieved because it has
     | not been set in the local session.

Vnořený skriptblock nemá přístup k proměnné $test2 a vyvolá se chyba.

Příklad 18: Vytvoření více úloh, které spouští skripty paralelně

Parametr ThrottleLimit omezuje počet paralelních skriptů spuštěných během každé instance ForEach-Object -Parallel. Neomezuje počet úloh, které je možné vytvořit při použití parametru AsJob. Vzhledem k tomu, že samotné úlohy běží souběžně, je možné vytvořit několik paralelních úloh, přičemž každý z nich běží až do limitu počtu souběžných skriptů.

$jobs = for ($i=0; $i -lt 10; $i++) {
    1..10 | ForEach-Object -Parallel {
        ./RunMyScript.ps1
    } -AsJob -ThrottleLimit 5
}

$jobs | Receive-Job -Wait

Tento příklad vytvoří 10 spuštěných úloh. Každá úloha nespustí více než 5 skriptů současně. Celkový počet spuštěných instancí je omezen na 50 (10 úloh krát Thromit 5).

Parametry

-ArgumentList

Určuje pole argumentů pro volání metody. Další informace o chování ArgumentListnaleznete v tématu about_Splatting.

Tento parametr byl představen ve Windows PowerShellu 3.0.

Typ:Object[]
Aliasy:Args
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-AsJob

Způsobí, že paralelní vyvolání se spustí jako úloha PowerShellu. Místo výstupu ze spuštěných bloků skriptu se vrátí jeden objekt úlohy. Objekt úlohy obsahuje podřízené úlohy pro každý blok paralelního skriptu, který se spouští. Objekt úlohy můžete použít s libovolnou rutinou úlohy PowerShellu k zobrazení spuštěného stavu a načtení dat.

Tento parametr byl představen v PowerShellu 7.0.

Typ:SwitchParameter
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-Begin

Určuje blok skriptu, který se spustí před tím, než tato rutina zpracuje všechny vstupní objekty. Tento blok skriptu se spustí pouze jednou pro celý kanál. Další informace o bloku begin naleznete v tématu about_Functions.

Typ:ScriptBlock
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-Confirm

Před spuštěním rutiny vás vyzve k potvrzení.

Typ:SwitchParameter
Aliasy:cf
Position:Named
Default value:False
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-End

Určuje blok skriptu, který se spustí po této rutině, zpracuje všechny vstupní objekty. Tento blok skriptu se spustí pouze jednou pro celý kanál. Další informace o bloku end naleznete v tématu about_Functions.

Typ:ScriptBlock
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-InputObject

Určuje vstupní objekty. ForEach-Object spustí blok skriptu nebo příkaz operace na každém vstupním objektu. Zadejte proměnnou, která obsahuje objekty, nebo zadejte příkaz nebo výraz, který objekty získá.

Pokud použijete InputObject parametr s ForEach-Object, místo piping command results to ForEach-Object, InputObject hodnota je považována za jeden objekt. To platí i v případě, že hodnota je kolekce, která je výsledkem příkazu, například -InputObject (Get-Process). Vzhledem k tomu, že InputObject nemůže vracet jednotlivé vlastnosti z pole nebo kolekce objektů, doporučujeme použít ForEach-Object k provádění operací s kolekcí objektů pro tyto objekty, které mají určité hodnoty v definovaných vlastnostech, použijete v kanálu ForEach-Object, jak je znázorněno v příkladech v tomto tématu.

Typ:PSObject
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:True
Přijmout zástupné znaky:False

-MemberName

Určuje název vlastnosti člena pro získání nebo metodu člena volání. Členy musí být členy instance, nikoli statické členy.

Jsou povoleny zástupné znaky, ale fungují pouze v případě, že se výsledný řetězec přeloží na jedinečnou hodnotu. Pokud například spustíte Get-Process | ForEach -MemberName *Name, vzor se zástupným znakem shoduje s více než jedním členem, což způsobí selhání příkazu.

Tento parametr byl představen ve Windows PowerShellu 3.0.

Typ:String
Position:0
Default value:None
Vyžadováno:True
Přijmout vstup kanálu:False
Přijmout zástupné znaky:True

-Parallel

Určuje blok skriptu, který se má použít pro paralelní zpracování vstupních objektů. Zadejte blok skriptu, který popisuje operaci.

Tento parametr byl představen v PowerShellu 7.0.

Typ:ScriptBlock
Position:Named
Default value:None
Vyžadováno:True
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-Process

Určuje operaci, která se provádí u každého vstupního objektu. Tento blok skriptu se spouští pro každý objekt v kanálu. Další informace o bloku process naleznete v tématu about_Functions.

Pokud do parametru Process zadáte více bloků skriptu, první blok skriptu se vždy mapuje na blok begin. Pokud existují jenom dva bloky skriptu, druhý blok se mapuje na process blok. Pokud existují tři nebo více bloků skriptu, první blok skriptu se vždy mapuje na blok begin, poslední blok se mapuje na blok end a prostřední bloky se mapují na blok process.

Typ:ScriptBlock[]
Position:0
Default value:None
Vyžadováno:True
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-RemainingScripts

Určuje všechny bloky skriptu, které nejsou převzaty parametrem Process.

Tento parametr byl představen ve Windows PowerShellu 3.0.

Typ:ScriptBlock[]
Position:Named
Default value:None
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-ThrottleLimit

Určuje počet bloků skriptu, které se spouští paralelně. Vstupní objekty jsou blokované, dokud počet spuštěných bloků skriptu klesne pod ThrottleLimit. Výchozí hodnota je 5.

Parametr ThrottleLimit omezuje počet paralelních skriptů spuštěných během každé instance ForEach-Object -Parallel. Neomezuje počet úloh, které je možné vytvořit při použití parametru AsJob. Vzhledem k tomu, že samotné úlohy běží souběžně, je možné vytvořit řadu paralelních úloh, přičemž každý z nich běží až do limitu počtu souběžných skriptů.

Tento parametr byl představen v PowerShellu 7.0.

Typ:Int32
Position:Named
Default value:5
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-TimeoutSeconds

Určuje počet sekund, po který se má čekat na zpracování všech vstupů paralelně. Po uplynutí zadaného časového limitu se zastaví všechny spuštěné skripty. Všechny zbývající vstupní objekty, které se mají zpracovat, se ignorují. Výchozí hodnota 0 časový limit zakáže a ForEach-Object -Parallel může běžet neomezeně dlouho. Psaní Ctrl+C na příkazovém řádku zastaví spuštěný příkaz ForEach-Object -Parallel. Tento parametr nelze použít společně s parametrem AsJob.

Tento parametr byl představen v PowerShellu 7.0.

Typ:Int32
Position:Named
Default value:0
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-UseNewRunspace

Způsobí, že paralelní vyvolání vytvoří nový runspace pro každou iteraci smyčky místo opakovaného použití prostorů runspace z fondu runspace.

Tento parametr byl představen v PowerShellu 7.1.

Typ:SwitchParameter
Position:Named
Default value:False
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

-WhatIf

Ukazuje, co se stane, když se rutina spustí. Rutina se nespustí.

Typ:SwitchParameter
Aliasy:wi
Position:Named
Default value:False
Vyžadováno:False
Přijmout vstup kanálu:False
Přijmout zástupné znaky:False

Vstupy

PSObject

Do této rutiny můžete převést libovolný objekt.

Výstupy

PSObject

Tato rutina vrátí objekty, které jsou určeny vstupem.

Poznámky

PowerShell obsahuje následující aliasy pro ForEach-Object:

  • Všechny platformy:
    • %
    • foreach

Rutina ForEach-Object funguje podobně jako příkaz Foreach s tím rozdílem, že vstup do příkazu Foreach nelze převést. Další informace o příkazu Foreach naleznete v tématu about_Foreach.

Počínaje PowerShellem 4.0 byly přidány metody Where a ForEach pro použití s kolekcemi. Další informace o těchto nových metodách najdete about_arrays

Použití ForEach-Object -Parallel:

  • ForEach-Object -Parallel spustí každý blok skriptu v novém prostředí runspace. Nové runspaces vytvářejí výrazně větší režii než spouštění ForEach-Object se sekvenčním zpracováním. Je důležité použít Parallel, kde je režie paralelního spuštění malá v porovnání s prací, kterou provádí blok skriptu. Například:

    • Skripty náročné na výpočetní výkon na počítačích s více jádry
    • Skripty, které tráví čas čekáním na výsledky nebo prováděním operací se soubory

    Použití parametru Parallel může způsobit, že skripty běží mnohem pomaleji než obvykle. Zvláště pokud jsou paralelní skripty triviální. Experimentujte s paralelními zjistit, kde může být přínosný.

  • Při paralelním spuštění objekty zdobené ScriptProperties nebo ScriptMethods nelze zaručit správné fungování, pokud jsou spouštěny v jiném prostředí runspace než skripty původně připojené.

    Vyvolání scriptblocku se vždy pokusí spustit ve svém domovské runspace bez ohledu na to, kde se skutečně vyvolá. ForEach-Object -Parallel však vytvoří dočasné prostředí runspace, které se po použití odstraní, takže skripty už nebudou spuštěné.

    Toto chování může fungovat, pokud domovské runspace stále existuje. Požadovaný výsledek však nelze získat, pokud je skript závislý na externích proměnných, které jsou přítomné pouze v prostředí runspace volajícího, a ne na domovské runspace.

  • Neukončující chyby se zapisují do datového proudu chyb rutiny, protože probíhají paralelně se spouštěním skriptů. Vzhledem k tomu, že pořadí provádění paralelního bloku skriptu není deterministické, pořadí, ve kterém se chyby zobrazují v chybovém streamu, je náhodné. Podobně se zprávy zapsané do jiných datových proudů, jako jsou upozornění, podrobné nebo informace, zapisují do těchto datových proudů v neurčité pořadí.

    Ukončování chyb, jako jsou výjimky, ukončete jednotlivé paralelní instance skriptů, ve kterých k nim dochází. Ukončení chyby v jednom bloku skriptu nemusí způsobit ukončení rutiny Foreach-Object. Ostatní skripty, spuštěné paralelně, se budou dál spouštět, pokud také nenarazí na ukončující chybu. Ukončovací chyba je zapsána do datového proudu chyby jako ErrorRecord s FullyQualifiedErrorIdPSTaskException. Ukončovací chyby je možné převést na neukončující chyby pomocí powershellových try/catch nebo bloků trap.

  • běžné proměnné parametrů PipelineVariable nejsou podporovány v paralelních scénářích ani s klíčovým slovem $using:.

    Důležitý

    Sada parametrů ForEach-Object -Parallel spouští bloky skriptu paralelně na samostatných vláknech procesu. Klíčové slovo $using: umožňuje předávání odkazů na proměnné z vlákna vyvolání rutiny do každého spuštěného vlákna bloku skriptu. Vzhledem k tomu, že bloky skriptu běží v různých vláknech, musí být proměnné objektů předané odkazem bezpečně použity. Obecně je bezpečné číst z odkazovaných objektů, které se nemění. Pokud potřebujete upravit stav objektu, je nutné použít bezpečné objekty vlákna, jako je .NET System.Collection.Concurrent typy (viz příklad 14).