Freigeben über


ForEach-Object

Führt einen Vorgang für jedes Element in einer Auflistung von Eingabeobjekten aus.

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>]

Beschreibung

Das ForEach-Object Cmdlet führt einen Vorgang für jedes Element in einer Auflistung von Eingabeobjekten aus. Die Eingabeobjekte können an das Cmdlet weitergeleitet oder mit dem InputObject-Parameter angegeben werden.

Ab Windows PowerShell 3.0 gibt es zwei verschiedene Möglichkeiten, einen ForEach-Object Befehl zu erstellen.

  • Skriptblock. Sie können einen Skriptblock verwenden, um den Vorgang anzugeben. Verwenden Sie im Skriptblock die $_ Variable, um das aktuelle Objekt darzustellen. Der Skriptblock ist der Wert des Process-Parameters. Der Skriptblock kann ein beliebiges PowerShell-Skript enthalten.

    Der folgende Befehl ruft beispielsweise den Wert der ProcessName-Eigenschaft der einzelnen Prozesse auf dem Computer ab.

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

    ForEach-Object unterstützt die beginBlöcke , processund end , wie in about_functions beschrieben.

    Hinweis

    Die Skriptblöcke werden im Bereich des Aufrufers ausgeführt. Daher haben die Blöcke Zugriff auf Variablen in diesem Bereich und können neue Variablen erstellen, die nach Abschluss des Cmdlets in diesem Bereich beibehalten werden.

  • Operation-Anweisung. Sie können auch eine Vorgangsanweisung schreiben, die viel mehr der natürlichen Sprache entspricht. Sie können die Vorgangsanweisung verwenden, um einen Eigenschaftenwert anzugeben oder eine Methode aufzurufen. Vorgangsanweisungen wurden in Windows PowerShell 3.0 eingeführt.

    Der folgende Befehl ruft beispielsweise ebenfalls den Wert der ProcessName-Eigenschaft der einzelnen Prozesse auf dem Computer ab.

    Get-Process | ForEach-Object ProcessName

  • Parallel ausgeführter Skriptblock. Ab PowerShell 7.0 ist ein dritter Parametersatz verfügbar, der jeden Skriptblock parallel ausführt. Der Parameter ThrottleLimit schränkt die Anzahl parallel ausgeführter Skripts ein. Verwenden Sie wie zuvor die $_ Variable, um das aktuelle Eingabeobjekt im Skriptblock darzustellen. Verwenden Sie die $using: Schlüsselwort (keyword), um Variablenverweise an das ausgeführte Skript zu übergeben.

    In PowerShell 7 wird für jede Schleifeniteration ein neuer Runspace erstellt, um eine maximale Isolation sicherzustellen. Dies kann ein großer Leistungs- und Ressourcentreffer sein, wenn die Arbeit, die Sie ausführen, im Vergleich zum Erstellen neuer Runspaces gering ist oder wenn es viele Iterationen gibt, die erhebliche Arbeit leisten. Ab PowerShell 7.1 werden Runspaces aus einem Runspace-Pool standardmäßig wiederverwendet. Die Größe des Runspacepools wird durch den Parameter ThrottleLimit angegeben. Die Standardgröße des Runspacepools ist 5. Sie können weiterhin einen neuen Runspace für jede Iteration mit dem UseNewRunspace-Switch erstellen.

    Standardmäßig verwenden die parallelen Skriptblöcke das aktuelle Arbeitsverzeichnis des Aufrufers, der die parallelen Aufgaben gestartet hat.

    Weitere Informationen finden Sie im Abschnitt NOTES dieses Artikels.

Beispiele

Beispiel 1: Teilen ganzer Zahlen in einem Array

In diesem Beispiel wird ein Array von drei ganzen Zahlen verwendet und jede einzelne durch 1024 unterteilt.

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

29.296875
55.466796875
12.140625

Beispiel 2: Abrufen der Länge aller Dateien in einem Verzeichnis

In diesem Beispiel werden die Dateien und Verzeichnisse im PowerShell-Installationsverzeichnis $PSHOMEverarbeitet.

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

Wenn das Objekt kein Verzeichnis ist, ruft der Skriptblock den Namen der Datei ab, dividiert den Wert der Length-Eigenschaft durch 1024 und fügt ein Leerzeichen (" ") hinzu, um es vom nächsten Eintrag zu trennen. Das Cmdlet verwendet die PSISContainer-Eigenschaft , um zu bestimmen, ob ein Objekt ein Verzeichnis ist.

