ForEach-Object
Voert een bewerking uit op elk item in een verzameling invoerobjecten.
Syntaxis
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
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 procesparameter . 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 debegin
,process
enend
blokken zoals beschreven in about_functions.Notitie
De scriptblokken worden uitgevoerd in het bereik van de aanroeper. De blokken hebben daarom toegang tot variabelen in dat bereik en kunnen nieuwe variabelen maken die in dat bereik blijven bestaan nadat de cmdlet is voltooid.
Bewerkingsinstructie. U kunt ook een bewerkingsinstructie schrijven, wat 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. Net als voorheen gebruikt u de
$_
variabele om het huidige invoerobject in het scriptblok weer te geven. Gebruik het$using:
trefwoord om variabele verwijzingen door te geven naar het actieve script.In PowerShell 7 wordt voor elke lusiteratie een nieuwe runspace gemaakt om maximale isolatie te garanderen. Dit kan een grote prestaties zijn en resources worden bereikt als het werk dat u uitvoert 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. Met de parameter ThrottleLimit wordt de grootte van de runspace-pool ingesteld. De standaardgrootte van de runspace-pool is 5. U kunt nog steeds een nieuwe runspace maken voor elke iteratie met behulp van de UseNewRunspace-switch .
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 worden ze allemaal gedeeld door 1024.
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 Installatiemap $PSHOME
van PowerShell verwerkt.
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, deelt u de waarde van de eigenschap Length door 1024 en voegt u een spatie (" ") toe om deze te scheiden van de volgende vermelding. De cmdlet gebruikt de eigenschap PSISContainer om te bepalen of een object een map is.
Voorbeeld 3: Werken op de meest recente systeem gebeurtenissen
In dit voorbeeld worden de 1000 meest recente gebeurtenissen uit het gebeurtenislogboek van het systeem naar een tekstbestand geschreven. De huidige tijd wordt weergegeven voor en na het verwerken van de gebeurtenissen.
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
haalt de 1000 meest recente gebeurtenissen op uit het gebeurtenislogboek van het systeem en pijpt deze 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 Einde gebruikt om de datum en tijd weer te geven nadat alle verwerking is voltooid.
Voorbeeld 4: De waarde van een registersleutel wijzigen
In dit voorbeeld wordt de waarde van de registervermelding RemotePath gewijzigd in alle subsleutels onder de HKCU:\Network
sleutel 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 aanmelding. De RemotePath-vermelding bevat het UNC-pad van het verbonden station. Als u het E:
station bijvoorbeeld toe wijst, wordt er een E-subsleutel gemaakt HKCU:\Network
waarin de registerwaarde RemotePath is ingesteld op \\Server\Share
\\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 RemotePath-registervermelding in elke sleutel te wijzigen. In de Set-ItemProperty
opdracht is het pad de waarde van de PSPath-eigenschap 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 . Dit is 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 automatische variabele $null gebruiken
In dit voorbeeld ziet u het effect van het doorsluisen van de $null
automatische variabele naar de ForEach-Object
cmdlet.
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
Omdat PowerShell als een expliciete tijdelijke aanduiding wordt behandeld $null
, genereert de ForEach-Object
cmdlet een waarde voor $null
net als voor andere objecten die eraan worden doorgesluisd.
Voorbeeld 6: Eigenschapswaarden ophalen
In dit voorbeeld wordt de waarde opgehaald van de eigenschap Path van alle geïnstalleerde PowerShell-modules 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. Dit is optioneel.
De ForEach-Object
cmdlet is handig voor het ophalen van eigenschapswaarden, omdat deze de waarde krijgt zonder het type te wijzigen, in tegenstelling tot de indelings-cmdlets of de Select-Object
cmdlet, die het eigenschapswaardetype 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. Met de opdrachten wordt de splitsmethode van tekenreeksen aangeroepen. 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. Hierbij wordt de syntaxis van de punt gebruikt om de methode en haakjes op te geven om het scheidingstekenargument 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 scheidingsteken voor splitsen.
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 binden aan de procesparameter . 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 vier scriptblokken positioneel door. Alle scriptblokken binden aan de procesparameter . Ze worden echter behandeld alsof ze zijn doorgegeven aan de parameters Begin, Proces en Eind .
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 twee middelste blokken worden toegewezen aan het process
blok.
Voorbeeld 10: Meerdere scriptblokken uitvoeren voor elk pijplijnitem
Zoals in het vorige voorbeeld wordt weergegeven, worden meerdere scriptblokken doorgegeven met behulp van de procesparameter toegewezen aan de begin- en eindparameters. Om deze toewijzing te voorkomen, moet u expliciete waarden opgeven voor de begin- en eindparameters.
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 scriptblok uitgevoerd waarmee een tekenreeks en slaapstand voor één seconde worden geëvalueerd.
$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 in batches van vier wordt verwerkt.
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
Met de parameter Parallel geeft u het scriptblok op dat parallel wordt uitgevoerd voor elke naam van het invoerlogboek. De parameter ThrottleLimit zorgt ervoor dat alle vijf scriptblokken tegelijkertijd worden uitgevoerd.
Voorbeeld 13: Parallel uitvoeren als een taak
In dit voorbeeld wordt een taak gemaakt waarmee een scriptblok parallel, twee tegelijk, wordt uitgevoerd.
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 …
De parameter ThrottleLimit beperkt het aantal parallelle scriptblokken dat tegelijk wordt uitgevoerd. De parameter AsJob zorgt ervoor dat de ForEach-Object
cmdlet een taakobject retourneert in plaats van streaming-uitvoer naar de console. De $job
variabele ontvangt het taakobject dat uitvoergegevens verzamelt en de status Van uitvoering bewaakt. De $job.ChildJobs
eigenschap bevat de onderliggende taken die de parallelle scriptblokken uitvoeren.
Voorbeeld 14: thread veilige variabeleverwijzingen gebruiken
In dit voorbeeld worden scriptblokken parallel aangeroepen om unieke procesobjecten 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
Eén exemplaar van een ConcurrentDictionary-object wordt 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, is hier niet veilig te gebruiken.
Notitie
Dit voorbeeld is een inefficiënt gebruik van de parameter Parallel . Het script voegt het invoerobject toe aan een gelijktijdig woordenlijstobject. Het is triviaal en niet de moeite waard om elk script in een afzonderlijke thread aan te roepen. Het uitvoeren ForEach-Object
zonder de parallelle switch is efficiënter en sneller. Dit voorbeeld is alleen bedoeld om te laten zien hoe u threadveilige variabelen gebruikt.
Voorbeeld 15: Schrijffouten met parallelle uitvoering
In dit voorbeeld wordt parallel naar de foutstroom geschreven, waarbij de volgorde van 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 scriptblok.
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
wordt nooit geschreven omdat de parallelle scriptblokkering voor die iteratie is beëindigd.
Notitie
Algemene parametervariabelen pipelineVariable 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 maken buiten een Foreach-Object -Parallel
scriptblok met een bereik en deze gebruiken in het scriptblok met het $using
trefwoord.
$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.
De geneste scriptblokkering heeft geen toegang tot de $test2
variabele en er wordt een fout gegenereerd.
Voorbeeld 18: Meerdere taken maken die scripts parallel uitvoeren
De parameter ThrottleLimit beperkt het aantal parallelle scripts dat wordt uitgevoerd tijdens elk exemplaar van ForEach-Object -Parallel
. Er wordt geen limiet ingesteld voor het aantal taken dat kan worden gemaakt bij het gebruik van de astaakparameter . Omdat taken zelf gelijktijdig worden uitgevoerd, is het mogelijk om meerdere parallelle taken te maken, die elk worden uitgevoerd tot het limietaantal gelijktijdige scriptblokkeringen.
$jobs = for ($i=0; $i -lt 10; $i++) {
1..10 | ForEach-Object -Parallel {
./RunMyScript.ps1
} -AsJob -ThrottleLimit 5
}
$jobs | Receive-Job -Wait
In dit voorbeeld worden 10 actieve taken gemaakt. Elke taak voert niet meer dan 5 scripts tegelijk uit. Het totale aantal exemplaren dat gelijktijdig wordt uitgevoerd, is beperkt tot 50 (10 taken keer het ThrottleLimit van 5).
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[] |
Aliassen: | Args |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | 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. U kunt het taakobject gebruiken met een van de PowerShell-taak-cmdlets om de actieve status te zien en gegevens op te halen.
Deze parameter is geïntroduceerd in PowerShell 7.0.
Type: | SwitchParameter |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | 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 begin
blok.
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-Confirm
Hiermee wordt u gevraagd om bevestiging voordat u de cmdlet uitvoert.
Type: | SwitchParameter |
Aliassen: | cf |
Position: | Named |
Default value: | False |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | 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 end
blok.
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-InputObject
Hiermee geeft u de invoerobjecten. 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 resultaten van de opdracht ForEach-Object
piping, 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 kan retourneren uit een matrix of verzameling objecten, raden we u ForEach-Object
aan om bewerkingen uit te voeren op een verzameling objecten voor die objecten met specifieke waarden in gedefinieerde eigenschappen, die u in de pijplijn gebruikt ForEach-Object
, zoals wordt weergegeven in de voorbeelden in dit onderwerp.
Type: | PSObject |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | True |
Jokertekens accepteren: | False |
-MemberName
Hiermee geeft u de naam van de lideigenschap op om op te halen of de lidmethode die moet worden aangeroepen. De leden moeten exemplaarleden zijn, niet statische leden.
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 |
Vereist: | True |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | True |
-Parallel
Hiermee geeft u het scriptblok moet worden gebruikt voor parallelle verwerking van invoerobjecten. Voer een scriptblok in waarmee de bewerking wordt beschreven.
Deze parameter is geïntroduceerd in PowerShell 7.0.
Type: | ScriptBlock |
Position: | Named |
Default value: | None |
Vereist: | True |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-Process
Hiermee geeft u de bewerking die wordt uitgevoerd op elk invoerobject. Dit scriptblok wordt uitgevoerd voor elk object in de pijplijn. Zie about_Functions voor meer informatie over het process
blok.
Wanneer u meerdere scriptblokken opgeeft aan de procesparameter , 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 middelste blokken toegewezen aan het process
blok.
Type: | ScriptBlock[] |
Position: | 0 |
Default value: | None |
Vereist: | True |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-RemainingScripts
Hiermee geeft u alle scriptblokken op die niet worden gebruikt door de parameter Proces .
Deze parameter is geïntroduceerd in Windows PowerShell 3.0.
Type: | ScriptBlock[] |
Position: | Named |
Default value: | None |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-ThrottleLimit
Hiermee geeft u het aantal scriptblokken op dat parallel wordt uitgevoerd. Invoerobjecten worden geblokkeerd totdat het aantal actieve scriptblokken onder het ThrottleLimit valt. De standaardwaarde is 5
.
De parameter ThrottleLimit beperkt het aantal parallelle scripts dat wordt uitgevoerd tijdens elk exemplaar van ForEach-Object -Parallel
. Er wordt geen limiet ingesteld voor het aantal taken dat kan worden gemaakt bij het gebruik van de astaakparameter . Omdat taken zelf gelijktijdig worden uitgevoerd, is het mogelijk om een aantal parallelle taken te maken, die elk worden uitgevoerd tot het beperkingslimietaantal gelijktijdige scriptblokkeringen.
Deze parameter is geïntroduceerd in PowerShell 7.0.
Type: | Int32 |
Position: | Named |
Default value: | 5 |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-TimeoutSeconds
Hiermee geeft u het aantal seconden op dat moet worden gewacht totdat alle invoer parallel wordt verwerkt. Na de opgegeven time-outtijd worden alle actieve scripts gestopt. En alle resterende invoerobjecten die moeten worden verwerkt, worden genegeerd. De standaardwaarde voor het uitschakelen van 0
de time-out 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 |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-UseNewRunspace
Zorgt ervoor dat de parallelle aanroep een nieuwe runspace maakt voor elke herhaling van een lus in plaats van runspaces opnieuw te gebruiken vanuit de runspace-pool.
Deze parameter is geïntroduceerd in PowerShell 7.1
Type: | SwitchParameter |
Position: | Named |
Default value: | False |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
-WhatIf
Hiermee wordt weergegeven wat er zou gebeuren als u de cmdlet uitvoert. De cmdlet wordt niet uitgevoerd.
Type: | SwitchParameter |
Aliassen: | wi |
Position: | Named |
Default value: | False |
Vereist: | False |
Pijplijninvoer accepteren: | False |
Jokertekens accepteren: | False |
Invoerwaarden
U kunt elk object doorsluisen naar deze cmdlet.
Uitvoerwaarden
Met deze cmdlet worden objecten geretourneerd die worden bepaald door de invoer.
Notities
PowerShell bevat de volgende aliassen voor ForEach-Object
:
- Alle platforms:
%
foreach
De ForEach-Object
cmdlet werkt net als de Foreach-instructie , behalve dat u geen invoer kunt doorsluisen naar een Foreach-instructie . Zie about_Foreach voor meer informatie over de Foreach-instructie.
Vanaf PowerShell 4.0 Where
ForEach
zijn methoden toegevoegd voor gebruik met verzamelingen. Meer informatie over deze nieuwe methoden vindt u hier about_arrays
Met behulp van ForEach-Object -Parallel
:
ForEach-Object -Parallel
voert elk scriptblok uit in een nieuwe runspace. De nieuwe runspaces zorgen voor aanzienlijk meer overhead dan het uitvoerenForEach-Object
met sequentiële verwerking. Het is belangrijk om Parallel te gebruiken, waarbij de overhead van parallel uitvoeren klein is in vergelijking met het werk dat het scriptblok uitvoert. Voorbeeld:- Rekenintensieve scripts op machines met meerdere kernen
- Scripts die tijd besteden aan het wachten op resultaten of het uitvoeren van bestandsbewerkingen
Als u de parameter Parallel gebruikt, kunnen scripts veel langzamer worden uitgevoerd dan normaal. Vooral als de parallelle scripts triviaal zijn. Experimenteer met Parallel om te ontdekken waar het nuttig kan zijn.
Wanneer objecten parallel worden uitgevoerd, kunnen objecten die zijn ingericht met ScriptProperties of ScriptMethods , niet correct functioneren als ze worden uitgevoerd in een andere runspace dan de scripts zijn gekoppeld.
Scriptblock-aanroep probeert altijd te worden uitgevoerd in de eigen runspace, ongeacht waar deze daadwerkelijk wordt aangeroepen.
ForEach-Object -Parallel
Maakt echter tijdelijke runspaces die na gebruik worden verwijderd, dus er is geen runspace meer voor de scripts die moeten worden uitgevoerd.Dit gedrag kan werken zolang de home runspace nog bestaat. Het is echter mogelijk dat u het gewenste resultaat niet krijgt als het script afhankelijk is van externe variabelen die alleen aanwezig zijn in de runspace van de aanroeper en niet van de startrunspace .
Niet-afsluitfouten worden naar de cmdlet-foutstroom geschreven wanneer deze optreden in parallelle actieve scriptblokkeringen. Omdat de uitvoeringsvolgorde voor parallelle scriptblokkering niet-deterministisch is, is de volgorde waarin fouten in de foutstroom willekeurig worden weergegeven. Berichten die naar andere gegevensstromen worden geschreven, zoals waarschuwing, uitgebreid of informatie, worden in een onbepaalde volgorde naar deze gegevensstromen geschreven.
Afsluitfouten, zoals uitzonderingen, beëindigen de afzonderlijke parallelle instantie van de scriptblokkeringen waarin ze optreden. Een afsluitfout in één scriptblokkering kan de beëindiging van de
Foreach-Object
cmdlet niet veroorzaken. De andere scriptblokkeringen, die parallel worden uitgevoerd, blijven actief, tenzij er ook een afsluitfout optreedt. De afsluitfout wordt naar de foutgegevensstroom geschreven als een ErrorRecord met een FullyQualifiedErrorId vanPSTaskException
. Afsluitfouten kunnen worden geconverteerd naar niet-afsluitfouten met behulp van PowerShelltry
/catch
oftrap
blokken.Algemene parametervariabelen pipelineVariable worden niet ondersteund in parallelle scenario's, zelfs niet met het
$using:
trefwoord.Belangrijk
Met de
ForEach-Object -Parallel
parameterset worden scriptblokken parallel uitgevoerd 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 door verwijzing worden doorgegeven veilig worden gebruikt. Over het algemeen is het veilig om te lezen van objecten waarnaar wordt verwezen en die niet veranderen. Als u de objectstatus wilt wijzigen, moet u threadveilige objecten gebruiken, zoals .NET System.Collection.Concurrent-typen (zie voorbeeld 14).