Delen via


ForEach-Object

Voert een bewerking uit op elk item in een verzameling invoerobjecten.

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

De ForEach-Object cmdlet voert een bewerking uit op elk item in een verzameling invoerobjecten. De invoerobjecten kunnen worden doorgesluisd naar de cmdlet of worden opgegeven met behulp van de parameter InputObject .

Vanaf Windows PowerShell 3.0 zijn er twee verschillende manieren om een ForEach-Object opdracht te maken.

  • Scriptblok. U kunt een scriptblok gebruiken om de bewerking op te geven. Gebruik in het scriptblok de $_ variabele om het huidige object weer te geven. Het scriptblok is de waarde van de parameter Process . Het scriptblok kan elk PowerShell-script bevatten.

    Met de volgende opdracht wordt bijvoorbeeld de waarde opgehaald van de eigenschap ProcessName van elk proces op de computer.

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

    ForEach-Object ondersteunt de beginblokken , processen end , zoals beschreven in about_functions.

    Notitie

    De scriptblokken worden uitgevoerd in het bereik van de aanroeper. Daarom hebben de blokken toegang tot variabelen in dat bereik en kunnen nieuwe variabelen worden gemaakt die in dat bereik blijven nadat de cmdlet is voltooid.

  • Bewerkingsinstructie. U kunt ook een bewerkingsinstructie schrijven, die veel meer lijkt op natuurlijke taal. U kunt de bewerkingsinstructie gebruiken om een eigenschapswaarde op te geven of een methode aan te roepen. Bewerkingsinstructies zijn geïntroduceerd in Windows PowerShell 3.0.

    Met de volgende opdracht wordt bijvoorbeeld ook de waarde opgehaald van de eigenschap ProcessName van elk proces op de computer.

    Get-Process | ForEach-Object ProcessName

  • Parallel uitvoeren van scriptblok. Vanaf PowerShell 7.0 is er een derde parameterset beschikbaar waarmee elk scriptblok parallel wordt uitgevoerd. De parameter ThrottleLimit beperkt het aantal parallelle scripts dat tegelijk wordt uitgevoerd. Gebruik net als voorheen de $_ variabele om het huidige invoerobject in het scriptblok weer te geven. Gebruik het $using: trefwoord om variabeleverwijzingen door te geven naar het actieve script.

    In PowerShell 7 wordt voor elke lus-iteratie een nieuwe runspace gemaakt om maximale isolatie te garanderen. Dit kan een grote prestatie- en resourceslag zijn als het werk dat u doet klein is in vergelijking met het maken van nieuwe runspaces of als er veel iteraties zijn die aanzienlijk werk uitvoeren. Vanaf PowerShell 7.1 worden runspaces uit een runspace-pool standaard opnieuw gebruikt. De grootte van de runspace-pool wordt opgegeven door de parameter ThrottleLimit . De standaardgrootte van runspace-pools is 5. U kunt nog steeds een nieuwe runspace maken voor elke iteratie met behulp van de switch UseNewRunspace .

    Standaard gebruiken de parallelle scriptblokkeringen de huidige werkmap van de aanroeper die de parallelle taken heeft gestart.

    Zie de sectie NOTITIES van dit artikel voor meer informatie.

Voorbeelden

Voorbeeld 1: gehele getallen in een matrix delen

In dit voorbeeld wordt een matrix van drie gehele getallen gebruikt en deze allemaal door 1024 gedeeld.

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

29.296875
55.466796875
12.140625

Voorbeeld 2: de lengte van alle bestanden in een map ophalen

In dit voorbeeld worden de bestanden en mappen in de PowerShell-installatiemap verwerkt $PSHOME.

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

Als het object geen map is, krijgt het scriptblok de naam van het bestand, wordt de waarde van de eigenschap Length door 1024 gedeeld en wordt een spatie (" ") toegevoegd om het te scheiden van de volgende vermelding. De cmdlet gebruikt de eigenschap PSISContainer om te bepalen of een object een map is.

