ForEach-Object

Provádí operaci proti každé položce v kolekci vstupních objektů.

Syntax

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
            [-InputObject <PSObject>]
            -Parallel <ScriptBlock>
            [-ThrottleLimit <Int32>]
            [-TimeoutSeconds <Int32>]
            [-AsJob]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

Description

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

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

  • 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-Objectpodporuje , processa end blokybegin, jak je popsáno v about_functions.

    Poznámka

    Skript blokuje spuštění v oboru volajícího. Proto bloky mají přístup k proměnným v daném oboru a můžou po dokončení rutiny vytvářet nové proměnné, které v daném oboru přetrvávají.

  • 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 v Windows PowerShell 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 $using: slova předejte proměnné odkazy na spuštěný skript.

    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 prostorů runspace nebo pokud existuje spousta iterací, které provádějí významnou práci. Od PowerShellu 7.1 se runspaces z fondu runspace ve výchozím nastavení znovu používají. Velikost fondu runspace je určena parametrem ThrottleLimit . 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í paralelní skripty používají 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 poli

Tento příklad vezme pole se třemi celými čísly a vydělí každou z nich čí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 $PSHOMEPowerShellu .

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 vlastnosti Délka 1024 a přidá mezeru (" ") k oddělení od další položky. Rutina používá vlastnost PSISContainer k určení, zda objekt je adresář.

Příklad 3: Provoz na nejnovějších událostech 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í.

$Events = Get-EventLog -LogName System -Newest 1000
$events | 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 uloží je do $Events proměnné. $Events pak se předá rutině ForEach-Object . Parametr Begin zobrazuje aktuální datum a čas. V dalším kroku použije parametr Process rutinu Out-File k vytvoření textového souboru s názvem events.txt a uloží vlastnost zprávy všech událostí v daném souboru. Nakonec se koncový parametr použije k zobrazení data a času po dokončení veškerého zpracování.

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 HKCU:\Network klíčem na text s velkými písmeny.

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 síťovém klíči představuje mapovanou 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, vytvoří se HKCU:\Network podklíč E s hodnotou registru RemotePath nastavenou na \\Server\Share.

Příkaz používá Get-ItemProperty rutinu k získání všech podklíčů síťového klíče a Set-ItemProperty rutiny ke změně hodnoty položky registru RemotePath v každém klíči. Set-ItemProperty V příkazu 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á metodu ToUpper() hodnoty RemotePath , což je řetězec (REG_SZ).

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

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

Tento příklad ukazuje účinek potrubí $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 vygeneruje hodnotu tak, ForEach-Object jak $null to dělá pro jiné objekty, které jsou k němu předané.

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

Tento příklad získá hodnotu path vlastnost 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 odpovídá prvnímu příkazu. Používá Foreach alias ForEach-Object rutiny a vynechá název parametru MemberName , který je volitelný.

Tato ForEach-Object rutina 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 Select-Object rutiny, 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 do názvů 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 . Používá syntaxi tečky k určení metody a závorek k uzavření argumentu oddělovače.

Druhý příkaz použije parametr MemberName k určení metody Split a parametr ArgumentList k identifikaci tečky (.) jako oddělovače rozdělení.

Třetí příkaz používá alias ForEach-ObjectForeach rutiny 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 na pozici. Všechny skripty blokují vazbu k parametru Process . Jsou však považovány za to, že byly předány parametrům Begin a 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áme dva bloky skriptu na pozici. Všechny skripty blokují vazbu k parametru Process . Jsou však považovány za to, že byly předány do parametrů Začátek, Proces a Konec .

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 je vždy namapován na begin blok, poslední blok je namapován na end blok a bloky mezi jsou namapovány na process blok.

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, více bloků skriptů předaných pomocí parametru Process se namapuje na parametry Begin a End . Abyste se tomuto mapování vyhnuli, musíte zadat explicitní hodnoty parametrů Začátek a Konec .

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 spí za jednu sekundu.

$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é $using: slovo se používá k předání proměnné do každého paralelního $Message skriptu bloku.

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 všechny pět bloků skriptů spustí současně.

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

Tento příklad vytvoří úlohu, která spouští blok skriptu paralelně, dva najednou.

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

$job | Receive-Job -Wait

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