Beispiel 3: Ausführen der neuesten Systemereignisse

In diesem Beispiel werden die 1000 neuesten Ereignisse aus dem Systemereignisprotokoll in eine Textdatei geschrieben. Die aktuelle Uhrzeit wird vor und nach der Verarbeitung der Ereignisse angezeigt.

$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 ruft die 1000 neuesten Ereignisse aus dem Systemereignisprotokoll ab und speichert sie in der $Events Variablen. $Events wird dann an das ForEach-Object Cmdlet weitergeleitet. Der Begin-Parameter zeigt das aktuelle Datum und die Uhrzeit. Als Nächstes erstellt der Process-Parameter mithilfe des Out-File Cmdlets eine Textdatei mit dem Namen events.txt und speichert die Nachrichteneigenschaft jedes Ereignisses in dieser Datei. Schließlich wird der End-Parameter verwendet, um das Datum und die Uhrzeit anzuzeigen, zu denen die gesamte Verarbeitung abgeschlossen wurde.

Beispiel 4: Ändern des Werts eines Registrierungsschlüssels

In diesem Beispiel wird der Wert des RemotePath-Registrierungseintrags in allen Unterschlüsseln unter dem HKCU:\Network Schlüssel in Großbuchstaben geändert.

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

Sie können dieses Format verwenden,um die Form oder den Inhalt eines Registrierungseintragswerts zu ändern.

Jeder Unterschlüssel im Netzwerkschlüssel stellt ein zugeordnetes Netzwerklaufwerk dar, das bei der Anmeldung wieder verbunden wird. Der RemotePath-Eintrag enthält den UNC-Pfad des verbundenen Laufwerks. Wenn Sie beispielsweise das Laufwerk E: zuordnen, \\Server\Sharewird in ein Unterschlüssel E erstellt, wobei HKCU:\Network der RemotePath-Registrierungswert auf \\Server\Sharefestgelegt ist.

Der Befehl verwendet das Get-ItemProperty Cmdlet, um alle Unterschlüssel des Netzwerkschlüssels und des Set-ItemProperty Cmdlets abzurufen, um den Wert des RemotePath-Registrierungseintrags in jedem Schlüssel zu ändern. Set-ItemProperty Im Befehl ist der Pfad der Wert der PSPath-Eigenschaft des Registrierungsschlüssels. Dies ist eine Eigenschaft des Microsoft .NET Framework-Objekts, das den Registrierungsschlüssel und keinen Registrierungseintrag darstellt. Der Befehl verwendet die ToUpper() -Methode des RemotePath-Werts , bei dem es sich um eine Zeichenfolge (REG_SZ) handelt.

Da Set-ItemProperty die Eigenschaft jedes Schlüssels geändert wird, ist das ForEach-Object Cmdlet erforderlich, um auf die Eigenschaft zuzugreifen.

Beispiel 5: Verwenden der $Null automatischen Variablen

In diesem Beispiel wird die Auswirkung des Pipings der $Null automatischen Variablen an das ForEach-Object Cmdlet veranschaulicht.

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

Hello
Hello
Hello
Hello

Da PowerShell NULL als expliziten Platzhalter behandelt, generiert das ForEach-Object Cmdlet einen Wert für $Null, genau wie für andere Objekte, die Sie an das Cmdlet übergeben haben.

Beispiel 6: Abrufen von Eigenschaftswerten

In diesem Beispiel wird der Wert der Path-Eigenschaft aller installierten PowerShell-Module mithilfe des MemberName-Parameters des ForEach-Object Cmdlets abgerufen.

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

Der zweite Befehl entspricht dem ersten. Es verwendet den Foreach Alias des ForEach-Object Cmdlets und lässt den Namen des MemberName-Parameters aus, der optional ist.

Das ForEach-Object Cmdlet ist nützlich zum Abrufen von Eigenschaftswerten, da es den Wert erhält, ohne den Typ zu ändern, im Gegensatz zu den Format-Cmdlets oder dem Select-Object Cmdlet, die den Eigenschaftswerttyp ändern.

Beispiel 7: Aufteilen von Modulnamen in Komponentennamen