Voorbeeld 3: Werken met de meest recente systeemevenementen

In dit voorbeeld worden de 1000 meest recente gebeurtenissen uit het systeemlogboek naar een tekstbestand geschreven. De huidige tijd wordt weergegeven voor en na het verwerken van de gebeurtenissen.

$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 haalt de 1000 meest recente gebeurtenissen op uit het systeemlogboek en slaat deze op in de $Events variabele. $Events wordt vervolgens doorgesluisd naar de ForEach-Object cmdlet. De parameter Begin geeft de huidige datum en tijd weer. Vervolgens gebruikt de parameter Proces de Out-File cmdlet om een tekstbestand te maken met de naam events.txt en slaat de berichteigenschap van elk van de gebeurtenissen in dat bestand op. Ten slotte wordt de parameter End gebruikt om de datum en tijd weer te geven nadat alle verwerkingen zijn voltooid.

Voorbeeld 4: de waarde van een registersleutel wijzigen

In dit voorbeeld wordt de waarde van de registervermelding RemotePath in alle subsleutels onder de HKCU:\Network sleutel gewijzigd in hoofdletters.

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

U kunt deze indeling gebruiken om het formulier of de inhoud van een registervermeldingswaarde te wijzigen.

Elke subsleutel in de netwerksleutel vertegenwoordigt een toegewezen netwerkstation dat opnieuw verbinding maakt bij het aanmelden. De RemotePath-vermelding bevat het UNC-pad van het verbonden station. Als u bijvoorbeeld het station E: toe wijst aan \\Server\Share, wordt er een E-subsleutel gemaakt in HKCU:\Network met de registerwaarde RemotePath ingesteld op \\Server\Share.

De opdracht gebruikt de Get-ItemProperty cmdlet om alle subsleutels van de netwerksleutel en de Set-ItemProperty cmdlet op te halen om de waarde van de registervermelding RemotePath in elke sleutel te wijzigen. In de Set-ItemProperty opdracht is het pad de waarde van de eigenschap PSPath van de registersleutel. Dit is een eigenschap van het Microsoft .NET Framework-object dat de registersleutel vertegenwoordigt, niet een registervermelding. De opdracht maakt gebruik van de methode ToUpper() van de RemotePath-waarde , een tekenreeks (REG_SZ).

Omdat Set-ItemProperty de eigenschap van elke sleutel wordt gewijzigd, is de ForEach-Object cmdlet vereist voor toegang tot de eigenschap.

Voorbeeld 5: de $Null automatische variabele gebruiken

In dit voorbeeld ziet u het effect van het doorspitten van de $Null automatische variabele naar de ForEach-Object cmdlet.

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

Hello
Hello
Hello
Hello

Omdat in PowerShell null als een expliciete tijdelijke aanduiding wordt behandeld, genereert de ForEach-Object cmdlet een waarde voor $Null, net als voor andere objecten die u doorgeeft.

Voorbeeld 6: eigenschapswaarden ophalen

In dit voorbeeld wordt de waarde van de eigenschap Path van alle geïnstalleerde PowerShell-modules opgehaald met behulp van de parameter MemberName van de ForEach-Object cmdlet.

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

De tweede opdracht is gelijk aan de eerste. Hierbij wordt de Foreach alias van de ForEach-Object cmdlet gebruikt en wordt de naam van de parameter MemberName weggelaten, wat optioneel is.

De ForEach-Object cmdlet is handig voor het ophalen van eigenschapswaarden, omdat de waarde wordt opgehaald zonder het type te wijzigen, in tegenstelling tot de cmdlets format of de Select-Object cmdlet, die het type eigenschapswaarde wijzigen.

Voorbeeld 7: modulenamen splitsen in onderdeelnamen

In dit voorbeeld ziet u drie manieren om twee door puntjes gescheiden modulenamen te splitsen in hun onderdeelnamen. De opdrachten roepen de splitsmethode van tekenreeksen aan. De drie opdrachten gebruiken verschillende syntaxis, maar ze zijn gelijkwaardig en uitwisselbaar. De uitvoer is hetzelfde voor alle drie de gevallen.