$job proměnná obdrží objekt úlohy, který shromažďuje výstupní data a monitoruje spuštěný stav. Objekt úlohy se předá Receive-Job parametrem přepínače Wait , který streamuje výstup do konzoly, jako by ForEach-Object -Parallel byl spuštěn bez úlohy AsJob.

Příklad 14: Použití odkazů na bezpečné proměnné vlákna

Tento příklad vyvolá bloky skriptů paralelně, aby shromažďoval jedinečně pojmenované procesní objekty.

$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 objektu ConcurrentDictionary , aby se shromažďovaly objekty. Vzhledem k tomu, že souběžný slovník je bezpečný pro vlákno, je bezpečné je upravit jednotlivými paralelními skripty. Objekt bez vlákna, jako je System.Collections.Generic.Dictionary, by zde nebyl bezpečný.

Poznámka

Tento příklad je velmi neefektivní použití paralelního parametru. Skript jednoduše přidá vstupní objekt do souběžného objektu slovníku. Je triviální a stojí za režii vyvolání každého skriptu v samostatném vlákně. Normální provoz ForEach-Object bez paralelního přepínače je mnohem efektivnější a rychlejší. Tento příklad je určen pouze k předvedení použití bezpečných proměnných vlákna.

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

Tento příklad zapíše 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čování chyb paralelního spouštění

Tento příklad ukazuje ukončovací 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 není nikdy zapsán, protože paralelní skriptblock pro tuto iteraci byl ukončen.

Poznámka

Běžné proměnné parametrů PipelineVariablenejsou podporovány ve Foreach-Object -Parallel scénářích ani s klíčovým slovem$using:.

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

Proměnnou můžete vytvořit mimo blok skriptu s vymezeným Foreach-Object -Parallel oborem a použít ji uvnitř bloku skriptu 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' cannot be retrieved because it has not been set in the local session.

Vnořený skriptový blok nemůže získat přístup k $test2 proměnné a vyvolá se chyba.

Příklad 18: Vytvoření více úloh, které spouštějí 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é lze 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 blokování 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 omezení 5).

Parametry

-ArgumentList

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

Tento parametr byl zaveden v Windows PowerShell 3.0.

Type:Object[]
Aliases:Args
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-AsJob

Způsobí paralelní vyvolání jako úlohu PowerShellu. Jeden objekt úlohy se vrátí místo výstupu ze spuštěných bloků skriptů. Objekt úlohy obsahuje podřízené úlohy pro každý blok paralelního skriptu, který běží. Objekt úlohy může používat všechny rutiny úloh PowerShellu k monitorování stavu spuštění a načítání dat.

Tento parametr byl zaveden v PowerShellu 7.0.

Type:SwitchParameter
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters: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í jenom jednou pro celý kanál. Další informace o begin bloku najdete v tématu about_Functions.

Type:ScriptBlock
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-Confirm

Před spuštěním rutiny zobrazí výzvu k potvrzení.

Type:SwitchParameter
Aliases:cf
Position:Named
Default value:False
Accept pipeline input:False
Accept wildcard characters:False

-End

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

Type:ScriptBlock
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-InputObject

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

Pokud použijete parametr InputObject 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, abyste provedli ForEach-Object operace s kolekcí objektů pro tyto objekty, které mají určité hodnoty v definovaných vlastnostech, použijete ForEach-Object v kanálu, jak je znázorněno v příkladech v tomto tématu.

Type:PSObject
Position:Named
Default value:None
Accept pipeline input:True
Accept wildcard characters:False

-MemberName

Určuje vlastnost pro získání nebo metodu volání.

Jsou povoleny zástupné znaky, ale fungují jenom v případě, že výsledný řetězec přeloží na jedinečnou hodnotu. Pokud například spustíte Get-Process | ForEach -MemberName *Name, vzor zástupných znaků odpovídá více než jednomu členu, což způsobí selhání příkazu.

Tento parametr byl zaveden v Windows PowerShell 3.0.

Type:String
Position:0
Default value:None
Accept pipeline input:False
Accept wildcard characters: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 zaveden v PowerShellu 7.0.

Type:ScriptBlock
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-Process

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

Pokud do parametru Process zadáte více bloků skriptů, první blok skriptu se vždy mapuje na begin blok. Pokud existují pouze dva bloky skriptu, druhý blok se namapuje na process blok. Pokud existují tři nebo více bloků skriptu, první blok skriptu je vždy namapován na begin blok, poslední blok je namapován na end blok a bloky mezi jsou namapovány na process blok.