In diesem Beispiel werden drei Möglichkeiten gezeigt, zwei punkttrennte Modulnamen in ihre Komponentennamen aufzuteilen. Die Befehle rufen die SplitMethode von Zeichenfolgen auf. Die drei Befehle verwenden unterschiedliche Syntax, sind aber äquivalent und austauschbar. Die Ausgabe ist für alle drei Fälle identisch.

"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

Der erste Befehl verwendet die herkömmliche Syntax, die einen Skriptblock und den aktuellen Objektoperator $_enthält. Es verwendet die Punktsyntax zum Angeben der Methode und die Klammern, um das Trennzeichenargument einzuschließen.

Der zweite Befehl verwendet den MemberName-Parameter , um die Split-Methode und den ArgumentList-Parameter anzugeben, um den Punkt (.) als geteiltes Trennzeichen zu identifizieren.

Der dritte Befehl verwendet den Foreach-Alias des ForEach-Object Cmdlets und verzichtet auf die Namen der optionalen Parameter MemberName und ArgumentList .

Beispiel 8: Verwenden von ForEach-Object mit zwei Skriptblöcken

In diesem Beispiel übergeben wir zwei Skriptblöcke positional. Alle Skriptblöcke binden an den Process-Parameter . Sie werden jedoch so behandelt, als wären sie an die Parameter Begin und Process übergeben worden.

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

begin
process
process

Beispiel 9: Verwenden von ForEach-Object mit mehr als zwei Skriptblöcken

In diesem Beispiel übergeben wir zwei Skriptblöcke positional. Alle Skriptblöcke binden an den Process-Parameter . Sie werden jedoch so behandelt, als wären sie an die Parameter Begin, Process und End übergeben worden.

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

begin
process A
process B
process A
process B
end

Hinweis

Der erste Skriptblock wird immer dem begin Block zugeordnet, der letzte Block wird dem end Block zugeordnet, und die Blöcke dazwischen sind alle dem process Block zugeordnet.

Beispiel 10: Ausführen mehrerer Skriptblöcke für jedes Pipelineelement

Wie im vorherigen Beispiel gezeigt, werden mehrere Skriptblöcke, die mit dem Process-Parameter übergeben werden, den Parametern Begin und End zugeordnet. Um diese Zuordnung zu vermeiden, müssen Sie explizite Werte für die Parameter Begin und End angeben.

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

one
two
three
one
two
three

Beispiel 11: Ausführen von langsamen Skripts in parallelen Batches

In diesem Beispiel wird ein einfacher Skriptblock ausgeführt, der eine Zeichenfolge auswertet und eine Sekunde lang ruhet.

$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

Der Wert des ThrottleLimit-Parameters ist auf 4 festgelegt, sodass die Eingabe in vier Batches verarbeitet wird. Die $using: Schlüsselwort (keyword) wird verwendet, um die $Message Variable an jeden parallelen Skriptblock zu übergeben.

Beispiel 12: Paralleles Abrufen von Protokolleinträgen

In diesem Beispiel werden 50.000 Protokolleinträge aus 5 Systemprotokollen auf einem lokalen Windows-Computer abgerufen.

$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

Der Parameter Parallel gibt den Skriptblock an, der für jeden Eingabeprotokollnamen parallel ausgeführt wird. Der ThrottleLimit-Parameter stellt sicher, dass alle fünf Skriptblöcke gleichzeitig ausgeführt werden.

Beispiel 13: Parallele Ausführung als Auftrag

In diesem Beispiel wird ein einfacher Skriptblock parallel ausgeführt, wobei zwei Hintergrundaufträge gleichzeitig erstellt werden.

$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

Die $job Variable empfängt das Auftragsobjekt, das Ausgabedaten sammelt und den Ausführungszustand überwacht. Das Auftragsobjekt wird mit dem Parameter Wait switch an Receive-Job pipediert. Und diese streamt die Ausgabe an die Konsole, als ob ForEach-Object -Parallel ohne AsJob ausgeführt wurde.

Beispiel 14: Verwenden von threadsicheren Variablenverweise

In diesem Beispiel werden Skriptblöcke parallel aufgerufen, um eindeutig benannte Process-Objekte zu sammeln.

$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

Ein einzelner instance eines ConcurrentDictionary-Objekts wird an jeden Skriptblock übergeben, um die Objekte zu sammeln. Da ConcurrentDictionary threadsicher ist, ist es sicher, von jedem parallelen Skript geändert zu werden. Ein nicht threadsicheres Objekt, z. B . System.Collections.Generic.Dictionary, kann hier nicht sicher verwendet werden.

