ForEach-Object

Wykonuje operację względem każdego elementu w kolekcji obiektów wejściowych.

Składnia

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
            [-InputObject <PSObject>]
            -Parallel <ScriptBlock>
            [-ThrottleLimit <Int32>]
            [-TimeoutSeconds <Int32>]
            [-AsJob]
            [-WhatIf]
            [-Confirm]
            [<CommonParameters>]

Opis

Polecenie ForEach-Object cmdlet wykonuje operację na każdym elemencie w kolekcji obiektów wejściowych. Obiekty wejściowe mogą być przesyłane potokami do polecenia cmdlet lub określone przy użyciu parametru InputObject .

Począwszy od Windows PowerShell 3.0, istnieją dwa różne sposoby konstruowania ForEach-Object polecenia.

  • Blok skryptu. Aby określić operację, możesz użyć bloku skryptu. W bloku skryptu użyj zmiennej $_ do reprezentowania bieżącego obiektu. Blok skryptu jest wartością parametru Process . Blok skryptu może zawierać dowolny skrypt programu PowerShell.

    Na przykład następujące polecenie pobiera wartość właściwości ProcessName każdego procesu na komputerze.

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

    ForEach-Object program obsługuje bloki begin, processi end zgodnie z opisem w about_functions.

    Uwaga

    Bloki skryptu są uruchamiane w zakresie wywołującego. W związku z tym bloki mają dostęp do zmiennych w tym zakresie i mogą tworzyć nowe zmienne, które utrzymują się w tym zakresie po zakończeniu wykonywania polecenia cmdlet.

  • Instrukcja Operation. Można również napisać instrukcję operacji, która jest znacznie bardziej podobna do języka naturalnego. Można użyć instrukcji operation, aby określić wartość właściwości lub wywołać metodę. Instrukcje operacji zostały wprowadzone w Windows PowerShell 3.0.

    Na przykład następujące polecenie pobiera również wartość właściwości ProcessName każdego procesu na komputerze.

    Get-Process | ForEach-Object ProcessName

  • Równoległy blok uruchamiania skryptu. Począwszy od programu PowerShell 7.0, dostępny jest trzeci zestaw parametrów, który uruchamia równolegle każdy blok skryptów. Parametr ThrottleLimit ogranicza liczbę uruchomionych jednocześnie skryptów równoległych. Tak jak poprzednio, użyj zmiennej $_ do reprezentowania bieżącego obiektu wejściowego w bloku skryptu. Użyj słowa kluczowego $using: , aby przekazać odwołania do zmiennej do uruchomionego skryptu.

    W programie PowerShell 7 dla każdej iteracji pętli jest tworzona nowa przestrzeń uruchomieniowa w celu zapewnienia maksymalnej izolacji. Może to być duża wydajność i trafienie zasobów, jeśli praca, którą wykonujesz, jest niewielka w porównaniu z tworzeniem nowych obszarów działania lub jeśli istnieje wiele iteracji wykonujących znaczną pracę. Od programu PowerShell 7.1 przestrzenie uruchomieniowe z puli obszarów runspace są domyślnie używane ponownie. Rozmiar puli przestrzeni uruchomieniowej jest określany przez parametr ThrottleLimit . Domyślny rozmiar puli przestrzeni uruchomieniowej to 5. Nadal można utworzyć nową przestrzeń uruchomieniową dla każdej iteracji przy użyciu przełącznika UseNewRunspace .

    Domyślnie skrypty równoległe używają bieżącego katalogu roboczego obiektu wywołującego, który uruchamiał zadania równoległe.

    Aby uzyskać więcej informacji, zobacz sekcję UWAGI w tym artykule.

Przykłady

Przykład 1. Dzielenie liczb całkowitych w tablicy

Ten przykład przyjmuje tablicę trzech liczb całkowitych i dzieli każdą z nich o 1024.

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

29.296875
55.466796875
12.140625

Przykład 2. Pobieranie długości wszystkich plików w katalogu

W tym przykładzie pliki i katalogi są przetwarzane w katalogu $PSHOMEinstalacyjnym programu PowerShell.

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

