Partager via


ForEach-Object

Effectue une opération sur chaque élément d'une collection d'objets d'entrée.

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
            -Parallel <scriptblock>
            [-InputObject <psobject>]
            [-ThrottleLimit <int>]
            [-TimeoutSeconds <int>]
            [-AsJob]
            [-UseNewRunspace]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

Description

L’applet ForEach-Object de commande effectue une opération sur chaque élément d’une collection d’objets d’entrée. Les objets d’entrée peuvent être dirigés vers l’applet de commande ou spécifiés à l’aide du paramètre InputObject .

À partir de Windows PowerShell 3.0, il existe deux façons différentes de construire une ForEach-Object commande.

  • Bloc de script. Vous pouvez utiliser un bloc de script pour spécifier l'opération. Dans le bloc de script, utilisez la $_ variable pour représenter l’objet actuel. Le bloc de script est la valeur du paramètre Process. Le bloc de script peut contenir n’importe quel script PowerShell.

    Par exemple, la commande suivante obtient la valeur de la propriété ProcessName de chaque processus sur l'ordinateur.

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

    ForEach-Object prend en charge les beginblocs , processet end comme décrit dans about_functions.

    Notes

    Les blocs de script s’exécutent dans l’étendue de l’appelant. Par conséquent, les blocs ont accès aux variables de cette étendue et peuvent créer de nouvelles variables qui persistent dans cette étendue une fois l’applet de commande terminée.

  • Instruction Operation. Vous pouvez également écrire une instruction d’opération, qui ressemble beaucoup plus au langage naturel. Vous pouvez utiliser l'instruction d'opération pour spécifier une valeur de propriété ou appeler une méthode. Les instructions d'opération ont été introduites dans Windows PowerShell 3.0.

    Par exemple, la commande suivante obtient également la valeur de la propriété ProcessName de chaque processus sur l'ordinateur.

    Get-Process | ForEach-Object ProcessName

  • Bloc de script en cours d’exécution parallèle. À compter de PowerShell 7.0, un troisième jeu de paramètres est disponible qui exécute chaque bloc de script en parallèle. Le paramètre ThrottleLimit limite le nombre de scripts parallèles en cours d’exécution à la fois. Comme précédemment, utilisez la $_ variable pour représenter l’objet d’entrée actuel dans le bloc de script. Utilisez le $using: mot clé pour passer des références de variable au script en cours d’exécution.

    Dans PowerShell 7, un nouvel espace d’exécution est créé pour chaque itération de boucle afin de garantir une isolation maximale. Il peut s’agir d’un impact important sur les performances et les ressources si le travail que vous effectuez est faible par rapport à la création de nouveaux espaces d’exécution ou si de nombreuses itérations effectuent un travail important. À partir de PowerShell 7.1, les runspaces d’un pool runspace sont réutilisés par défaut. Le paramètre ThrottleLimit définit la taille du pool d’espaces d’exécution. La taille du pool Runspace par défaut est 5. Vous pouvez toujours créer un runspace pour chaque itération à l’aide du commutateur UseNewRunspace .

    Par défaut, les blocs de script parallèles utilisent le répertoire de travail actuel de l’appelant qui a démarré les tâches parallèles.

    Pour plus d’informations, consultez la section NOTES de cet article.

Exemples

Exemple 1 : Diviser les entiers dans un tableau

Cet exemple prend un tableau de trois entiers et divise chacun d’eux par 1024.

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

29.296875
55.466796875
12.140625

Exemple 2 : Obtenir la longueur de tous les fichiers d’un répertoire

Cet exemple traite les fichiers et les répertoires dans le répertoire $PSHOMEd’installation de PowerShell .

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

Si l’objet n’est pas un répertoire, le bloc de script obtient le nom du fichier, divise la valeur de sa propriété Length par 1024 et ajoute un espace ( » « ) pour le séparer de l’entrée suivante. L’applet de commande utilise la propriété PSISContainer pour déterminer si un objet est un répertoire.