"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

De eerste opdracht maakt gebruik van de traditionele syntaxis, die een scriptblok en de huidige objectoperator $_bevat. De syntaxis van de punt wordt gebruikt om de methode en haakjes op te geven om het argument scheidingsteken in te sluiten.

De tweede opdracht gebruikt de parameter MemberName om de splitsmethode en de parameter ArgumentList op te geven om de punt (.) te identificeren als het splitsscheidingsteken.

De derde opdracht maakt gebruik van de Foreach-alias van de ForEach-Object cmdlet en laat de namen van de parameters MemberName en ArgumentList weg, die optioneel zijn.

Voorbeeld 8: ForEach-Object gebruiken met twee scriptblokken

In dit voorbeeld geven we twee scriptblokken positioneel door. Alle scriptblokken zijn gebonden aan de parameter Process . Ze worden echter behandeld alsof ze zijn doorgegeven aan de parameters Begin en Proces .

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

begin
process
process

Voorbeeld 9: ForEach-Object gebruiken met meer dan twee scriptblokken

In dit voorbeeld geven we twee scriptblokken positioneel door. Alle scriptblokken zijn gebonden aan de parameter Process . Ze worden echter behandeld alsof ze zijn doorgegeven aan de parameters Begin, Proces en Einde .

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

begin
process A
process B
process A
process B
end

Notitie

Het eerste scriptblok wordt altijd toegewezen aan het begin blok, het laatste blok wordt toegewezen aan het end blok en de blokken ertussen worden allemaal toegewezen aan het process blok.

Voorbeeld 10: meerdere scriptblokken uitvoeren voor elk pijplijnitem

Zoals weergegeven in het vorige voorbeeld, worden meerdere scriptblokken die zijn doorgegeven met behulp van de parameter Process , toegewezen aan de parameters Begin en Einde . Om deze toewijzing te voorkomen, moet u expliciete waarden opgeven voor de parameters Begin en Einde .

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

one
two
three
one
two
three

Voorbeeld 11: Traag script uitvoeren in parallelle batches

In dit voorbeeld wordt een eenvoudig scriptblok uitgevoerd dat een tekenreeks evalueert en één seconde slaapstanden uitvoert.

$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

De parameterwaarde ThrottleLimit is ingesteld op 4, zodat de invoer wordt verwerkt in batches van vier. Het $using: trefwoord wordt gebruikt om de $Message variabele door te geven aan elk parallel scriptblok.

Voorbeeld 12: logboekvermeldingen parallel ophalen

In dit voorbeeld worden 50.000 logboekvermeldingen opgehaald uit 5 systeemlogboeken op een lokale Windows-computer.

$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

De parameter Parallel geeft het scriptblok op dat parallel wordt uitgevoerd voor elke naam van het invoerlogboek. De parameter ThrottleLimit zorgt ervoor dat alle vijf de scriptblokken tegelijkertijd worden uitgevoerd.

Voorbeeld 13: Parallel uitvoeren als een taak

In dit voorbeeld wordt een eenvoudig scriptblok parallel uitgevoerd, waarbij twee achtergrondtaken tegelijk worden gemaakt.

$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

de $job variabele ontvangt het taakobject dat uitvoergegevens verzamelt en de status van de uitvoering bewaakt. Het taakobject wordt doorgesluisd naar Receive-Job met de parameter Wachtschakelaar . En deze streamt de uitvoer naar de console, alsof ForEach-Object -Parallel het zonder AsJob wordt uitgevoerd.

Voorbeeld 14: Thread Veilige variabeleverwijzingen gebruiken

In dit voorbeeld worden scriptblokken parallel aangeroepen om procesobjecten met een unieke naam te verzamelen.

$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