Jeśli obiekt nie jest katalogiem, blok skryptu pobiera nazwę pliku, dzieli wartość jego właściwości Length przez 1024 i dodaje spację (" ") w celu oddzielenia go od następnego wpisu. Polecenie cmdlet używa właściwości PSISContainer do określenia, czy obiekt jest katalogiem.

Przykład 3: Działanie na najnowszych zdarzeniach systemowych

Ten przykład zapisuje 1000 najnowszych zdarzeń z dziennika zdarzeń systemu do pliku tekstowego. Bieżący czas jest wyświetlany przed i po przetworzeniu zdarzeń.

$Events = Get-EventLog -LogName System -Newest 1000
$events | ForEach-Object -Begin {Get-Date} -Process {Out-File -FilePath Events.txt -Append -InputObject $_.Message} -End {Get-Date}

Get-EventLog Pobiera 1000 najnowszych zdarzeń z dziennika zdarzeń systemu i zapisuje je w zmiennej $Events . $Events polecenie jest następnie przesyłane potokami ForEach-Object do polecenia cmdlet. Parametr Begin wyświetla bieżącą datę i godzinę. Następnie parametr Process używa Out-File polecenia cmdlet do utworzenia pliku tekstowego o nazwie events.txt i przechowuje właściwość komunikatu każdego zdarzenia w tym pliku. Na koniec parametr End służy do wyświetlania daty i godziny po zakończeniu całego przetwarzania.

Przykład 4. Zmiana wartości klucza rejestru

W tym przykładzie zmienia się wartość wpisu rejestru RemotePath we wszystkich podkluczach pod kluczem HKCU:\Network na tekst wielkie litery.

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

Możesz użyć tego formatu, aby zmienić formularz lub zawartość wartości wpisu rejestru.

Każdy podklucz w kluczu sieci reprezentuje zamapowany dysk sieciowy, który ponownie łączy się podczas logowania. Wpis RemotePath zawiera ścieżkę UNC podłączonego dysku. Jeśli na przykład mapujesz dysk E: na \\Server\Sharewartość , zostanie utworzony HKCU:\Network podklucz E z wartością rejestru RemotePath ustawioną na \\Server\Sharewartość .

Polecenie używa Get-ItemProperty polecenia cmdlet , aby pobrać wszystkie podklucze klucza sieciowego i Set-ItemProperty polecenie cmdlet, aby zmienić wartość wpisu rejestru RemotePath w każdym kluczu. W poleceniu Set-ItemProperty ścieżka jest wartością właściwości PSPath klucza rejestru. Jest to właściwość obiektu microsoft .NET Framework, który reprezentuje klucz rejestru, a nie wpis rejestru. Polecenie używa metody ToUpper() wartości RemotePath , która jest ciągiem (REG_SZ).

Ponieważ Set-ItemProperty zmienia właściwość każdego klucza, ForEach-Object polecenie cmdlet jest wymagane do uzyskania dostępu do właściwości.

Przykład 5. Użycie zmiennej automatycznej $Null

W tym przykładzie pokazano efekt potokowania zmiennej automatycznej $NullForEach-Object do polecenia cmdlet.

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

Hello
Hello
Hello
Hello

Ponieważ program PowerShell traktuje wartość null jako jawny symbol zastępczy, ForEach-Object polecenie cmdlet generuje wartość dla $Nullparametru , podobnie jak w przypadku innych obiektów, które są do niego przesyłane potokiem.

Przykład 6. Pobieranie wartości właściwości

Ten przykład pobiera wartość właściwości Path wszystkich zainstalowanych modułów programu PowerShell przy użyciu parametru ForEach-ObjectMemberName polecenia cmdlet.

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

Drugie polecenie jest równoważne pierwszemu. Używa Foreach aliasu ForEach-Object polecenia cmdlet i pomija nazwę parametru MemberName , który jest opcjonalny.

Polecenie ForEach-Object cmdlet jest przydatne do pobierania wartości właściwości, ponieważ pobiera wartość bez zmiany typu, w przeciwieństwie do poleceń cmdlet Format lub Select-Object polecenia cmdlet, które zmieniają typ wartości właściwości.

Przykład 7. Dzielenie nazw modułów na nazwy składników