Exemple 3 : Utiliser les événements système les plus récents

Cet exemple écrit les 1 000 événements les plus récents du journal des événements système dans un fichier texte. L’heure actuelle s’affiche avant et après le traitement des événements.

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 obtient les 1 000 événements les plus récents du journal des événements système et les dirige vers l’applet de ForEach-Object commande. Le paramètre Begin affiche la date et l'heure actuelles. Ensuite, le paramètre Process utilise l’applet Out-File de commande pour créer un fichier texte nommé events.txt et stocke la propriété message de chacun des événements de ce fichier. Enfin, le paramètre End est utilisé pour afficher la date et l’heure une fois le traitement terminé.

Exemple 4 : Modifier la valeur d’une clé de Registre

Cet exemple montre comment modifier la valeur de l’entrée de Registre RemotePath dans toutes les sous-clés sous la HKCU:\Network clé en texte majuscule.

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

Vous pouvez utiliser ce format pour modifier la forme ou le contenu d'une valeur d'entrée de Registre.

Chaque sous-clé de la clé réseau représente un lecteur réseau mappé qui se reconnecte lors de la connexion. L'entrée RemotePath contient le chemin d'accès UNC du lecteur connecté. Par exemple, si vous mappez le E: lecteur à \\Server\Share, une sous-clé E est créée dans HKCU:\Network avec la valeur de Registre RemotePath définie sur \\Server\Share.

La commande utilise l’applet Get-ItemProperty de commande pour obtenir toutes les sous-clés de la clé réseau et l’applet Set-ItemProperty de commande pour modifier la valeur de l’entrée de Registre RemotePath dans chaque clé. Dans la Set-ItemProperty commande, le chemin est la valeur de la propriété PSPath de la clé de Registre. Il s’agit d’une propriété de l’objet Microsoft .NET Framework qui représente la clé de Registre, et non une entrée du Registre. La commande utilise la méthode ToUpper() de la valeur RemotePath , qui est une chaîne REG_SZ.

Étant donné que Set-ItemProperty modifie la propriété de chaque clé, l’applet de ForEach-Object commande est requise pour accéder à la propriété.

Exemple 5 : Utiliser la variable automatique $null

Cet exemple montre l’effet du pipage de la $null variable automatique vers l’applet de ForEach-Object commande.

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

Hello
Hello
Hello
Hello

Étant donné que PowerShell traite $null comme un espace réservé explicite, l’applet ForEach-Object de commande génère une valeur pour $null comme elle le fait pour d’autres objets dirigés vers elle.

Exemple 6 : Obtenir des valeurs de propriété

Cet exemple obtient la valeur de la propriété Path de tous les modules PowerShell installés à l’aide du paramètre MemberName de l’applet ForEach-Object de commande.

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

La deuxième commande est équivalente à la première. Il utilise l’alias Foreach de l’applet ForEach-Object de commande et omet le nom du paramètre MemberName , qui est facultatif.

L’applet ForEach-Object de commande est utile pour obtenir des valeurs de propriété, car elle obtient la valeur sans modifier le type, contrairement aux applets de commande Format ou à l’applet Select-Object de commande, qui modifient le type de valeur de propriété.

Exemple 7 : Fractionner les noms de modules en noms de composants

Cet exemple montre trois façons de diviser deux noms de modules séparés par points en noms de composants. Elles appellent la méthode Split de chaînes. Les trois commandes utilisent une syntaxe différente, mais elles sont équivalentes et interchangeables. La sortie est la même pour les trois cas.

"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

La première commande utilise la syntaxe traditionnelle, qui inclut un bloc de script et l’opérateur $_d’objet actuel . Elle utilise la syntaxe à point pour spécifier la méthode et des parenthèses pour encadrer l'argument délimiteur.

La deuxième commande utilise le paramètre MemberName pour spécifier la méthode Split et le paramètre ArgumentList pour identifier le point (.) comme délimiteur fractionné.