Hinweis

Dieses Beispiel ist eine sehr ineffiziente Verwendung des Parallel-Parameters . Das Skript fügt das Eingabeobjekt einfach einem gleichzeitigen Wörterbuchobjekt hinzu. Es ist trivial und lohnt sich nicht den Mehraufwand, jedes Skript in einem separaten Thread zu aufrufen. Die normale Ausführung ForEach-Objectohne parallelen Schalter ist viel effizienter und schneller. In diesem Beispiel soll nur veranschaulicht werden, wie threadsichere Variablen verwendet werden.

Beispiel 15: Schreibfehler bei paralleler Ausführung

In diesem Beispiel wird parallel in den Fehlerstream geschrieben, wobei die Reihenfolge der geschriebenen Fehler zufällig ist.

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

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

Beispiel 16: Beenden von Fehlern bei paralleler Ausführung

In diesem Beispiel wird ein Abbruchfehler in einem parallel ausgeführten Skriptblock veranschaulicht.

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 wird nie geschrieben, weil der parallele Skriptblock für diese Iteration beendet wurde.

Hinweis

Allgemeine Parametervariablen von PipelineVariable werden in Foreach-Object -Parallel Szenarien auch mit dem $using: Schlüsselwort (keyword) nicht unterstützt.

Beispiel 17: Übergeben von Variablen im geschachtelten parallelen Skript ScriptBlockSet

Sie können eine Variable außerhalb eines Foreach-Object -Parallel bereichsbezogenen Skriptblocks erstellen und im Scriptblock mit dem $using Schlüsselwort (keyword) verwenden.

$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.

Der geschachtelte Skriptblock kann nicht auf die $test2 Variable zugreifen, und es wird ein Fehler ausgelöst.

Parameter

-ArgumentList

Gibt ein Array von Argumenten für einen Methodenaufruf an. Weitere Informationen zum Verhalten von ArgumentList finden Sie unter about_Splatting.

Dieser Parameter wurde in Windows PowerShell 3.0 eingeführt.

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

-AsJob

Bewirkt, dass der parallele Aufruf als PowerShell-Auftrag ausgeführt wird. Ein einzelnes Auftragsobjekt wird anstelle der Ausgabe der ausgeführten Skriptblöcke zurückgegeben. Das Auftragsobjekt enthält untergeordnete Aufträge für jeden ausgeführten parallelen Skriptblock. Das Auftragsobjekt kann von allen PowerShell-Auftrags-Cmdlets verwendet werden, um den Ausführungsstatus zu überwachen und Daten abzurufen.

Dieser Parameter wurde in PowerShell 7.0 eingeführt.

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

-Begin

Gibt einen Skriptblock an, der ausgeführt wird, bevor dieses Cmdlet Eingabeobjekte verarbeitet. Dieser Skriptblock wird nur einmal für die gesamte Pipeline ausgeführt. Weitere Informationen zum begin Block finden Sie unter about_Functions.

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

-Confirm

Hiermit werden Sie vor der Ausführung des Cmdlets zur Bestätigung aufgefordert.

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

-End

Gibt einen Skriptblock an, der ausgeführt wird, nachdem dieses Cmdlet alle Eingabeobjekte verarbeitet hat. Dieser Skriptblock wird nur einmal für die gesamte Pipeline ausgeführt. Weitere Informationen zum end Block finden Sie unter about_Functions.

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

-InputObject

Gibt die Eingabeobjekte an. ForEach-Object führt den Skriptblock oder die Operation-Anweisung für jedes Eingabeobjekt aus. Geben Sie eine Variable ein, die die Objekte enthält, oder geben Sie einen Befehl oder einen Ausdruck ein, mit dem die Objekte abgerufen werden.

Wenn Sie den InputObject-Parameter mit ForEach-Objectverwenden, anstatt Befehlsergebnisse an zu ForEach-Objectleiten, wird der InputObject-Wert als einzelnes Objekt behandelt. Dies gilt auch, wenn der Wert eine Auflistung ist, die das Ergebnis eines Befehls ist, z -InputObject (Get-Process). B. . Da InputObject keine einzelnen Eigenschaften aus einem Array oder einer Auflistung von Objekten zurückgeben kann, wird empfohlen, dass Sie, wie in den Beispielen in diesem Thema gezeigt, in der Pipeline verwendenForEach-Object, wenn Sie ForEach-Object zum Ausführen von Vorgängen für eine Auflistung von Objekten verwenden, die bestimmte Werte in definierten Eigenschaften aufweisen.

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