W tym przykładzie przedstawiono trzy sposoby dzielenia dwóch nazw modułów rozdzielonych kropkami na ich nazwy składników. Polecenia wywołają metodę Split ciągów. Trzy polecenia używają innej składni, ale są równoważne i wymienne. Dane wyjściowe są takie same dla wszystkich trzech przypadków.

"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

Pierwsze polecenie używa tradycyjnej składni, która zawiera blok skryptu i bieżący operator $_obiektu . Używa składni kropki, aby określić metodę i nawiasy, aby ująć argument ogranicznika.

Drugie polecenie używa parametru MemberName , aby określić metodę Split i parametr ArgumentList w celu zidentyfikowania kropki (.) jako ogranicznika podziału.

Trzecie polecenie używa aliasu ForEach-ObjectForeach polecenia cmdlet i pomija nazwy parametrów MemberName i ArgumentList, które są opcjonalne.

Przykład 8: Używanie ForEach-Object z dwoma blokami skryptów

W tym przykładzie przekazujemy dwa bloki skryptu w pozycji. Wszystkie bloki skryptu są powiązane z parametrem Process . Są one jednak traktowane tak, jakby zostały przekazane do parametrów Początek i Proces .

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

begin
process
process

Przykład 9: Używanie ForEach-Object z więcej niż dwoma blokami skryptu

W tym przykładzie przekazujemy dwa bloki skryptu w pozycji. Wszystkie bloki skryptu są powiązane z parametrem Process . Są one jednak traktowane tak, jakby zostały przekazane do parametrów Początek, Proces i Koniec .

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

begin
process A
process B
process A
process B
end

Uwaga

Pierwszy blok skryptu jest zawsze mapowany na begin blok, ostatni blok jest mapowany na end blok, a bloki między nimi są mapowane na process blok.

Przykład 10: Uruchamianie wielu bloków skryptu dla każdego elementu potoku

Jak pokazano w poprzednim przykładzie, wiele bloków skryptu przekazanych przy użyciu parametru Proces jest mapowane na parametry Początek i Koniec . Aby uniknąć tego mapowania, należy podać jawne wartości parametrów Begin i End .

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

one
two
three
one
two
three

Przykład 11: Uruchamianie powolnego skryptu w równoległych partiach

W tym przykładzie jest uruchamiany prosty blok skryptu, który ocenia ciąg i śpi przez jedną sekundę.

$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

Wartość parametru ThrottleLimit jest ustawiona na 4, aby dane wejściowe są przetwarzane w partiach czterech. Słowo $using: kluczowe jest używane do przekazywania zmiennej $Message do każdego bloku skryptu równoległego.

Przykład 12: Równoległe pobieranie wpisów dziennika

Ten przykład pobiera 50 000 wpisów dziennika z 5 dzienników systemowych na lokalnym komputerze z systemem Windows.

$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

Parametr Parallel określa blok skryptu uruchamiany równolegle dla każdej nazwy dziennika wejściowego. Parametr ThrottleLimit zapewnia, że wszystkie pięć bloków skryptu jest uruchamianych w tym samym czasie.

Przykład 13: Równoległe uruchamianie jako zadanie

W tym przykładzie jest uruchamiany prosty blok skryptu równolegle, tworząc jednocześnie dwa zadania w tle.

$job = 1..10 | ForEach-Object -Parallel {
    "Output: $_"
    Start-Sleep 1
} -ThrottleLimit 2 -AsJob

$job | Receive-Job -Wait

Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8
Output: 9
Output: 10

zmienna $job odbiera obiekt zadania, który zbiera dane wyjściowe i monitoruje stan działania. Obiekt zadania jest przełączany potokiem do Receive-Job parametru przełącznika oczekiwania . A to przesyła strumieniowo dane wyjściowe do konsoli, tak jakby ForEach-Object -Parallel zostało uruchomione bez zadania AsJob.

Przykład 14: Używanie odwołań do zmiennej bezpiecznej wątku

W tym przykładzie są wywoływane bloki skryptów równolegle w celu zbierania unikatowych obiektów procesu.

$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