La troisième commande utilise l’alias Foreach de l’applet ForEach-Object de commande et omet les noms des paramètres MemberName et ArgumentList , qui sont facultatifs.

Exemple 8 : Utilisation de ForEach-Object avec deux blocs de script

Dans cet exemple, nous passons deux blocs de script par position. Tous les blocs de script sont liés au paramètre Process . Toutefois, ils sont traités comme s’ils avaient été passés aux paramètres Begin et Process .

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

begin
process
process

Exemple 9 : Utilisation de ForEach-Object avec plus de deux blocs de script

Dans cet exemple, nous passons quatre blocs de script par position. Tous les blocs de script sont liés au paramètre Process . Toutefois, ils sont traités comme s’ils avaient été passés aux paramètres Begin, Process et End .

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

begin
process A
process B
process A
process B
end

Notes

Le premier bloc de script est toujours mappé au begin bloc, le dernier est mappé au end bloc et les deux blocs intermédiaires sont mappés au process bloc.

Exemple 10 : Exécuter plusieurs blocs de script pour chaque élément de pipeline

Comme indiqué dans l’exemple précédent, plusieurs blocs de script passés à l’aide du paramètre Process sont mappés aux paramètres Begin et End . Pour éviter ce mappage, vous devez fournir des valeurs explicites pour les paramètres Begin et End .

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

one
two
three
one
two
three

Exemple 11 : Exécuter un script lent dans des lots parallèles

Cet exemple montre comment exécuter un bloc de script qui évalue une chaîne et met en veille pendant une seconde.

$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

La valeur du paramètre ThrottleLimit est définie sur 4 afin que l’entrée soit traitée par lots de quatre. Le $using: mot clé est utilisé pour passer la $Message variable dans chaque bloc de script parallèle.

Exemple 12 : Récupérer des entrées de journal en parallèle

Cet exemple récupère 50 000 entrées de journal à partir de 5 journaux système sur un ordinateur Windows local.

$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

Le paramètre Parallel spécifie le bloc de script exécuté en parallèle pour chaque nom de journal d’entrée. Le paramètre ThrottleLimit garantit que les cinq blocs de script s’exécutent en même temps.

Exemple 13 : Exécuter en parallèle en tant que travail

Cet exemple crée un travail qui exécute un bloc de script en parallèle, deux à la fois.

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    …

Le paramètre ThrottleLimit limite le nombre de blocs de script parallèles en cours d’exécution à la fois. Le paramètre AsJob oblige l’applet ForEach-Object de commande à retourner un objet de travail au lieu de diffuser en continu la sortie vers la console. La $job variable reçoit l’objet de travail qui collecte les données de sortie et surveille l’état d’exécution. La $job.ChildJobs propriété contient les travaux enfants qui exécutent les blocs de script parallèles.

Exemple 14 : Utilisation des références de variable sécurisée de thread

Cet exemple appelle des blocs de script en parallèle pour collecter des objets Process nommés de manière unique.

$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

Un seul instance d’un objet ConcurrentDictionary est passé à chaque bloc de script pour collecter les objets. Étant donné que ConcurrentDictionary est thread safe, il est sûr d’être modifié par chaque script parallèle. Un objet non thread-safe, tel que System.Collections.Generic.Dictionary, ne peut pas être utilisé ici.

Notes

Cet exemple est une utilisation inefficace du paramètre Parallèle . Le script ajoute l’objet d’entrée à un objet de dictionnaire simultané. Il est trivial et ne vaut pas la peine d’appeler chaque script dans un thread distinct. L’exécution ForEach-Object sans le commutateur Parallèle est plus efficace et plus rapide. Cet exemple est uniquement destiné à montrer comment utiliser des variables thread safe.

Exemple 15 : Écriture d’erreurs avec exécution parallèle

Cet exemple écrit dans le flux d’erreurs en parallèle, où l’ordre des erreurs écrites est aléatoire.

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

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

Exemple 16 : Fin des erreurs dans l’exécution parallèle

