ForEach-Object

Realiza una operación en cada elemento de una colección de objetos de entrada.

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

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 los beginbloques , processy end 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

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 $PSHOMEde 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\Shareen 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

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.

Type:Object[]
Aliases:Args
Position:Named
Default value:None
Required:False
Accept pipeline input:False
Accept wildcard characters: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.

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

-Confirm

Le solicita su confirmación antes de ejecutar el cmdlet.

Type:SwitchParameter
Aliases:cf
Position:Named
Default value:False
Required:False
Accept pipeline input:False
Accept wildcard characters: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.

Type:ScriptBlock
Position:Named
Default value:None
Required:False
Accept pipeline input:False
Accept wildcard characters: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.

Type:PSObject
Position:Named
Default value:None
Required:False
Accept pipeline input:True
Accept wildcard characters: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.

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

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

Type:ScriptBlock[]
Position:0
Default value:None
Required:True
Accept pipeline input:False
Accept wildcard characters: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.

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

-WhatIf

Muestra lo que sucedería si se ejecutara el cmdlet. El cmdlet no se ejecuta.

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

Entradas

PSObject

Puede canalizar cualquier objeto a este cmdlet.

Salidas

PSObject

Este cmdlet devuelve objetos determinados por la entrada.

Notas

Windows PowerShell incluye los siguientes alias para ForEach-Object:

  • %
  • 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