Pojedyncze wystąpienie obiektu ConcurrentDictionary jest przekazywane do każdego bloku skryptu w celu zbierania obiektów. Ponieważ funkcja ConcurrentDictionary jest bezpieczna dla wątków, można ją bezpiecznie modyfikować przy użyciu każdego skryptu równoległego. Niewątkowy obiekt, taki jak System.Collections.Generic.Dictionary, nie byłby bezpieczny do użycia w tym miejscu.

Uwaga

W tym przykładzie jest bardzo nieefektywne użycie parametru Parallel . Skrypt po prostu dodaje obiekt wejściowy do współbieżnego obiektu słownika. Jest to trywialne i nie warto wywołać każdego skryptu w osobnym wątku. Normalne działanie ForEach-Object bez przełącznika równoległego jest znacznie wydajniejsze i szybsze. W tym przykładzie pokazano tylko, jak używać zmiennych bezpiecznych wątków.

Przykład 15: Zapisywanie błędów z równoległym wykonywaniem

W tym przykładzie jest zapisywany strumień błędów równolegle, gdzie kolejność zapisanych błędów jest losowa.

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

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

Przykład 16. Błędy kończenie równoległego wykonywania

W tym przykładzie pokazano błąd zakończenia w jednym równoległym uruchomionym skryblokowaniu.

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 nigdy nie jest zapisywany, ponieważ blok równoległy dla tej iteracji został zakończony.

Uwaga

Typowe zmienne parametrów PipelineVariablenie są obsługiwane w scenariuszach nawet przy Foreach-Object -Parallel użyciu słowa kluczowego$using:.

Przykład 17: Przekazywanie zmiennych w zagnieżdżonym skryptie równoległym ScriptBlockSet

Możesz utworzyć zmienną poza zakresem Foreach-Object -Parallel scriptblock i użyć jej wewnątrz skryptblock z $using słowem kluczowym.

$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' cannot be retrieved because it has not been set in the local session.

Zagnieżdżony skryptblock nie może uzyskać dostępu do zmiennej $test2 i zostanie zgłoszony błąd.

Parametry

-ArgumentList

Określa tablicę argumentów do wywołania metody. Aby uzyskać więcej informacji na temat zachowania argumentlist, zobacz about_Splatting.

Ten parametr został wprowadzony w Windows PowerShell 3.0.

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

-AsJob

Powoduje równoległe wywołanie uruchamiane jako zadanie programu PowerShell. Pojedynczy obiekt zadania jest zwracany zamiast danych wyjściowych z uruchomionych bloków skryptu. Obiekt zadania zawiera zadania podrzędne dla każdego równoległego bloku skryptu, który jest uruchamiany. Obiekt zadania może być używany przez wszystkie polecenia cmdlet zadania programu PowerShell, aby monitorować stan działania i pobierać dane.

Ten parametr został wprowadzony w programie PowerShell 7.0.

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

-Begin

Określa blok skryptu uruchamiany przed wykonaniem tego polecenia cmdlet przetwarza wszystkie obiekty wejściowe. Ten blok skryptu jest uruchamiany tylko raz dla całego potoku. Aby uzyskać więcej informacji na temat begin bloku, zobacz about_Functions.

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

-Confirm

Monituje o potwierdzenie przed uruchomieniem polecenia cmdlet.

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

-End

Określa blok skryptu uruchamiany po tym poleceniu cmdlet przetwarza wszystkie obiekty wejściowe. Ten blok skryptu jest uruchamiany tylko raz dla całego potoku. Aby uzyskać więcej informacji na temat end bloku, zobacz about_Functions.

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

-InputObject

Określa obiekty wejściowe. ForEach-Object uruchamia instrukcję bloku skryptu lub operacji dla każdego obiektu wejściowego. Wprowadź zmienną zawierającą obiekty lub wpisz polecenie lub wyrażenie, które pobiera obiekty.

Jeśli używasz parametru InputObject z parametrem ForEach-Object, zamiast potokowania wyników polecenia do ForEach-Objectmetody , wartość InputObject jest traktowana jako pojedynczy obiekt. Jest to prawda, nawet jeśli wartość jest kolekcją, która jest wynikiem polecenia, takiego jak -InputObject (Get-Process). Ponieważ obiekt InputObject nie może zwrócić poszczególnych właściwości z tablicy lub kolekcji obiektów, zalecamy wykonanie ForEach-Object operacji na kolekcji obiektów dla tych obiektów, które mają określone wartości w zdefiniowanych właściwościach, należy użyć ForEach-Object w potoku, jak pokazano w przykładach w tym temacie.

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