Er wordt één exemplaar van een ConcurrentDictionary-object doorgegeven aan elk scriptblok om de objecten te verzamelen. Omdat de ConcurrentDictionary thread-veilig is, is het veilig om te worden gewijzigd door elk parallel script. Een niet-thread-veilig object, zoals System.Collections.Generic.Dictionary, zou hier niet veilig kunnen worden gebruikt.

Notitie

Dit voorbeeld is een zeer inefficiënt gebruik van de parameter Parallel . Het script voegt het invoerobject gewoon toe aan een gelijktijdig woordenboekobject. Het is triviaal en de overhead van het aanroepen van elk script in een afzonderlijke thread niet waard. Normaal werken ForEach-Object zonder de Parallelle schakelaar is veel efficiënter en sneller. Dit voorbeeld is alleen bedoeld om te laten zien hoe u thread-veilige variabelen gebruikt.

Voorbeeld 15: Schrijffouten met parallelle uitvoering

In dit voorbeeld wordt parallel naar de foutenstroom geschreven, waarbij de volgorde van de geschreven fouten willekeurig is.

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

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

Voorbeeld 16: Afsluitfouten bij parallelle uitvoering

In dit voorbeeld ziet u een afsluitfout in één parallel uitgevoerd scriptblock.

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 is nooit geschreven omdat het parallelle scriptblok voor die iteratie is beëindigd.

Notitie

PipelineVariable algemene parametervariabelen worden niet ondersteund in Foreach-Object -Parallel scenario's, zelfs niet met het $using: trefwoord.

Voorbeeld 17: Variabelen doorgeven in geneste parallelle script ScriptBlockSet

U kunt een variabele buiten een Foreach-Object -Parallel scoped scriptblock maken en deze binnen het scriptblock gebruiken met het $using sleutelwoord.

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

Het geneste scriptblock heeft geen toegang tot de $test2 variabele en er wordt een fout gegenereerd.

Parameters

-ArgumentList

Hiermee geeft u een matrix van argumenten voor een methodeaanroep. Zie about_Splatting voor meer informatie over het gedrag van ArgumentList.

Deze parameter is geïntroduceerd in Windows PowerShell 3.0.

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

-AsJob

Zorgt ervoor dat de parallelle aanroep wordt uitgevoerd als een PowerShell-taak. Er wordt één taakobject geretourneerd in plaats van uitvoer van de actieve scriptblokken. Het taakobject bevat onderliggende taken voor elk parallel scriptblok dat wordt uitgevoerd. Het taakobject kan worden gebruikt door alle PowerShell-taak-cmdlets om de actieve status te controleren en gegevens op te halen.

Deze parameter is geïntroduceerd in PowerShell 7.0.

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

-Begin

Hiermee geeft u een scriptblok op dat wordt uitgevoerd voordat deze cmdlet invoerobjecten verwerkt. Dit scriptblok wordt slechts eenmaal uitgevoerd voor de hele pijplijn. Zie about_Functions voor meer informatie over het beginblok.

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

-Confirm

Hiermee wordt u gevraagd om bevestiging voordat u de cmdlet uitvoert.

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

-End

Hiermee geeft u een scriptblok op dat wordt uitgevoerd nadat deze cmdlet alle invoerobjecten verwerkt. Dit scriptblok wordt slechts eenmaal uitgevoerd voor de hele pijplijn. Zie about_Functions voor meer informatie over het endblok.

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

-InputObject

Hiermee geeft u de invoerobjecten op. ForEach-Object voert het scriptblok of de bewerkingsinstructie uit op elk invoerobject. Voer een variabele in die de objecten bevat of typ een opdracht of expressie waarmee de objecten worden opgehaald.

Wanneer u de parameter InputObject gebruikt met ForEach-Object, in plaats van de opdrachtresultaten door te sturen naar ForEach-Object, wordt de waarde InputObject behandeld als één object. Dit geldt zelfs als de waarde een verzameling is die het resultaat is van een opdracht, zoals -InputObject (Get-Process). Omdat InputObject geen afzonderlijke eigenschappen van een matrix of verzameling objecten kan retourneren, raden we u ForEach-Object aan om bewerkingen uit te voeren op een verzameling objecten voor objecten die specifieke waarden in gedefinieerde eigenschappen hebben, ForEach-Object in de pijplijn, zoals wordt weergegeven in de voorbeelden in dit onderwerp.

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