Type:ScriptBlock[]
Position:0
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-RemainingScripts

Určuje všechny bloky skriptu, které parametr Process nepřebíná.

Tento parametr byl zaveden v Windows PowerShell 3.0.

Type:ScriptBlock[]
Position:Named
Default value:None
Accept pipeline input:False
Accept wildcard characters:False

-ThrottleLimit

Určuje počet bloků skriptu, které jsou paralelně. Vstupní objekty jsou zablokované, dokud počet spuštěných bloků skriptu klesne pod omezeníLimit. 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é lze 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 blokování skriptů.

Tento parametr byl zaveden v PowerShellu 7.0.

Type:Int32
Position:Named
Default value:5
Accept pipeline input:False
Accept wildcard characters:False

-TimeoutSeconds

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

Tento parametr byl zaveden v PowerShellu 7.0.

Type:Int32
Position:Named
Default value:0
Accept pipeline input:False
Accept wildcard characters:False

-UseNewRunspace

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

Tento parametr byl zaveden v PowerShellu 7.1.

Type:SwitchParameter
Position:Named
Default value:False
Accept pipeline input:False
Accept wildcard characters:False

-WhatIf

Zobrazuje, co by se stalo při spuštění rutiny. Rutina není spuštěna.

Type:SwitchParameter
Aliases:wi
Position:Named
Default value:False
Accept pipeline input:False
Accept wildcard characters:False

Vstupy

PSObject

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

Výstupy

PSObject

Tato rutina vrací objekty, které jsou určeny vstupem.

Poznámky

Rutina ForEach-Object funguje podobně jako příkaz Foreach , s výjimkou toho, že nemůžete zadat příkaz Foreach . Další informace o příkazu Foreach najdete v tématu about_Foreach.

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

Pomocí ForEach-Object -Parallel:

  • Sada ForEach-Object -Parallel parametrů používá interní rozhraní API PowerShellu ke spuštění každého bloku skriptu v novém prostředí runspace. To je výrazně větší režijní náklady než běžné spouštění ForEach-Object sekvenčním zpracováním. Je důležité použít paralelně , kde je režie spuštění paralelně malá v porovnání s prací, které blok skriptu provádí. Příklad:

    • Výpočetní skripty náročné na vícejádrových počítačích
    • Skripty, které tráví čas čekáním na výsledky nebo provádění operací se soubory

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

  • Při paralelním spuštění nelze zaručit, že objekty zařízené scriptProperties nebo ScriptMethods budou fungovat správně, pokud jsou spuštěny v jiném prostředí runspace než skripty byly původně připojeny k nim.

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

    Toto chování může fungovat, pokud home runspace stále existuje. Pokud je však skript závislý na externích proměnných, které jsou přítomné pouze v prostoru runspace volajícího, a ne na domovském prostoru runspace, nemusí být požadovaný výsledek.

  • Nedokončující chyby se zapisují do datového proudu chyb rutiny, protože probíhají paralelně se spuštěnými skriptovacími bloky. Vzhledem k tomu, že pořadí provádění paralelního blokování skriptů není deterministické, je pořadí, ve kterém se chyby zobrazují v chybovém streamu, 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 nedeterminovat 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 blokování skriptů nemusí způsobit ukončení rutiny Foreach-Object . Ostatní bloky skriptů, spuštěné paralelně, se budou dál spouštět, pokud také nenarazí na ukončovací chybu. Ukončovací chyba se zapíše do datového proudu chyb jako ChybaZáznam s plně kvalifikovaným identifikátoremErrorId .PSTaskException Ukončovací chyby lze převést na nekončující chyby pomocí PowerShellu try/catch nebo trap bloků.

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

    Důležité

    Sada ForEach-Object -Parallel parametrů spouští bloky skriptů paralelně na samostatných vláknech procesu. $using: Klíčové slovo umožňuje předávat odkazy 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žívány. Obecně platí, že je bezpečné číst z odkazovaných objektů, které se nemění. Pokud se ale stav objektu upravuje, musíte použít bezpečné objekty vlákna, jako jsou typy .NET System.Collection.Concurrent (viz příklad 11).