-MemberName

Określa właściwość do pobrania lub metody do wywołania.

Dozwolone są symbole wieloznaczne, ale działają tylko wtedy, gdy wynikowy ciąg jest rozpoznawany jako unikatowa wartość. Jeśli na przykład uruchomisz polecenie Get-Process | ForEach -MemberName *Name, wzorzec symbolu wieloznakowego pasuje do więcej niż jednego elementu członkowskiego, co powoduje niepowodzenie polecenia.

Ten parametr został wprowadzony w Windows PowerShell 3.0.

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

-Parallel

Określa blok skryptu, który ma być używany do przetwarzania równoległego obiektów wejściowych. Wprowadź blok skryptu opisujący operację.

Ten parametr został wprowadzony w programie PowerShell 7.0.

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

-Process

Określa operację wykonywaną na każdym obiekcie wejściowym. Ten blok skryptu jest uruchamiany dla każdego obiektu w potoku. Aby uzyskać więcej informacji na temat process bloku, zobacz about_Functions.

Po podaniu wielu bloków skryptu do parametru Process pierwszy blok skryptu jest zawsze mapowany na begin blok. Jeśli istnieją tylko dwa bloki skryptu, drugi blok jest mapowany na process blok. Jeśli istnieją co najmniej trzy bloki skryptu, pierwszy blok skryptu jest zawsze mapowany na begin blok, ostatni blok jest mapowany na end blok, a bloki między są mapowane na process blok.

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

-RemainingScripts

Określa wszystkie bloki skryptu, które nie są pobierane przez parametr Procesu .

Ten parametr został wprowadzony w Windows PowerShell 3.0.

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

-ThrottleLimit

Określa liczbę bloków skryptu, które równolegle. Obiekty wejściowe są blokowane, dopóki liczba uruchomionych bloków skryptu nie spadnie poniżej wartości ThrottleLimit. Wartość domyślna to 5.

Ten parametr został wprowadzony w programie PowerShell 7.0.

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

-TimeoutSeconds

Określa liczbę sekund oczekiwania na równoległe przetworzenie wszystkich danych wejściowych. Po upływie określonego limitu czasu wszystkie uruchomione skrypty zostaną zatrzymane. Pozostałe obiekty wejściowe do przetworzenia są ignorowane. Wartość domyślna wyłącza 0 limit czasu i ForEach-Object -Parallel może działać w nieskończoność. Naciśnięcie klawiszy Ctrl+C w wierszu polecenia powoduje zatrzymanie uruchomionego ForEach-Object -Parallel polecenia. Tego parametru nie można użyć wraz z parametrem AsJob .

Ten parametr został wprowadzony w programie PowerShell 7.0.

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

-UseNewRunspace

Powoduje wywołanie równoległe w celu utworzenia nowej przestrzeni uruchomieniowej dla każdej iteracji pętli zamiast ponownego użycia przestrzeni uruchomieniowych z puli obszarów uruchamiania.

Ten parametr został wprowadzony w programie PowerShell 7.1

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

-WhatIf

Pokazuje, co się stanie po uruchomieniu polecenia cmdlet. Polecenie cmdlet nie zostało uruchomione.

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

Dane wejściowe

PSObject

Możesz przekazać dowolny obiekt do tego polecenia cmdlet.

Dane wyjściowe

PSObject

To polecenie cmdlet zwraca obiekty określone przez dane wejściowe.

Uwagi

Polecenie ForEach-Object cmdlet działa podobnie jak instrukcja Foreach , z tą różnicą, że nie można potokować danych wejściowych do instrukcji Foreach . Aby uzyskać więcej informacji na temat instrukcji Foreach , zobacz about_Foreach.

Począwszy od programu PowerShell 4.0, Where a ForEach metody zostały dodane do użycia z kolekcjami. Więcej informacji o tych nowych metodach można znaleźć tutaj about_arrays