-MemberName

Hiermee geeft u de eigenschap om op te halen of de methode om aan te roepen.

Jokertekens zijn toegestaan, maar werken alleen als de resulterende tekenreeks wordt omgezet in een unieke waarde. Als u bijvoorbeeld uitvoert Get-Process | ForEach -MemberName *Name, komt het jokertekenpatroon overeen met meer dan één lid, waardoor de opdracht mislukt.

Deze parameter is geïntroduceerd in Windows PowerShell 3.0.

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

-Parallel

Hiermee geeft u het scriptblok dat moet worden gebruikt voor parallelle verwerking van invoerobjecten. Voer een scriptblok in dat de bewerking beschrijft.

Deze parameter is geïntroduceerd in PowerShell 7.0.

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

-Process

Hiermee geeft u de bewerking op die wordt uitgevoerd op elk invoerobject. Dit scriptblok wordt uitgevoerd voor elk object in de pijplijn. Zie about_Functions voor meer informatie over het processblok.

Wanneer u meerdere scriptblokken opgeeft aan de parameter Process , wordt het eerste scriptblok altijd toegewezen aan het begin blok. Als er slechts twee scriptblokken zijn, wordt het tweede blok toegewezen aan het process blok. Als er drie of meer scriptblokken zijn, wordt het eerste scriptblok altijd toegewezen aan het begin blok, wordt het laatste blok toegewezen aan het end blok en worden de blokken ertussen allemaal toegewezen aan het process blok.

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

-RemainingScripts

Hiermee geeft u alle scriptblokken die niet worden gebruikt door de procesparameter .

Deze parameter is geïntroduceerd in Windows PowerShell 3.0.

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

-ThrottleLimit

Hiermee geeft u het aantal scriptblokken op dat parallel wordt uitgevoerd. Invoerobjecten worden geblokkeerd totdat het aantal actieve scriptblokken onder de ThrottleLimit komt. De standaardwaarde is 5.

Deze parameter is geïntroduceerd in PowerShell 7.0.

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

-TimeoutSeconds

Hiermee geeft u het aantal seconden op dat moet worden gewacht totdat alle invoer parallel wordt verwerkt. Na de opgegeven time-out worden alle actieve scripts gestopt. En alle resterende invoerobjecten die moeten worden verwerkt, worden genegeerd. De standaardwaarde van 0 schakelt de time-out uit en ForEach-Object -Parallel kan voor onbepaalde tijd worden uitgevoerd. Als u Ctrl+C op de opdrachtregel typt, wordt een actieve opdracht gestopt ForEach-Object -Parallel . Deze parameter kan niet samen met de asjob-parameter worden gebruikt.

Deze parameter is geïntroduceerd in PowerShell 7.0.

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

-UseNewRunspace

Zorgt ervoor dat de parallelle aanroep een nieuwe runspace maakt voor elke lus-iteratie in plaats van runspaces uit de runspace-pool opnieuw te gebruiken.

Deze parameter is geïntroduceerd in PowerShell 7.1

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

-WhatIf

Hiermee wordt weergegeven wat er zou gebeuren als u de cmdlet uitvoert. De cmdlet wordt niet uitgevoerd.

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

Invoerwaarden

PSObject

U kunt elk object doorsnijden naar deze cmdlet.

Uitvoerwaarden

PSObject

Deze cmdlet retourneert objecten die worden bepaald door de invoer.

Notities

De ForEach-Object cmdlet werkt vergelijkbaar met de Foreach-instructie , behalve dat u invoer niet kunt doorspeinzen naar een Foreach-instructie . Zie about_Foreach voor meer informatie over de Foreach-instructie.

Vanaf PowerShell 4.0 zijn WhereForEach methoden toegevoegd voor gebruik met verzamelingen. Meer informatie over deze nieuwe methoden vindt u hier about_arrays