Cet exemple illustre une erreur de fin dans un scriptblock en cours d’exécution parallèle.

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 n’est jamais écrit, car le scriptblock parallèle de cette itération a été arrêté.

Notes

Les variables de paramètres communs PipelineVariablene sont pas prises en charge dans Foreach-Object -Parallel les scénarios, même avec le $using: mot clé.

Exemple 17 : Passage de variables dans script parallèle imbriqué ScriptBlockSet

Vous pouvez créer une variable en dehors d’un Foreach-Object -Parallel scriptblock délimité et l’utiliser à l’intérieur du scriptblock avec le $using mot clé.

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

Le scriptblock imbriqué ne peut pas accéder à la $test2 variable et une erreur est générée.

Exemple 18 : Création de plusieurs travaux qui exécutent des scripts en parallèle

Le paramètre ThrottleLimit limite le nombre de scripts parallèles en cours d’exécution pendant chaque instance de ForEach-Object -Parallel. Il ne limite pas le nombre de travaux qui peuvent être créés lors de l’utilisation du paramètre AsJob . Étant donné que les travaux s’exécutent simultanément, il est possible de créer plusieurs travaux parallèles, chacun s’exécutant jusqu’au nombre limite de blocs de script simultanés.

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

$jobs | Receive-Job -Wait

Cet exemple crée 10 travaux en cours d’exécution. Chaque travail n’exécute pas plus de 5 scripts simultanément. Le nombre total d’instances s’exécutant simultanément est limité à 50 (10 travaux fois la limite de limitation de 5).

Paramètres

-ArgumentList

Spécifie un tableau d’arguments à un appel de méthode. Pour plus d’informations sur le comportement d’ArgumentList, consultez about_Splatting.

Ce paramètre a été introduit dans Windows PowerShell 3.0.

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

-AsJob

Provoque l’exécution de l’appel parallèle en tant que travail PowerShell. Un seul objet de travail est retourné au lieu de la sortie des blocs de script en cours d’exécution. L’objet de travail contient des travaux enfants pour chaque bloc de script parallèle qui s’exécute. Vous pouvez utiliser l’objet de travail avec n’importe quelle applet de commande de travail PowerShell pour voir l’état en cours d’exécution et récupérer des données.

Ce paramètre a été introduit dans PowerShell 7.0.

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

-Begin

Spécifie un bloc de script qui s’exécute avant que cette applet de commande ne traite tous les objets d’entrée. Ce bloc de script n’est exécuté qu’une seule fois pour l’ensemble du pipeline. Pour plus d’informations sur le begin bloc, consultez about_Functions.

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

-Confirm

Vous demande une confirmation avant d’exécuter l’applet de commande.

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

-End

Spécifie un bloc de script qui s’exécute après que cette applet de commande traite tous les objets d’entrée. Ce bloc de script n’est exécuté qu’une seule fois pour l’ensemble du pipeline. Pour plus d’informations sur le end bloc, consultez about_Functions.

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

-InputObject

Spécifie les objets d'entrée. ForEach-Object exécute le bloc de script ou l’instruction d’opération sur chaque objet d’entrée. Entrez une variable contenant les objets, ou tapez une commande ou une expression qui obtient ces objets.

Lorsque vous utilisez le paramètre InputObject avec ForEach-Object, au lieu de rediriger les résultats de la commande vers ForEach-Object, la valeur InputObject est traitée comme un objet unique. Cela est vrai même si la valeur est une collection qui est le résultat d’une commande, telle que -InputObject (Get-Process). Étant donné qu’InputObject ne peut pas retourner des propriétés individuelles à partir d’un tableau ou d’une collection d’objets, nous vous ForEach-Object recommandons d’utiliser pour effectuer des opérations sur une collection d’objets pour les objets qui ont des valeurs spécifiques dans des propriétés définies, d’utiliser ForEach-Object dans le pipeline, comme indiqué dans les exemples de cette rubrique.

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