Za pomocą polecenia ForEach-Object -Parallel:

  • Zestaw ForEach-Object -Parallel parametrów używa wewnętrznego interfejsu API programu PowerShell do uruchamiania każdego bloku skryptu w nowej przestrzeni uruchomieniowej. Jest to znacznie większe obciążenie niż zwykle z ForEach-Object przetwarzaniem sekwencyjnym. Ważne jest, aby użyć funkcji Parallel , w której obciążenie uruchomione równolegle jest małe w porównaniu do pracy wykonywanej przez blok skryptów. Przykład:

    • Skrypty intensywnie korzystające z obliczeń na maszynach wielordzeniowych
    • Skrypty, które spędzają czas na oczekiwaniu na wyniki lub wykonywanie operacji na plikach

    Użycie parametru Parallel może spowodować, że skrypty działają znacznie wolniej niż normalnie. Zwłaszcza jeśli skrypty równoległe są proste. Eksperymentuj z równoległym , aby dowiedzieć się, gdzie może być korzystne.

  • W przypadku równoległego uruchamiania obiektów ozdobionych właściwościami ScriptProperties lub ScriptMethods nie można zagwarantować prawidłowego działania, jeśli są one uruchamiane w innej przestrzeni uruchomieniowej niż skrypty zostały pierwotnie dołączone do nich.

    Wywołanie scriptblock zawsze próbuje uruchomić w swojej głównej przestrzeni runspace, niezależnie od tego, gdzie jest on rzeczywiście wywoływany. ForEach-Object -Parallel Jednak tworzy tymczasowe przestrzenie uruchomieniowe, które zostaną usunięte po użyciu, więc nie ma już przestrzeni uruchamiania skryptów do wykonania.

    To zachowanie może działać tak długo, jak nadal istnieje główna przestrzeń uruchomieniowa. Jednak nie można uzyskać żądanego wyniku, jeśli skrypt jest zależny od zmiennych zewnętrznych, które są obecne tylko w przestrzeni uruchomieniowej obiektu wywołującego, a nie w przestrzeni uruchamiania domu .

  • Błędy niepowodujące zakończenia są zapisywane w strumieniu błędów polecenia cmdlet podczas równoległego uruchamiania bloków skryptów. Ponieważ równoległa kolejność wykonywania skryptblock nie jest deterministyczna, kolejność, w której błędy pojawiają się w strumieniu błędów, jest losowa. Podobnie komunikaty zapisywane w innych strumieniach danych, takie jak ostrzeżenie, pełne lub informacje, są zapisywane w tych strumieniach danych w nieokreślonej kolejności.

    Błędy kończenie, takie jak wyjątki, przerywają poszczególne równoległe wystąpienia bloków skryptów, w których występują. Błąd zakończenia w jednym skryblokowaniu może nie spowodować zakończenia Foreach-Object polecenia cmdlet. Inne bloki skryptów, uruchomione równolegle, nadal działają, chyba że napotkają również błąd zakończenia. Błąd zakończenia jest zapisywany w strumieniu danych błędu jako BłądRecord z w pełniqualifiedErrorId .PSTaskException Błędy zakończenia można przekonwertować na błędy niezwiązane z kończeniem przy użyciu bloków try/catch lub pułapki programu PowerShell.

  • Typowe zmienne parametrów PipelineVariablenie są obsługiwane w scenariuszach równoległych nawet przy użyciu słowa kluczowego$using:.

    Ważne

    Zestaw ForEach-Object -Parallel parametrów uruchamia bloki skryptów równolegle w oddzielnych wątkach procesu. Słowo $using: kluczowe umożliwia przekazywanie odwołań zmiennych z wątku wywołania polecenia cmdlet do każdego uruchomionego wątku blokowego skryptu. Ponieważ bloki skryptu są uruchamiane w różnych wątkach, zmienne obiektu przekazywane przez odwołanie muszą być bezpiecznie używane. Ogólnie rzecz biorąc, bezpieczne jest odczytywanie odwołanych obiektów, które nie zmieniają się. Jeśli jednak stan obiektu jest modyfikowany, należy użyć bezpiecznych obiektów wątków, takich jak .NET System.Collection.Concurrent types (Zobacz przykład 11).