Met behulp van ForEach-Object -Parallel:

  • De ForEach-Object -Parallel parameterset maakt gebruik van de interne API van PowerShell om elk scriptblok in een nieuwe runspace uit te voeren. Dit is aanzienlijk meer overhead dan normaal wordt uitgevoerd ForEach-Object met sequentiële verwerking. Het is belangrijk om Parallel te gebruiken wanneer de overhead van het parallel uitvoeren klein is in vergelijking met het werk dat het scriptblok uitvoert. Bijvoorbeeld:

    • Rekenintensieve scripts op computers met meerdere kernen
    • Scripts die tijd besteden aan het wachten op resultaten of het uitvoeren van bestandsbewerkingen

    Het gebruik van de parameter Parallel kan ertoe leiden dat scripts veel langzamer worden uitgevoerd dan normaal. Vooral als de parallelle scripts triviaal zijn. Experimenteer met Parallel om te ontdekken waar dit nuttig kan zijn.

  • Wanneer objecten parallel worden uitgevoerd, kan niet worden gegarandeerd dat objecten die zijn ingericht met ScriptProperties of ScriptMethods correct werken als ze worden uitgevoerd in een andere runspace dan de scripts die er oorspronkelijk aan zijn gekoppeld.

    Scriptblock-aanroep probeert altijd uit te voeren in de eigen runspace, ongeacht waar deze daadwerkelijk wordt aangeroepen. Maakt echter ForEach-Object -Parallel tijdelijke runspaces die na gebruik worden verwijderd, zodat er geen runspace meer is voor de scripts om in uit te voeren.

    Dit gedrag kan werken zolang de homerunspace nog bestaat. Mogelijk krijgt u echter niet het gewenste resultaat als het script afhankelijk is van externe variabelen die alleen aanwezig zijn in de runspace van de aanroeper en niet de startrunspace .

  • Niet-afsluitfouten worden naar de cmdlet-foutstroom geschreven als ze optreden in parallel uitgevoerde scriptblokken. Omdat parallelle uitvoeringsvolgorde van scriptblock niet-deterministisch is, is de volgorde waarin fouten worden weergegeven in de foutenstroom willekeurig. Op dezelfde manier worden berichten die naar andere gegevensstromen zijn geschreven, zoals waarschuwing, uitgebreide of informatie, in onbepaalde volgorde naar die gegevensstromen geschreven.

    Afsluitfouten, zoals uitzonderingen, beëindigen het afzonderlijke parallelle exemplaar van de scriptblokken waarin ze optreden. Een afsluitfout in één scriptblok kan de beëindiging van de Foreach-Object cmdlet niet veroorzaken. De andere scriptblokken, die parallel worden uitgevoerd, blijven worden uitgevoerd, tenzij er ook een afsluitfout optreedt. De afsluitfout wordt naar de foutgegevensstroom geschreven als een ErrorRecord met een FullyQualifiedErrorId van PSTaskException. Afsluitfouten kunnen worden geconverteerd naar niet-afsluitfouten met behulp van PowerShell try/catch- of trapblokken.

  • PipelineVariable algemene parametervariabelen worden niet ondersteund in parallelle scenario's, zelfs niet met het $using: trefwoord.

    Belangrijk

    De ForEach-Object -Parallel parameterset voert scriptblokken parallel uit op afzonderlijke procesthreads. Met $using: het trefwoord kunnen variabele verwijzingen van de cmdlet-aanroepthread worden doorgegeven aan elke actieve scriptblokthread. Omdat de scriptblokken in verschillende threads worden uitgevoerd, moeten de objectvariabelen die worden doorgegeven door verwijzing veilig worden gebruikt. Over het algemeen is het veilig om objecten te lezen waarnaar wordt verwezen die niet worden gewijzigd. Maar als de objectstatus wordt gewijzigd, moet u veilige threadobjecten gebruiken, zoals .NET System.Collection.Concurrent-typen (zie voorbeeld 11).