-MemberName

Spécifie le nom de la propriété membre à obtenir ou la méthode membre à appeler. Les membres doivent être instance membres, et non pas des membres statiques.

Les caractères génériques sont autorisés, mais fonctionnent uniquement si la chaîne résultante est résolue en une valeur unique. Par exemple, si vous exécutez Get-Process | ForEach -MemberName *Name, le modèle générique correspond à plusieurs membres entraînant l’échec de la commande.

Ce paramètre a été introduit dans Windows PowerShell 3.0.

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

-Parallel

Spécifie le bloc de script à utiliser pour le traitement parallèle des objets d’entrée. Entrez un bloc de script décrivant l'opération.

Ce paramètre a été introduit dans PowerShell 7.0.

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

-Process

Spécifie l’opération effectuée sur chaque objet d’entrée. Ce bloc de script est exécuté pour chaque objet du pipeline. Pour plus d’informations sur le process bloc, consultez about_Functions.

Lorsque vous fournissez plusieurs blocs de script au paramètre Process , le premier bloc de script est toujours mappé au begin bloc. S’il n’existe que deux blocs de script, le deuxième bloc est mappé au process bloc. S’il existe au moins trois blocs de script, le premier bloc de script est toujours mappé au begin bloc, le dernier bloc est mappé au end bloc et les blocs du milieu sont mappés au process bloc.

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

-RemainingScripts

Spécifie tous les blocs de script qui ne sont pas pris par le paramètre Process .

Ce paramètre a été introduit dans Windows PowerShell 3.0.

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

-ThrottleLimit

Spécifie le nombre de blocs de script qui s’exécutent en parallèle. Les objets d’entrée sont bloqués jusqu’à ce que le nombre de blocs de script en cours d’exécution se situe en dessous de la Limite de limitation. La valeur par défaut est 5.

Le paramètre ThrottleLimit limite le nombre de scripts parallèles en cours d’exécution pendant chaque instance de ForEach-Object -Parallel. Il ne limite pas le nombre de travaux qui peuvent être créés lors de l’utilisation du paramètre AsJob . Étant donné que les travaux s’exécutent simultanément, il est possible de créer un certain nombre de travaux parallèles, chacun s’exécutant jusqu’à la limite de limitation du nombre de blocs de script simultanés.

Ce paramètre a été introduit dans PowerShell 7.0.

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

-TimeoutSeconds

Spécifie le nombre de secondes à attendre pour que toutes les entrées soient traitées en parallèle. Après le délai d’expiration spécifié, tous les scripts en cours d’exécution sont arrêtés. Et tous les objets d’entrée restants à traiter sont ignorés. La valeur par défaut de 0 désactive le délai d’expiration et ForEach-Object -Parallel peut s’exécuter indéfiniment. Le fait de taper Ctrl+C sur la ligne de commande arrête une commande en cours d’exécution ForEach-Object -Parallel . Ce paramètre ne peut pas être utilisé avec le paramètre AsJob .

Ce paramètre a été introduit dans PowerShell 7.0.

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

-UseNewRunspace

Provoque l’appel parallèle pour créer un runspace pour chaque itération de boucle au lieu de réutiliser les runspaces à partir du pool d’runspaces.

Ce paramètre a été introduit dans PowerShell 7.1

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

-WhatIf

Montre ce qui se passe en cas d’exécution de l’applet de commande. L’applet de commande n’est pas exécutée.

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

Entrées

PSObject

Vous pouvez diriger n’importe quel objet vers cette applet de commande.

Sorties

PSObject

Cette applet de commande retourne des objets déterminés par l’entrée.

Notes

PowerShell inclut les alias suivants pour ForEach-Object:

  • Toutes les plateformes :
    • %
    • foreach

L’applet ForEach-Object de commande fonctionne comme l’instruction Foreach , sauf que vous ne pouvez pas diriger l’entrée vers une instruction Foreach . Pour plus d’informations sur l’instruction Foreach , consultez about_Foreach.

