ForEach-Object
Realiza una operación en cada elemento de una colección de objetos de entrada.
Sintaxis
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
El ForEach-Object
cmdlet realiza una operación en cada elemento de una colección de objetos de entrada. Los objetos de entrada se pueden canalizar al cmdlet o especificarse mediante el parámetro InputObject .
A partir de Windows PowerShell 3.0, hay dos maneras diferentes de construir un ForEach-Object
comando.
Bloque de script. Puede usar un bloque de scripts para especificar la operación. Dentro del bloque de script, use la
$_
variable para representar el objeto actual. El bloque de script es el valor del parámetro Process . El bloque de script puede contener cualquier script de PowerShell.Por ejemplo, el siguiente comando obtiene el valor de la propiedad ProcessName de cada proceso del equipo.
Get-Process | ForEach-Object {$_.ProcessName}
ForEach-Object
admite losbegin
bloques ,process
yend
como se describe en about_functions.Nota:
Los bloques de script se ejecutan en el ámbito del autor de la llamada. Por lo tanto, los bloques tienen acceso a variables de ese ámbito y pueden crear nuevas variables que persistan en ese ámbito una vez completado el cmdlet.
Instrucción Operation. También puede escribir una instrucción operation, que es mucho más similar al lenguaje natural. Puede usar la instrucción de operación para especificar un valor de propiedad o llamar a un método. Las instrucciones de operación se presentaron en Windows PowerShell 3.0.
Por ejemplo, el siguiente comando también obtiene el valor de la propiedad ProcessName de cada proceso del equipo.
Get-Process | ForEach-Object ProcessName
Bloque de script en ejecución en paralelo. A partir de PowerShell 7.0, hay disponible un tercer conjunto de parámetros que ejecuta cada bloque de script en paralelo. El parámetro ThrottleLimit limita el número de scripts paralelos que se ejecutan a la vez. Como antes, use la
$_
variable para representar el objeto de entrada actual en el bloque de script. Use la$using:
palabra clave para pasar referencias de variables al script en ejecución.En PowerShell 7, se crea un nuevo espacio de ejecución para cada iteración de bucle para garantizar el aislamiento máximo. Esto puede ser un gran rendimiento y acierto de recursos si el trabajo que está realizando es pequeño en comparación con la creación de nuevos espacios de ejecución o si hay muchas iteraciones que realizan un trabajo significativo. A partir de PowerShell 7.1, los espacios de ejecución de un grupo de espacios de ejecución se reutilizan de forma predeterminada. El parámetro ThrottleLimit establece el tamaño del grupo de espacios de ejecución. El tamaño predeterminado del grupo de espacios de ejecución es 5. Todavía puede crear un nuevo espacio de ejecución para cada iteración mediante el modificador UseNewRunspace .
De forma predeterminada, los bloques de scripts paralelos usan el directorio de trabajo actual del autor de la llamada que inició las tareas paralelas.
Para obtener más información, consulte la sección NOTAS de este artículo.
Ejemplos
Ejemplo 1: Dividir enteros en una matriz
En este ejemplo se toma una matriz de tres enteros y se divide cada uno de ellos en 1024.
30000, 56798, 12432 | ForEach-Object -Process {$_/1024}
29.296875
55.466796875
12.140625
Ejemplo 2: Obtener la longitud de todos los archivos de un directorio
En este ejemplo se procesan los archivos y directorios del directorio $PSHOME
de instalación de PowerShell .
Get-ChildItem $PSHOME |
ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}
Si el objeto no es un directorio, el bloque de script obtiene el nombre del archivo, divide el valor de su propiedad Length en 1024 y agrega un espacio (" ") para separarlo de la entrada siguiente. El cmdlet usa la propiedad PSISContainer para determinar si un objeto es un directorio.
Ejemplo 3: Operar en los eventos del sistema más recientes
En este ejemplo se escriben los 1000 eventos más recientes del registro de eventos del sistema en un archivo de texto. La hora actual se muestra antes y después de procesar los eventos.
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
obtiene los 1000 eventos más recientes del registro de eventos del sistema y los canaliza al ForEach-Object
cmdlet . El parámetro Begin muestra la fecha y hora actuales. A continuación, el parámetro Process usa el Out-File
cmdlet para crear un archivo de texto denominado events.txt y almacena la propiedad message de cada uno de los eventos de ese archivo. Por último, el parámetro End se usa para mostrar la fecha y hora después de que se haya completado todo el procesamiento.
Ejemplo 4: Cambiar el valor de una clave del Registro
En este ejemplo se cambia el valor de la entrada del Registro RemotePath en todas las subclaves de la HKCU:\Network
clave a texto en mayúsculas.
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {
Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
}
Puede usar este formato para cambiar la forma o el contenido de un valor de la entrada del Registro.
Cada subclave de la clave de red representa una unidad de red asignada que se vuelve a conectar al iniciar sesión. La entrada RemotePath contiene la ruta de acceso UNC de la unidad conectada. Por ejemplo, si asigna la E:
unidad a \\Server\Share
, se crea una subclave E con el valor del Registro RemotePath establecido \\Server\Share
en HKCU:\Network
.
El comando usa el Get-ItemProperty
cmdlet para obtener todas las subclaves de la clave de red y el Set-ItemProperty
cmdlet para cambiar el valor de la entrada del Registro RemotePath en cada clave. En el Set-ItemProperty
comando , la ruta de acceso es el valor de la propiedad PSPath de la clave del Registro. Se trata de una propiedad del objeto de Microsoft .NET Framework que representa la clave del Registro, no una entrada del Registro. El comando usa el método ToUpper() del valor remotePath , que es una cadena REG_SZ.
Dado que Set-ItemProperty
cambia la propiedad de cada clave, el ForEach-Object
cmdlet es necesario para acceder a la propiedad .
Ejemplo 5: Uso de la variable automática $null
En este ejemplo se muestra el efecto de canalización de la $null
variable automática al ForEach-Object
cmdlet .
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
Dado que PowerShell trata $null
como un marcador de posición explícito, el ForEach-Object
cmdlet genera un valor para $null
como lo hace para otros objetos canalizaciones a él.
Ejemplo 6: Obtener valores de propiedad
En este ejemplo se obtiene el valor de la propiedad Path de todos los módulos de PowerShell instalados mediante el parámetro MemberName del ForEach-Object
cmdlet .
Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path
El segundo comando es equivalente al primero. Usa el Foreach
alias del ForEach-Object
cmdlet y omite el nombre del parámetro MemberName , que es opcional.
El ForEach-Object
cmdlet es útil para obtener valores de propiedad, ya que obtiene el valor sin cambiar el tipo, a diferencia de los cmdlets Format o el Select-Object
cmdlet , que cambian el tipo de valor de propiedad.
Ejemplo 7: Dividir nombres de módulo en nombres de componente
En este ejemplo se muestran tres maneras de dividir dos nombres de módulo separados por puntos en sus nombres de componente. Los comandos llaman al método Split de cadenas. Los tres comandos usan una sintaxis diferente, pero son equivalentes e intercambiables. La salida es la misma para los tres casos.
"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
El primer comando usa la sintaxis tradicional, que incluye un bloque de script y el operador $_
de objeto actual. Usa la sintaxis de puntos para especificar el método y los paréntesis para delimitar el argumento delimitador.
El segundo comando usa el parámetro MemberName para especificar el método Split y el parámetro ArgumentList para identificar el punto (.
) como delimitador de división.
El tercer comando usa el alias Foreach del ForEach-Object
cmdlet y omite los nombres de los parámetros MemberName y ArgumentList , que son opcionales.
Ejemplo 8: Uso de ForEach-Object con dos bloques de script
En este ejemplo, pasamos dos bloques de script de forma posicional. Todos los bloques de script se enlazan al parámetro Process . Sin embargo, se tratan como si se hubieran pasado a los parámetros Begin y Process .
1..2 | ForEach-Object { 'begin' } { 'process' }
begin
process
process
Ejemplo 9: Uso de ForEach-Object con más de dos bloques de script
En este ejemplo, pasamos cuatro bloques de script posicionalmente. Todos los bloques de script se enlazan al parámetro Process . Sin embargo, se tratan como si se hubieran pasado a los parámetros Begin, Process y End .
1..2 | ForEach-Object { 'begin' } { 'process A' } { 'process B' } { 'end' }
begin
process A
process B
process A
process B
end
Nota:
El primer bloque de script siempre se asigna al begin
bloque, el último bloque se asigna al end
bloque y los dos bloques intermedios se asignan al process
bloque.
Ejemplo 10: Ejecución de varios bloques de script para cada elemento de canalización
Como se muestra en el ejemplo anterior, se asignan varios bloques de script mediante el parámetro Process a los parámetros Begin y End . Para evitar esta asignación, debe proporcionar valores explícitos para los parámetros Begin y End .
1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null
one
two
three
one
two
three
Ejemplo 11: Ejecución de scripts lentos en lotes paralelos
En este ejemplo se ejecuta un bloque de script que evalúa una cadena y se suspende durante un segundo.
$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
El valor del parámetro ThrottleLimit se establece en 4 para que la entrada se procese en lotes de cuatro.
La $using:
palabra clave se usa para pasar la $Message
variable a cada bloque de script paralelo.
Ejemplo 12: Recuperación de entradas de registro en paralelo
En este ejemplo se recuperan 50 000 entradas de registro de 5 registros del sistema en una máquina 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
El parámetro Parallel especifica el bloque de script que se ejecuta en paralelo para cada nombre de registro de entrada. El parámetro ThrottleLimit garantiza que los cinco bloques de script se ejecuten al mismo tiempo.
Ejemplo 13: Ejecutar en paralelo como un trabajo
En este ejemplo se crea un trabajo que ejecuta un bloque de script en paralelo, dos a la vez.
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 …
El parámetro ThrottleLimit limita el número de bloques de script paralelos que se ejecutan a la vez. El parámetro AsJob hace que el ForEach-Object
cmdlet devuelva un objeto de trabajo en lugar de transmitir la salida a la consola. La $job
variable recibe el objeto de trabajo que recopila datos de salida y supervisa el estado de ejecución. La $job.ChildJobs
propiedad contiene los trabajos secundarios que ejecutan los bloques de script paralelos.
Ejemplo 14: Uso de referencias de variables seguras para subprocesos
En este ejemplo se invocan bloques de script en paralelo para recopilar objetos Process con nombre único.
$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
Se pasa una sola instancia de un objeto ConcurrentDictionary a cada bloque de script para recopilar los objetos. Dado que ConcurrentDictionary es seguro para subprocesos, es seguro modificarlo cada script paralelo. Un objeto no seguro para subprocesos, como System.Collections.Generic.Dictionary, no sería seguro usarlo aquí.
Nota:
Este ejemplo es un uso ineficaz del parámetro Parallel . El script agrega el objeto de entrada a un objeto de diccionario simultáneo. Es trivial y no vale la pena invocar cada script en un subproceso independiente. La ejecución ForEach-Object
sin el conmutador Parallel es más eficaz y rápida. Este ejemplo solo está pensado para demostrar cómo usar variables seguras para subprocesos.
Ejemplo 15: Escritura de errores con ejecución paralela
En este ejemplo se escribe en la secuencia de errores en paralelo, donde el orden de los errores escritos es aleatorio.
1..3 | ForEach-Object -Parallel {
Write-Error "Error: $_"
}
Write-Error: Error: 1
Write-Error: Error: 3
Write-Error: Error: 2
Ejemplo 16: Finalización de errores en la ejecución en paralelo
En este ejemplo se muestra un error de terminación en un scriptblock en ejecución paralelo.
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
nunca se escribe porque se finalizó el scriptblock paralelo para esa iteración.
Nota:
Las variables de parámetro comunes PipelineVariable no se admiten en Foreach-Object -Parallel
escenarios incluso con la $using:
palabra clave .
Ejemplo 17: Pasar variables en script paralelo anidado ScriptBlockSet
Puede crear una variable fuera de un Foreach-Object -Parallel
scriptblock con ámbito y usarla dentro del scriptblock con la $using
palabra clave .
$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.
El scriptblock anidado no puede acceder a la $test2
variable y se produce un error.
Ejemplo 18: Creación de varios trabajos que ejecutan scripts en paralelo
El parámetro ThrottleLimit limita el número de scripts paralelos que se ejecutan durante cada instancia de ForEach-Object -Parallel
. No limita el número de trabajos que se pueden crear al usar el parámetro AsJob . Dado que los propios trabajos se ejecutan simultáneamente, es posible crear varios trabajos paralelos, cada uno de los cuales se ejecuta hasta el número de límites de bloqueos de script simultáneos.
$jobs = for ($i=0; $i -lt 10; $i++) {
1..10 | ForEach-Object -Parallel {
./RunMyScript.ps1
} -AsJob -ThrottleLimit 5
}
$jobs | Receive-Job -Wait
En este ejemplo se crean 10 trabajos en ejecución. Cada trabajo no ejecuta más de 5 scripts simultáneamente. El número total de instancias que se ejecutan simultáneamente se limita a 50 (10 trabajos por el límite de 5).
Parámetros
-ArgumentList
Especifica una matriz de argumentos para una llamada de método. Para obtener más información sobre el comportamiento de ArgumentList, vea about_Splatting.
Este parámetro se incorporó en Windows PowerShell 3.0.
Tipo: | Object[] |
Alias: | Args |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-AsJob
Hace que la invocación paralela se ejecute como un trabajo de PowerShell. Se devuelve un único objeto de trabajo en lugar de la salida de los bloques de script en ejecución. El objeto de trabajo contiene trabajos secundarios para cada bloque de script paralelo que se ejecuta. Puede usar el objeto de trabajo con cualquiera de los cmdlets de trabajo de PowerShell para ver el estado en ejecución y recuperar datos.
Este parámetro se introdujo en PowerShell 7.0.
Tipo: | SwitchParameter |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-Begin
Especifica un bloque de script que se ejecuta antes de que este cmdlet procese los objetos de entrada. Este bloque de script solo se ejecuta una vez para toda la canalización. Para obtener más información sobre el begin
bloque, consulte about_Functions.
Tipo: | ScriptBlock |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-Confirm
Le solicita su confirmación antes de ejecutar el cmdlet.
Tipo: | SwitchParameter |
Alias: | cf |
Posición: | Named |
Valor predeterminado: | False |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-End
Especifica un bloque de script que se ejecuta después de que este cmdlet procese todos los objetos de entrada. Este bloque de script solo se ejecuta una vez para toda la canalización. Para obtener más información sobre el end
bloque, consulte about_Functions.
Tipo: | ScriptBlock |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-InputObject
Especifica los objetos de entrada. ForEach-Object
ejecuta la instrucción script block o operation en cada objeto de entrada. Especifique una variable que contenga los objetos o escriba un comando o una expresión que obtenga los objetos.
Cuando se usa el parámetro InputObject con ForEach-Object
, en lugar de canalizar los resultados del comando a ForEach-Object
, el valor InputObject se trata como un único objeto. Esto es true incluso si el valor es una colección que es el resultado de un comando, como -InputObject (Get-Process)
.
Dado que InputObject no puede devolver propiedades individuales de una matriz o colección de objetos, se recomienda que si usa ForEach-Object
para realizar operaciones en una colección de objetos para esos objetos que tienen valores específicos en propiedades definidas, se usa ForEach-Object
en la canalización, como se muestra en los ejemplos de este tema.
Tipo: | PSObject |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | True |
Aceptar caracteres comodín: | False |
-MemberName
Especifica el nombre de la propiedad miembro a la que se va a obtener o al método miembro que se va a llamar. Los miembros deben ser miembros de instancia, no miembros estáticos.
Se permiten caracteres comodín, pero solo funcionan si la cadena resultante se resuelve en un valor único.
Por ejemplo, si ejecuta Get-Process | ForEach -MemberName *Name
, el patrón comodín coincide con más de un miembro que provoca un error en el comando.
Este parámetro se incorporó en Windows PowerShell 3.0.
Tipo: | String |
Posición: | 0 |
Valor predeterminado: | None |
Requerido: | True |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | True |
-Parallel
Especifica el bloque de script que se va a usar para el procesamiento paralelo de objetos de entrada. Escriba un bloque de scripts que describa la operación.
Este parámetro se introdujo en PowerShell 7.0.
Tipo: | ScriptBlock |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | True |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-Process
Especifica la operación que se realiza en cada objeto de entrada. Este bloque de script se ejecuta para cada objeto de la canalización. Para obtener más información sobre el process
bloque, consulte about_Functions.
Cuando se proporcionan varios bloques de script al parámetro Process , el primer bloque de script siempre se asigna al begin
bloque . Si solo hay dos bloques de script, el segundo bloque se asigna al process
bloque . Si hay tres o más bloques de script, el primer bloque de script siempre se asigna al begin
bloque, el último bloque se asigna al end
bloque y los bloques intermedios se asignan al process
bloque.
Tipo: | ScriptBlock[] |
Posición: | 0 |
Valor predeterminado: | None |
Requerido: | True |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-RemainingScripts
Especifica todos los bloques de script que el parámetro Process no toma.
Este parámetro se incorporó en Windows PowerShell 3.0.
Tipo: | ScriptBlock[] |
Posición: | Named |
Valor predeterminado: | None |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-ThrottleLimit
Especifica el número de bloques de script que se ejecutan en paralelo. Los objetos de entrada se bloquean hasta que el recuento de bloques de script en ejecución se encuentra por debajo del LímiteLimit. El valor predeterminado es 5
.
El parámetro ThrottleLimit limita el número de scripts paralelos que se ejecutan durante cada instancia de ForEach-Object -Parallel
. No limita el número de trabajos que se pueden crear al usar el parámetro AsJob . Dado que los propios trabajos se ejecutan simultáneamente, es posible crear una serie de trabajos paralelos, cada uno de los cuales se ejecuta hasta el número de límites de bloqueos de scripts simultáneos.
Este parámetro se introdujo en PowerShell 7.0.
Tipo: | Int32 |
Posición: | Named |
Valor predeterminado: | 5 |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-TimeoutSeconds
Especifica el número de segundos que se van a esperar a que se procesen todas las entradas en paralelo. Después del tiempo de espera especificado, se detienen todos los scripts en ejecución. Y se omiten los objetos de entrada restantes que se van a procesar. El valor predeterminado de deshabilita el tiempo de 0
espera y ForEach-Object -Parallel
se puede ejecutar indefinidamente. Al escribir Ctrl+C en la línea de comandos, se detiene un comando en ejecución.ForEach-Object -Parallel
Este parámetro no se puede usar junto con el parámetro AsJob .
Este parámetro se introdujo en PowerShell 7.0.
Tipo: | Int32 |
Posición: | Named |
Valor predeterminado: | 0 |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-UseNewRunspace
Hace que la invocación paralela cree un nuevo espacio de ejecución para cada iteración de bucle en lugar de reutilizar los espacios de ejecución del grupo de espacios de ejecución.
Este parámetro se introdujo en PowerShell 7.1
Tipo: | SwitchParameter |
Posición: | Named |
Valor predeterminado: | False |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
-WhatIf
Muestra lo que sucedería si se ejecutara el cmdlet. El cmdlet no se ejecuta.
Tipo: | SwitchParameter |
Alias: | wi |
Posición: | Named |
Valor predeterminado: | False |
Requerido: | False |
Aceptar entrada de canalización: | False |
Aceptar caracteres comodín: | False |
Entradas
Puede canalizar cualquier objeto a este cmdlet.
Salidas
Este cmdlet devuelve objetos determinados por la entrada.
Notas
PowerShell incluye los siguientes alias para ForEach-Object
:
- Todas las plataformas:
%
foreach
El ForEach-Object
cmdlet funciona de forma muy similar a la instrucción Foreach , excepto que no se puede canalizar la entrada a una instrucción Foreach . Para obtener más información sobre la instrucción Foreach , consulte about_Foreach.
A partir de PowerShell 4.0, Where
y ForEach
se agregaron métodos para su uso con colecciones. Puede obtener más información sobre estos nuevos métodos aquí about_arrays
Usar ForEach-Object -Parallel
:
ForEach-Object -Parallel
ejecuta cada bloque de script en un nuevo espacio de ejecución. Los nuevos espacios de ejecución crean significativamente más sobrecarga que la ejecuciónForEach-Object
con procesamiento secuencial. Es importante usar Parallel donde la sobrecarga de ejecutarse en paralelo es pequeña en comparación con el trabajo que realiza el bloque de script. Por ejemplo:- Scripts intensivos de proceso en máquinas de varios núcleos
- Scripts que pasan tiempo esperando resultados o realizando operaciones de archivo
El uso del parámetro Parallel puede hacer que los scripts se ejecuten mucho más lentamente de lo normal. Especialmente si los scripts paralelos son triviales. Experimente con Parallel para descubrir dónde puede ser beneficioso.
Cuando se ejecuta en paralelo, los objetos decorados con ScriptProperties o ScriptMethods no se pueden garantizar que funcionen correctamente si se ejecutan en un espacio de ejecución diferente al que los scripts se asociaron originalmente a ellos.
La invocación de scriptblock siempre intenta ejecutarse en su espacio de ejecución principal , independientemente de dónde se invoque realmente. Sin embargo,
ForEach-Object -Parallel
crea espacios de ejecución temporales que se eliminan después de su uso, por lo que ya no hay ningún espacio de ejecución para que los scripts se ejecuten en .Este comportamiento puede funcionar siempre que el espacio de ejecución principal siga existiendo. Sin embargo, es posible que no obtenga el resultado deseado si el script depende de variables externas que solo están presentes en el espacio de ejecución del autor de la llamada y no en el espacio de ejecución principal.
Los errores de no terminación se escriben en el flujo de errores del cmdlet a medida que se producen en los bloques de script en ejecución en paralelo. Dado que el orden de ejecución de scriptblock paralelo no es determinista, el orden en el que aparecen errores en la secuencia de errores es aleatorio. Del mismo modo, los mensajes escritos en otros flujos de datos, como la advertencia, el detalle o la información se escriben en esos flujos de datos en un orden indeterminado.
Los errores de terminación, como excepciones, finalizan la instancia paralela individual de los bloques de script en los que se producen. Un error de terminación en un scriptblocks puede no provocar la terminación del
Foreach-Object
cmdlet. Los otros bloques de script, que se ejecutan en paralelo, continúan ejecutándose a menos que también encuentren un error de terminación. El error de terminación se escribe en el flujo de datos de error como errorRecord con un valor FullyQualifiedErrorId dePSTaskException
. Los errores de terminación se pueden convertir en errores de no terminación mediante PowerShelltry
/catch
otrap
bloques.Las variables de parámetro comunes PipelineVariable no se admiten en escenarios paralelos incluso con la
$using:
palabra clave .Importante
El
ForEach-Object -Parallel
conjunto de parámetros ejecuta bloques de script en paralelo en subprocesos de proceso independientes. La$using:
palabra clave permite pasar referencias de variables desde el subproceso de invocación de cmdlet a cada subproceso de bloque de script en ejecución. Dado que los bloques de script se ejecutan en subprocesos diferentes, las variables de objeto pasadas por referencia deben usarse de forma segura. Por lo general, es seguro leer de objetos a los que se hace referencia que no cambian. Si necesita modificar el estado del objeto, debe usar objetos seguros para subprocesos, como los tipos System.Collection.Concurrent de .NET (vea el ejemplo 14).