-MemberName

Gibt die abzurufende Eigenschaft oder die aufzurufende Methode an.

Wildcardzeichen sind zulässig, funktionieren jedoch nur, wenn die resultierende Zeichenfolge in einen eindeutigen Wert aufgelöst wird. Wenn Sie z. B. ausführen Get-Process | ForEach -MemberName *Name, stimmt das Wildcardmuster mit mehreren Membern überein, was dazu führt, dass der Befehl fehlschlägt.

Dieser Parameter wurde in Windows PowerShell 3.0 eingeführt.

Type:String
Position:0
Default value:None
Required:True
Accept pipeline input:False
Accept wildcard characters:True

-Parallel

Gibt den Skriptblock an, der für die parallele Verarbeitung von Eingabeobjekten verwendet werden soll. Geben Sie einen Skriptblock ein, der den Vorgang beschreibt.

Dieser Parameter wurde in PowerShell 7.0 eingeführt.

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

-Process

Gibt den Vorgang an, der für jedes Eingabeobjekt ausgeführt wird. Dieser Skriptblock wird für jedes Objekt in der Pipeline ausgeführt. Weitere Informationen zum process Block finden Sie unter about_Functions.

Wenn Sie mehrere Skriptblöcke für den Parameter Process bereitstellen, wird dem Block immer der erste Skriptblock zugeordnet begin . Wenn nur zwei Skriptblöcke vorhanden sind, wird der zweite Block dem process Block zugeordnet. Wenn drei oder mehr Skriptblöcke vorhanden sind, wird der erste Skriptblock immer dem begin Block zugeordnet, der letzte Block wird dem end Block zugeordnet, und die Blöcke dazwischen werden dem process Block zugeordnet.

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

-RemainingScripts

Gibt alle Skriptblöcke an, die nicht vom Process-Parameter übernommen werden.

Dieser Parameter wurde in Windows PowerShell 3.0 eingeführt.

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

-ThrottleLimit

Gibt die Anzahl von Skriptblöcken an, die parallel ausgeführt werden. Eingabeobjekte werden blockiert, bis die Anzahl der ausgeführten Skriptblocks unter das ThrottleLimit fällt. Standardwert: 5.

Dieser Parameter wurde in PowerShell 7.0 eingeführt.

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

-TimeoutSeconds

Gibt die Anzahl von Sekunden an, die auf die parallele Verarbeitung aller Eingaben gewartet werden soll. Nach dem angegebenen Timeout werden alle ausgeführten Skripts beendet. Alle verbleibenden zu verarbeitenden Eingabeobjekte werden ignoriert. Der Standardwert von 0 deaktiviert das Timeout und ForEach-Object -Parallel kann unbegrenzt ausgeführt werden. Durch Drücken von STRG+C an der Befehlszeile wird ein ausgeführter ForEach-Object -Parallel Befehl beendet. Dieser Parameter kann nicht zusammen mit dem AsJob-Parameter verwendet werden.

Dieser Parameter wurde in PowerShell 7.0 eingeführt.

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

-UseNewRunspace

Bewirkt, dass der parallele Aufruf einen neuen Runspace für jede Schleifeniteration erstellt, anstatt Runspaces aus dem Runspacepool wiederzuverwenden.

Dieser Parameter wurde in PowerShell 7.1 eingeführt.

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

-WhatIf

Zeigt, was geschieht, wenn das Cmdlet ausgeführt wird. Das Cmdlet wird nicht ausgeführt.

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

Eingaben

PSObject

Sie können jedes Objekt an dieses Cmdlet übergeben.

Ausgaben

PSObject

Dieses Cmdlet gibt Objekte zurück, die durch die Eingabe bestimmt werden.

Hinweise

Das ForEach-Object Cmdlet funktioniert ähnlich wie die Foreach-Anweisung , mit der Ausnahme, dass Sie keine Eingabe an eine Foreach-Anweisung übergeben können. Weitere Informationen zur Foreach-Anweisung finden Sie unter about_Foreach.

Ab PowerShell 4.0 WhereForEach wurden Methoden für die Verwendung mit Sammlungen hinzugefügt. Weitere Informationen zu diesen neuen Methoden finden Sie hier about_arrays

