ForEach-Object
Executa uma operação em cada item de uma coleção de objetos de entrada.
Sintaxe
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
O ForEach-Object
cmdlet executa uma operação em cada item em uma coleção de objetos de entrada. Os objetos de entrada podem ser canalizados para o cmdlet ou especificados usando o parâmetro InputObject .
A partir do Windows PowerShell 3.0, há duas maneiras diferentes de construir um ForEach-Object
comando.
Bloco de script. Você pode usar um bloco de script para especificar a operação. Dentro do bloco de script, use a
$_
variável para representar o objeto atual. O bloco de script é o valor do parâmetro Process . O bloco de script pode conter qualquer script do PowerShell.Por exemplo, o comando a seguir obtém o valor da propriedade ProcessName de cada processo no computador.
Get-Process | ForEach-Object {$_.ProcessName}
ForEach-Object
Suporta osbegin
blocos ,process
e conformeend
descrito em about_functions.Observação
Os blocos de script são executados no escopo do chamador. Portanto, os blocos têm acesso a variáveis nesse escopo e podem criar novas variáveis que persistem nesse escopo após a conclusão do cmdlet.
Instrução de operação. Você também pode escrever uma instrução de operação, que é muito mais parecida com a linguagem natural. Você pode usar a instrução de operação para especificar um valor de propriedade ou chamar um método. Instruções de operação foram introduzidas no Windows PowerShell 3.0.
Por exemplo, o comando a seguir também obtém o valor da propriedade ProcessName de cada processo no computador.
Get-Process | ForEach-Object ProcessName
Bloco de script em execução paralela. A partir do PowerShell 7.0, um terceiro conjunto de parâmetros está disponível que executa cada bloco de script em paralelo. O parâmetro ThrottleLimit limita o número de scripts paralelos em execução por vez. Como antes, use a
$_
variável para representar o objeto de entrada atual no bloco de script. Use a$using:
palavra-chave para passar referências de variáveis para o script em execução.No PowerShell 7, um novo runspace é criado para cada iteração de loop para garantir o isolamento máximo. Isso pode ser um grande impacto no desempenho e nos recursos se o trabalho que você está fazendo for pequeno em comparação com a criação de novos runspaces ou se houver muitas iterações executando um trabalho significativo. A partir do PowerShell 7.1, os runspaces de um pool de runspace são reutilizados por padrão. O parâmetro ThrottleLimit define o tamanho do pool de runspace. O tamanho padrão do pool de runspace é 5. Você ainda pode criar um novo runspace para cada iteração usando a opção UseNewRunspace .
Por padrão, os scriptblocks paralelos usam o diretório de trabalho atual do chamador que iniciou as tarefas paralelas.
Para obter mais informações, consulte a seção NOTAS deste artigo.
Exemplos
Exemplo 1: Dividir inteiros em uma matriz
Este exemplo pega uma matriz de três inteiros e divide cada um deles por 1024.
30000, 56798, 12432 | ForEach-Object -Process {$_/1024}
29.296875
55.466796875
12.140625
Exemplo 2: Obter o comprimento de todos os arquivos em um diretório
Este exemplo processa os arquivos e diretórios no diretório $PSHOME
de instalação do PowerShell.
Get-ChildItem $PSHOME |
ForEach-Object -Process {if (!$_.PSIsContainer) {$_.Name; $_.Length / 1024; " " }}
Se o objeto não for um diretório, o bloco de script obterá o nome do arquivo, dividirá o valor de sua propriedade Length por 1024 e adicionará um espaço (" ") para separá-lo da próxima entrada. O cmdlet usa a propriedade PSISContainer para determinar se um objeto é um diretório.
Exemplo 3: Operar nos eventos mais recentes do sistema
Este exemplo grava os 1000 eventos mais recentes do log de eventos do sistema em um arquivo de texto. A hora atual é exibida antes e depois do processamento dos 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
obtém os 1000 eventos mais recentes do log de eventos do sistema e os canaliza para o ForEach-Object
cmdlet. O parâmetro Begin exibe a data e a hora atuais. Em seguida, o parâmetro Process usa o Out-File
cmdlet para criar um arquivo de texto chamado events.txt e armazena a propriedade message de cada um dos eventos nesse arquivo. Por último, o parâmetro End é usado para exibir a data e a hora após a conclusão de todo o processamento.
Exemplo 4: Alterar o valor de uma chave do Registro
Este exemplo altera o valor da entrada do Registro RemotePath em todas as subchaves sob a chave para texto HKCU:\Network
em maiúsculas.
Get-ItemProperty -Path HKCU:\Network\* |
ForEach-Object {
Set-ItemProperty -Path $_.PSPath -Name RemotePath -Value $_.RemotePath.ToUpper()
}
Você pode usar esse formato para alterar a forma ou o conteúdo de um valor de entrada de registro.
Cada subchave na chave de rede representa uma unidade de rede mapeada que se reconecta no logon. A entrada RemotePath contém o caminho UNC da unidade conectada. Por exemplo, se você mapear a unidade para \\Server\Share
, uma subchave E será criada com HKCU:\Network
o valor do Registro RemotePath definido como \\Server\Share
.E:
O comando usa o Get-ItemProperty
cmdlet para obter todas as subchaves da chave de rede e o Set-ItemProperty
cmdlet para alterar o valor da entrada do Registro RemotePath em cada chave. Set-ItemProperty
No comando, o caminho é o valor da propriedade PSPath da chave do Registro. Essa é uma propriedade do objeto do Microsoft .NET Framework que representa a chave do Registro, não uma entrada do Registro. O comando usa o método ToUpper() do valor RemotePath , que é uma string REG_SZ.
Como Set-ItemProperty
está alterando a propriedade de cada chave, o ForEach-Object
cmdlet é necessário para acessar a propriedade.
Exemplo 5: Usar a variável automática $null
Este exemplo mostra o efeito de canalizar a $null
variável automática para o ForEach-Object
cmdlet.
1, 2, $null, 4 | ForEach-Object {"Hello"}
Hello
Hello
Hello
Hello
Como o PowerShell é tratado $null
como um espaço reservado explícito, o ForEach-Object
cmdlet gera um valor para $null
como faz para outros objetos canalizados para ele.
Exemplo 6: Obter valores de propriedade
Este exemplo obtém o valor da propriedade Path de todos os módulos do PowerShell instalados usando o parâmetro MemberName do ForEach-Object
cmdlet.
Get-Module -ListAvailable | ForEach-Object -MemberName Path
Get-Module -ListAvailable | Foreach Path
O segundo comando é equivalente ao primeiro. Ele usa o Foreach
alias do ForEach-Object
cmdlet e omite o nome do parâmetro MemberName , que é opcional.
O ForEach-Object
cmdlet é útil para obter valores de propriedade, pois obtém o valor sem alterar o tipo, ao contrário dos cmdlets Format ou do Select-Object
cmdlet, que alteram o tipo de valor da propriedade.
Exemplo 7: Dividir nomes de módulos em nomes de componentes
Este exemplo mostra três maneiras de dividir dois nomes de módulos separados por pontos em seus nomes de componentes. Os comandos chamam o método Split de cadeias de caracteres. Os três comandos usam uma sintaxe diferente, mas são equivalentes e intercambiáveis. A saída é a mesma para todos os três 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
O primeiro comando usa a sintaxe tradicional, que inclui um bloco de script e o operador $_
de objeto atual . Ele usa a sintaxe de ponto para especificar o método e parênteses para incluir o argumento delimitador.
O segundo comando usa o parâmetro MemberName para especificar o método Split e o parâmetro ArgumentList para identificar o ponto (.
) como o delimitador de divisão.
O terceiro comando usa o alias Foreach do ForEach-Object
cmdlet e omite os nomes dos parâmetros MemberName e ArgumentList , que são opcionais.
Exemplo 8: Usando ForEach-Object com dois blocos de script
Neste exemplo, passamos dois blocos de script posicionalmente. Todos os blocos de script são associados ao parâmetro Process . No entanto, eles são tratados como se tivessem sido passados para os parâmetros Begin e Process .
1..2 | ForEach-Object { 'begin' } { 'process' }
begin
process
process
Exemplo 9: Usando ForEach-Object com mais de dois blocos de script
Neste exemplo, passamos quatro blocos de script posicionalmente. Todos os blocos de script são associados ao parâmetro Process . No entanto, eles são tratados como se tivessem sido passados para os parâmetros Begin, Process e End.
1..2 | ForEach-Object { 'begin' } { 'process A' } { 'process B' } { 'end' }
begin
process A
process B
process A
process B
end
Observação
O primeiro bloco de script é sempre mapeado para o begin
bloco, o último bloco é mapeado para o end
bloco e os dois blocos do meio são mapeados para o process
bloco.
Exemplo 10: Executar vários blocos de script para cada item de pipeline
Conforme mostrado no exemplo anterior, vários blocos de script passados usando o parâmetro Process são mapeados para os parâmetros Begin e End. Para evitar esse mapeamento, você deve fornecer valores explícitos para os parâmetros Begin e End.
1..2 | ForEach-Object -Begin $null -Process { 'one' }, { 'two' }, { 'three' } -End $null
one
two
three
one
two
three
Exemplo 11: Executar script lento em lotes paralelos
Este exemplo executa um bloco de script que avalia uma cadeia de caracteres e dorme por um 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
O valor do parâmetro ThrottleLimit é definido como 4 para que a entrada seja processada em lotes de quatro.
A $using:
palavra-chave é usada para passar a $Message
variável para cada bloco de script paralelo.
Exemplo 12: Recuperar entradas de log em paralelo
Este exemplo recupera 50.000 entradas de log de 5 logs do sistema em um computador 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
O parâmetro Parallel especifica o bloco de script que é executado em paralelo para cada nome de log de entrada. O parâmetro ThrottleLimit garante que todos os cinco blocos de script sejam executados ao mesmo tempo.
Exemplo 13: Executar em paralelo como um trabalho
Este exemplo cria um trabalho que executa um bloco de script em paralelo, dois de cada 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 …
O parâmetro ThrottleLimit limita o número de blocos de script paralelos em execução por vez. O parâmetro AsJob faz com que o ForEach-Object
cmdlet retorne um objeto de trabalho em vez de transmitir a saída para o console. A $job
variável recebe o objeto de trabalho que coleta dados de saída e monitora o estado de execução. A $job.ChildJobs
propriedade contém os trabalhos filho que executam os blocos de script paralelos.
Exemplo 14: Usando referências de variáveis thread-safe
Este exemplo invoca blocos de script em paralelo para coletar objetos Process com nomes exclusivos.
$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
Uma única instância de um objeto ConcurrentDictionary é passada para cada bloco de script para coletar os objetos. Como o ConcurrentDictionary é thread-safe, é seguro ser modificado por cada script paralelo. Um objeto não thread-safe, como System.Collections.Generic.Dictionary, não seria seguro para uso aqui.
Observação
Este exemplo é um uso ineficiente do parâmetro Parallel . O script adiciona o objeto de entrada a um objeto de dicionário simultâneo. É trivial e não vale a pena invocar cada script em um thread separado. Executar ForEach-Object
sem o switch paralelo é mais eficiente e rápido. Este exemplo destina-se apenas a demonstrar como usar variáveis thread-safe.
Exemplo 15: Erros de gravação com execução paralela
Este exemplo grava no fluxo de erros em paralelo, em que a ordem dos erros gravados é aleatória.
1..3 | ForEach-Object -Parallel {
Write-Error "Error: $_"
}
Write-Error: Error: 1
Write-Error: Error: 3
Write-Error: Error: 2
Exemplo 16: Erros de encerramento na execução paralela
Este exemplo demonstra um erro de encerramento em um scriptblock em execução paralela.
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 é gravado porque o scriptblock paralelo para essa iteração foi encerrado.
Observação
Não há suporte para variáveis de parâmetro comuns PipelineVariable em Foreach-Object -Parallel
cenários, mesmo com a $using:
palavra-chave.
Exemplo 17: Passando variáveis no script paralelo aninhado ScriptBlockSet
Você pode criar uma variável fora de um Foreach-Object -Parallel
scriptblock com escopo e usá-la dentro do scriptblock com a $using
palavra-chave.
$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.
O bloco de script aninhado não pode acessar a $test2
variável e um erro é gerado.
Exemplo 18: Criando vários trabalhos que executam scripts em paralelo
O parâmetro ThrottleLimit limita o número de scripts paralelos em execução durante cada instância do ForEach-Object -Parallel
. Ele não limita o número de trabalhos que podem ser criados ao usar o parâmetro AsJob . Como os próprios trabalhos são executados simultaneamente, é possível criar vários trabalhos paralelos, cada um executando até o número limite de limitação de blocos 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
Este exemplo cria 10 trabalhos em execução. Cada trabalho não executa mais de 5 scripts simultaneamente. O número total de instâncias em execução simultaneamente é limitado a 50 (10 trabalhos vezes o ThrottleLimit de 5).
Parâmetros
-ArgumentList
Especifica uma matriz de argumentos para uma chamada de método. Para obter mais informações sobre o comportamento de ArgumentList, consulte about_Splatting.
Este parâmetro foi introduzido no Windows PowerShell 3.0.
Tipo: | Object[] |
Aliases: | Args |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-AsJob
Faz com que a invocação paralela seja executada como um trabalho do PowerShell. Um único objeto de trabalho é retornado em vez da saída dos blocos de script em execução. O objeto de trabalho contém trabalhos filho para cada bloco de script paralelo executado. Você pode usar o objeto de trabalho com qualquer um dos cmdlets de trabalho do PowerShell para ver o estado de execução e recuperar dados.
Esse parâmetro foi introduzido no PowerShell 7.0.
Tipo: | SwitchParameter |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-Begin
Especifica um bloco de script que é executado antes que esse cmdlet processe qualquer objeto de entrada. Esse bloco de script é executado apenas uma vez para todo o pipeline. Para obter mais informações sobre o bloqueio, consulte about_Functionsbegin
.
Tipo: | ScriptBlock |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-Confirm
Solicita sua confirmação antes de executar o cmdlet.
Tipo: | SwitchParameter |
Aliases: | cf |
Cargo: | Named |
Valor padrão: | False |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-End
Especifica um bloco de script que é executado depois que esse cmdlet processa todos os objetos de entrada. Esse bloco de script é executado apenas uma vez para todo o pipeline. Para obter mais informações sobre o bloqueio, consulte about_Functionsend
.
Tipo: | ScriptBlock |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-InputObject
Especifica os objetos de entrada. ForEach-Object
Executa o bloco de script ou a instrução de operação em cada objeto de entrada. Insira uma variável que contém os objetos ou digite um comando ou uma expressão que obtém os objetos.
Quando você usa o parâmetro InputObject com ForEach-Object
, em vez de canalizar os resultados do comando para ForEach-Object
, o valor InputObject é tratado como um único objeto. Isso é verdadeiro mesmo que o valor seja uma coleção resultante de um comando, como -InputObject (Get-Process)
.
Como InputObject não pode retornar propriedades individuais de uma matriz ou coleção de objetos, recomendamos que, se você usar ForEach-Object
para executar operações em uma coleção de objetos para os objetos que têm valores específicos em propriedades definidas, use ForEach-Object
no pipeline, conforme mostrado nos exemplos deste tópico.
Tipo: | PSObject |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | True |
Aceitar caracteres curinga: | False |
-MemberName
Especifica o nome da propriedade de membro a ser obtida ou o método de membro a ser chamado. Os membros devem ser membros de instância, não membros estáticos.
Caracteres curinga são permitidos, mas funcionam somente se a cadeia de caracteres resultante for resolvida para um valor exclusivo.
Por exemplo, se você executar Get-Process | ForEach -MemberName *Name
o , o padrão curinga corresponderá a mais de um membro, fazendo com que o comando falhe.
Este parâmetro foi introduzido no Windows PowerShell 3.0.
Tipo: | String |
Cargo: | 0 |
Valor padrão: | None |
Obrigatório: | True |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | True |
-Parallel
Especifica o bloco de script a ser usado para processamento paralelo de objetos de entrada. Insira um bloco de script que descreve a operação.
Esse parâmetro foi introduzido no PowerShell 7.0.
Tipo: | ScriptBlock |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | True |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-Process
Especifica a operação executada em cada objeto de entrada. Esse bloco de script é executado para cada objeto no pipeline. Para obter mais informações sobre o bloqueio, consulte about_Functionsprocess
.
Quando você fornece vários blocos de script para o parâmetro Process , o primeiro bloco de script é sempre mapeado para o begin
bloco. Se houver apenas dois blocos de script, o segundo bloco será mapeado para o process
bloco. Se houver três ou mais blocos de script, o primeiro bloco de script será sempre mapeado para o begin
bloco, o último bloco será mapeado para o end
bloco e os blocos do meio serão mapeados para o process
bloco.
Tipo: | ScriptBlock[] |
Cargo: | 0 |
Valor padrão: | None |
Obrigatório: | True |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-RemainingScripts
Especifica todos os blocos de script que não são usados pelo parâmetro Process .
Este parâmetro foi introduzido no Windows PowerShell 3.0.
Tipo: | ScriptBlock[] |
Cargo: | Named |
Valor padrão: | None |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-ThrottleLimit
Especifica o número de blocos de script que são executados em paralelo. Os objetos de entrada são bloqueados até que a contagem de blocos de script em execução fique abaixo do ThrottleLimit. O valor padrão é 5
.
O parâmetro ThrottleLimit limita o número de scripts paralelos em execução durante cada instância do ForEach-Object -Parallel
. Ele não limita o número de trabalhos que podem ser criados ao usar o parâmetro AsJob . Como os próprios trabalhos são executados simultaneamente, é possível criar vários trabalhos paralelos, cada um executando até o número limite de limitação de blocos de script simultâneos.
Esse parâmetro foi introduzido no PowerShell 7.0.
Tipo: | Int32 |
Cargo: | Named |
Valor padrão: | 5 |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-TimeoutSeconds
Especifica o número de segundos a aguardar para que todas as entradas sejam processadas em paralelo. Após o tempo limite especificado, todos os scripts em execução são interrompidos. E todos os objetos de entrada restantes a serem processados são ignorados. O valor padrão de 0
desabilita o tempo limite e ForEach-Object -Parallel
pode ser executado indefinidamente. Digitar Ctrl+C na linha de comando interrompe um comando em execução.ForEach-Object -Parallel
Esse parâmetro não pode ser usado junto com o parâmetro AsJob .
Esse parâmetro foi introduzido no PowerShell 7.0.
Tipo: | Int32 |
Cargo: | Named |
Valor padrão: | 0 |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-UseNewRunspace
Faz com que a invocação paralela crie um novo runspace para cada iteração de loop em vez de reutilizar runspaces do pool de runspace.
Esse parâmetro foi introduzido no PowerShell 7.1
Tipo: | SwitchParameter |
Cargo: | Named |
Valor padrão: | False |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
-WhatIf
Mostra o que aconteceria se o cmdlet fosse executado. O cmdlet não é executado.
Tipo: | SwitchParameter |
Aliases: | wi |
Cargo: | Named |
Valor padrão: | False |
Obrigatório: | False |
Aceitar a entrada de pipeline: | False |
Aceitar caracteres curinga: | False |
Entradas
Você pode canalizar qualquer objeto para esse cmdlet.
Saídas
Esse cmdlet retorna objetos que são determinados pela entrada.
Observações
O PowerShell inclui os seguintes aliases para ForEach-Object
:
- Todas as plataformas:
%
foreach
O ForEach-Object
cmdlet funciona de forma muito parecida com a instrução Foreach , exceto que você não pode canalizar a entrada para uma instrução Foreach . Para obter mais informações sobre a instrução Foreach , consulte about_Foreach.
A partir do PowerShell 4.0, Where
os ForEach
métodos foram adicionados para uso com coleções. Você pode ler mais sobre esses novos métodos aqui about_arrays
Usando ForEach-Object -Parallel
:
ForEach-Object -Parallel
executa cada bloco de script em um novo runspace. Os novos runspaces criam significativamente mais sobrecarga do que a execuçãoForEach-Object
com processamento sequencial. É importante usar Parallel onde a sobrecarga de execução em paralelo é pequena em comparação com o trabalho que o bloco de script executa. Por exemplo:- Scripts de computação intensiva em computadores com vários núcleos
- Scripts que passam tempo aguardando resultados ou fazendo operações de arquivo
O uso do parâmetro Parallel pode fazer com que os scripts sejam executados muito mais lentamente do que o normal. Especialmente se os scripts paralelos forem triviais. Experimente o Parallel para descobrir onde pode ser benéfico.
Ao executar em paralelo, os objetos decorados com ScriptProperties ou ScriptMethods não podem ter garantia de funcionar corretamente se forem executados em um runspace diferente daquele em que os scripts foram originalmente anexados a eles.
A invocação do bloco de script sempre tenta ser executada em seu home runspace, independentemente de onde ela é realmente invocada. No entanto,
ForEach-Object -Parallel
cria runspaces temporários que são excluídos após o uso, portanto, não há mais espaço de execução para os scripts serem executados.Esse comportamento pode funcionar desde que o home runspace ainda exista. No entanto, você pode não obter o resultado desejado se o script depender de variáveis externas que estão presentes apenas no runspace do chamador e não no home runspace.
Erros de não encerramento são gravados no fluxo de erros do cmdlet à medida que ocorrem em scriptblocks em execução paralela. Como a ordem de execução do bloco de script paralelo não é determinística, a ordem na qual os erros aparecem no fluxo de erros é aleatória. Da mesma forma, as mensagens gravadas em outros fluxos de dados, como aviso, detalhado ou informações, são gravadas nesses fluxos de dados em uma ordem indeterminada.
Erros de encerramento, como exceções, encerram a instância paralela individual dos scriptblocks nos quais eles ocorrem. Um erro de encerramento em um scriptblocks pode não causar o encerramento do
Foreach-Object
cmdlet. Os outros scriptblocks, em execução em paralelo, continuam a ser executados, a menos que também encontrem um erro de encerramento. O erro de encerramento é gravado no fluxo de dados de erro como um ErrorRecord com um FullyQualifiedErrorId dePSTaskException
. Os erros de encerramento podem ser convertidos em erros de não encerramento usando o PowerShelltry
/catch
outrap
blocos.Não há suporte para variáveis de parâmetro comuns PipelineVariable em cenários paralelos, mesmo com a
$using:
palavra-chave.Importante
O
ForEach-Object -Parallel
conjunto de parâmetros executa blocos de script em paralelo em threads de processo separados. A$using:
palavra-chave permite passar referências de variáveis do thread de invocação do cmdlet para cada thread de bloco de script em execução. Como os blocos de script são executados em threads diferentes, as variáveis de objeto passadas por referência devem ser usadas com segurança. Geralmente, é seguro ler de objetos referenciados que não mudam. Se você precisar modificar o estado do objeto, deverá usar objetos thread-safe, como tipos .NET System.Collection.Concurrent (consulte o Exemplo 14).