À partir de PowerShell 4.0, Where des ForEach méthodes ont été ajoutées pour une utilisation avec des collections. Vous pouvez en savoir plus sur ces nouvelles méthodes ici about_arrays

Utilisation de ForEach-Object -Parallel:

  • ForEach-Object -Parallel exécute chaque bloc de script dans un nouvel espace d’exécution. Les nouveaux espaces d’exécution créent beaucoup plus de surcharge que l’exécution ForEach-Object avec un traitement séquentiel. Il est important d’utiliser Parallel où la surcharge liée à l’exécution en parallèle est faible par rapport au travail effectué par le bloc de script. Par exemple :

    • Scripts gourmands en calcul sur des machines multicœurs
    • Scripts qui passent du temps à attendre les résultats ou à effectuer des opérations de fichier

    L’utilisation du paramètre Parallel peut entraîner une exécution des scripts beaucoup plus lente que la normale. Surtout si les scripts parallèles sont trivials. Expérimentez avec Parallel pour découvrir où il peut être bénéfique.

  • Lors de l’exécution en parallèle, les objets décorés avec ScriptProperties ou ScriptMethods ne peuvent pas fonctionner correctement s’ils sont exécutés dans un runspace différent de celui qui leur était initialement attaché.

    L’appel de scriptblock tente toujours de s’exécuter dans son runspace d’accueil , quel que soit l’endroit où il est réellement appelé. Toutefois, ForEach-Object -Parallel crée des runspaces temporaires qui sont supprimés après utilisation, de sorte qu’il n’y a plus d’runspace dans lequel les scripts peuvent s’exécuter.

    Ce comportement peut fonctionner tant que l’espace d’exécution d’accueil existe toujours. Toutefois, il se peut que vous n’obteniez pas le résultat souhaité si le script dépend de variables externes qui sont uniquement présentes dans l’espace d’exécution de l’appelant et non dans l’espace d’exécution de base.

  • Les erreurs qui ne se terminent pas sont écrites dans le flux d’erreurs d’applet de commande, car elles se produisent dans des blocs de script en cours d’exécution parallèles. Étant donné que l’ordre d’exécution de scriptblock parallèle n’est pas déterministe, l’ordre dans lequel les erreurs apparaissent dans le flux d’erreurs est aléatoire. De même, les messages écrits dans d’autres flux de données, tels que l’avertissement, le détail ou les informations, sont écrits dans ces flux de données dans un ordre indéterminé.

    Les erreurs de fin, telles que les exceptions, mettent fin à la instance parallèle individuelle des blocs de script dans lesquels elles se produisent. Une erreur de fin dans un scriptblocks peut ne pas entraîner l’arrêt de l’applet Foreach-Object de commande. Les autres blocs de script, exécutés en parallèle, continuent à s’exécuter, sauf s’ils rencontrent également une erreur de fin. L’erreur de fin est écrite dans le flux de données d’erreur en tant que ErrorRecord avec un FullyQualifiedErrorId de PSTaskException. Les erreurs de fin peuvent être converties en erreurs de non-fin à l’aide de PowerShell try/catch ou trap de blocs.

  • Les variables de paramètres communs PipelineVariablene sont pas prises en charge dans les scénarios parallèles, même avec le $using: mot clé.

    Important

    Le ForEach-Object -Parallel jeu de paramètres exécute des blocs de script en parallèle sur des threads de processus distincts. Le $using: mot clé permet de transmettre des références de variable à partir du thread d’appel d’applet de commande à chaque thread de bloc de script en cours d’exécution. Étant donné que les blocs de script s’exécutent dans différents threads, les variables d’objet transmises par référence doivent être utilisées en toute sécurité. En règle générale, il est prudent de lire à partir d’objets référencés qui ne changent pas. Si vous devez modifier l’état de l’objet, vous devez utiliser des objets thread sécurisés, tels que les types .NET System.Collection.Concurrent (voir exemple 14).