Verwenden von ForEach-Object -Parallel:

  • Der ForEach-Object -Parallel Parametersatz verwendet die interne PowerShell-API, um jeden Skriptblock in einem neuen Runspace auszuführen. Dies ist deutlich mehr Aufwand als bei der normalen Ausführung ForEach-Object bei sequenzieller Verarbeitung. Es ist wichtig, Parallel zu verwenden, wenn der Mehraufwand für die parallele Ausführung im Vergleich zur Arbeit, die der Skriptblock ausführt, gering ist. Beispiel:

    • Rechenintensive Skripts auf Computern mit mehreren Kernen
    • Skripts, die Zeit damit verbringen, auf Ergebnisse zu warten oder Dateivorgänge auszuführen

    Die Verwendung des Parallel-Parameters kann dazu führen, dass Skripts viel langsamer als normal ausgeführt werden. Insbesondere, wenn die parallelen Skripts trivial sind. Experimentieren Sie mit Parallel , um herauszufinden, wo es von Vorteil sein kann.

  • Bei paralleler Ausführung kann nicht garantiert werden, dass Objekte, die mit ScriptProperties oder ScriptMethods versehen sind, ordnungsgemäß funktionieren, wenn sie in einem anderen Runspace ausgeführt werden, als die Skripts ursprünglich an sie angefügt waren.

    Der Scriptblock-Aufruf versucht immer, in seinem Startrunspace auszuführen, unabhängig davon, wo er tatsächlich aufgerufen wird. Erstellt jedoch temporäre Runspaces, ForEach-Object -Parallel die nach der Verwendung gelöscht werden, sodass es keinen Runspace mehr gibt, in dem die Skripts ausgeführt werden können.

    Dieses Verhalten kann funktionieren, solange der Startrunspace noch vorhanden ist. Sie erhalten jedoch möglicherweise nicht das gewünschte Ergebnis, wenn das Skript von externen Variablen abhängig ist, die nur im Runspace des Aufrufers und nicht im Startrunspace vorhanden sind.

  • Fehler, die nicht beendet werden, werden in den Cmdlet-Fehlerstream geschrieben, wenn sie in parallel ausgeführten Skriptblocks auftreten. Da die Ausführungsreihenfolge des parallelen Skriptblocks nicht deterministisch ist, ist die Reihenfolge, in der Fehler im Fehlerstream angezeigt werden, zufällig. Ebenso werden nachrichten, die in andere Datenströme geschrieben werden, z. B. Warnungen, ausführliche Informationen oder Informationen, in unbestimmter Reihenfolge in diese Datenströme geschrieben.

    Beim Beenden von Fehlern, z. B. Ausnahmen, werden die einzelnen parallelen instance der Skriptblöcke beendet, in denen sie auftreten. Ein Abbruchfehler in einem Skriptblock führt möglicherweise nicht zum Beenden des Foreach-Object Cmdlets. Die anderen skriptblocks, die parallel ausgeführt werden, werden weiterhin ausgeführt, es sei denn, es tritt ebenfalls ein Abbruchfehler auf. Der Abbruchfehler wird als ErrorRecord mit einer FullyQualifiedErrorId von PSTaskExceptionin den Fehlerdatenstrom geschrieben. Abbruchfehler können mithilfe von PowerShell-Try/Catch- oder Trap-Blöcken in Fehler ohne Abbruch konvertiert werden.

  • Allgemeine Parametervariable-Variablen von PipelineVariable werden in parallelen Szenarien auch mit dem $using: Schlüsselwort (keyword) nicht unterstützt.

    Wichtig

    Der ForEach-Object -Parallel Parametersatz führt Skriptblöcke parallel für separate Prozessthreads aus. Die $using: Schlüsselwort (keyword) ermöglicht das Übergeben von Variablenverweise vom Cmdletaufrufthread an jeden ausgeführten Skriptblockthread. Da die Skriptblöcke in verschiedenen Threads ausgeführt werden, müssen die als Verweis übergebenen Objektvariablen sicher verwendet werden. Im Allgemeinen ist es sicher, aus Objekten zu lesen, auf die verwiesen wird, die sich nicht ändern. Wenn der Objektzustand jedoch geändert wird, müssen Sie threadsichere Objekte wie .NET System.Collection.Concurrent-Typen verwenden (siehe Beispiel 11).