Skip to content

Commit

Permalink
Merge pull request #10556 from MicrosoftDocs/main
Browse files Browse the repository at this point in the history
10/20/2023 PM Publish
  • Loading branch information
Taojunshen authored Oct 20, 2023
2 parents d46662f + 00def06 commit 0109413
Show file tree
Hide file tree
Showing 8 changed files with 589 additions and 567 deletions.
137 changes: 65 additions & 72 deletions reference/5.1/Microsoft.PowerShell.Core/About/about_Foreach.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes a language command you can use to traverse all the items in a collection of items.
Locale: en-US
ms.date: 01/18/2022
ms.date: 10/20/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_foreach?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Foreach
Expand All @@ -14,11 +14,11 @@ collection of items.

## Long description

The `foreach` statement (also known as a `foreach` loop) is a language construct
for stepping through (iterating) a series of values in a collection of items.
The `foreach` statement is a language construct for iterating over a set of
values in a collection.

The simplest and most typical type of collection to traverse is an array.
Within a `foreach` loop, it is common to run one or more commands against each
Within a `foreach` loop, it's common to run one or more commands against each
item in an array.

## Syntax
Expand All @@ -29,37 +29,34 @@ The following shows the `foreach` syntax:
foreach ($<item> in $<collection>){<statement list>}
```

The part of the `foreach` statement enclosed in parenthesis represents a
variable and a collection to iterate. PowerShell creates the variable
`$<item>` automatically when the `foreach` loop runs. Prior to each
iteration through the loop, the variable is set to a value in the collection.
The block following a `foreach` statement `{<statement list>}` contains a set
of commands to execute against each item in a collection.
The part of the `foreach` statement inside parenthesis represents a variable
and a collection to iterate. PowerShell creates the variable `$<item>`
automatically when the `foreach` loop runs. At the start of each iteration,
`foreach` sets the item variable to the next value in the collection. The
`{<statement list>}` block contains the commands to execute for each iteration.

### Examples

For example, the `foreach` loop in the following example displays the values
in the `$letterArray` array.
For example, the `foreach` loop in the following example displays the values in
the `$letterArray` array.

```powershell
$letterArray = "a","b","c","d"
$letterArray = 'a','b','c','d'
foreach ($letter in $letterArray)
{
Write-Host $letter
}
```

In this example, the `$letterArray` array is created and initialized with the
string values `"a"`, `"b"`, `"c"`, and `"d"`. The first time the `foreach`
statement runs, it sets the `$letter` variable equal to the first item in
`$letterArray` (`"a"`). Then, it uses the `Write-Host` cmdlet to display the
letter a. The next time through the loop, `$letter` is set to `"b"`, and so
on. After the `foreach` loop displays the letter d, PowerShell exits
the loop.
In this example, the `$letterArray` contains the string values `a`, `b`,
`c`, and `d`. The first time the `foreach` statement runs, it sets the
`$letter` variable equal to the first item in `$letterArray` (`a`). Then, it
uses `Write-Host` to display the value. The next time through the loop,
`$letter` is set to `b`. The pattern repeats for each item in the array.

`foreach` statements can also be used together with cmdlets that return a
collection of items. In the following example, the Foreach statement steps
through the list of items that is returned by the `Get-ChildItem` cmdlet.
You can also use `foreach` statements with cmdlets that return a collection of
items. In the following example, the `foreach` statement steps through the list
of items returned by the `Get-ChildItem` cmdlet.

```powershell
foreach ($file in Get-ChildItem)
Expand All @@ -68,92 +65,82 @@ foreach ($file in Get-ChildItem)
}
```

You can refine the example by using an `if` statement to limit the results
that are returned. In the following example, the `foreach` statement performs
the same looping operation as the previous example, but it adds an `if`
statement to limit the results to files that are greater than 100 kilobytes
(KB):
You can refine the example using an `if` statement to limit the results that
are returned. In the following example, the `if` statement limits the results
to files that are greater than 100 kilobytes (KB):

```powershell
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100KB)
if ($file.Length -gt 100KB)
{
Write-Host $file
}
}
```

In this example, the `foreach` loop uses a property of the `$file` variable to
perform a comparison operation (`$file.length -gt 100KB`). The `$file`
variable contains all the properties in the object that is returned by the
`Get-ChildItem` cmdlet. Therefore, you can return more than just a file name.
In the next example, PowerShell returns the length and the last access time
perform a comparison operation (`$file.length -gt 100KB`). The `$file` variable
has all the properties of the object returned by the `Get-ChildItem`.

In the next example, the script displays the length and the last access time
inside the statement list:

```powershell
foreach ($file in Get-ChildItem)
{
if ($file.length -gt 100KB)
if ($file.Length -gt 100KB)
{
Write-Host $file
Write-Host $file.length
Write-Host $file.lastaccesstime
Write-Host $file.Length
Write-Host $file.LastAccessTime
}
}
```

In this example, you are not limited to running a single command in a
statement list.

You can also use a variable outside a `foreach` loop and increment the
variable inside the loop. The following example counts files over 100 KB in
size:
You can also use variables from outside a `foreach` loop. The following example
counts files over 100 KB in size:

```powershell
$i = 0
foreach ($file in Get-ChildItem) {
if ($file.length -gt 100KB) {
Write-Host $file "file size:" ($file.length / 1024).ToString("F0") KB
Write-Host $file 'file size:' ($file.length / 1024).ToString('F0') KB
$i = $i + 1
}
}
if ($i -ne 0) {
Write-Host
Write-Host $i " file(s) over 100 KB in the current directory."
Write-Host $i ' file(s) over 100KB in the current directory.'
}
else {
Write-Host "No files greater than 100 KB in the current directory."
Write-Host 'No files greater than 100KB in the current directory.'
}
```

In the preceding example, the `$i` variable is set to `0` outside the loop,
and the variable is incremented inside the loop for each file that is found
that is larger than 100 KB. When the loop exits, an `if` statement evaluates
the value of `$i` to display a count of all the files over 100 KB. Or, it
displays a message stating that no files over 100 KB were found.
In the preceding example, `$i` starts with a value of `0` outside the loop.
Then, `$i` is incremented inside the loop for each file that's larger than
100KB. When the loop exits, an `if` statement evaluates the value of `$i` to
display a count of files over 100KB.

The previous example also demonstrates how to format the file length results:

```powershell
($file.length / 1024).ToString("F0")
($file.length / 1024).ToString('F0')
```

The value is divided by 1,024 to show the results in kilobytes rather than
bytes, and the resulting value is then formatted using the fixed-point format
specifier to remove any decimal values from the result. The 0 makes the format
specifier show no decimal places.
specifier to remove any decimal values from the result. The `0` makes the
format specifier show no decimal places.

In the following example, the function defined parses PowerShell scripts and
script modules and returns the location of functions contained within. The
example demonstrates how to use the `MoveNext` method (which works similarly
to `skip X` on a `For` loop) and the `Current` property of the `$foreach`
variable inside of a foreach script block. The example function can find
functions in a script even if there are unusually- or inconsistently-spaced
function definitions that span multiple lines.
The following function parses PowerShell scripts and script modules and returns
the location of functions contained within. The example demonstrates how to use
the `MoveNext` method and the `Current` property of the `$foreach` variable
inside of a `foreach` script block.

For more information, see [Using Enumerators](about_Automatic_Variables.md#using-enumerators).
For more information, see [Using Enumerators][02].

```powershell
function Get-FunctionPosition {
Expand All @@ -171,23 +158,19 @@ function Get-FunctionPosition {
process {
try {
$filesToProcess = if ($_ -is [System.IO.FileSystemInfo]) {
Write-Verbose "From pipeline"
$_
} else {
Write-Verbose "From parameter, $Path"
Get-Item -Path $Path
}
$parser = [System.Management.Automation.Language.Parser]
Write-Verbose "lets start the foreach loop on `$filesToProcess with $($filesToProcess.count) as count"
foreach ($item in $filesToProcess) {
Write-Verbose "$item"
if ($item.PSIsContainer -or
$item.Extension -notin @('.ps1', '.psm1')) {
continue
}
$tokens = $errors = $null
$parser::ParseFile($item.FullName, ([REF]$tokens),
([REF]$errors)) | Out-Null
$ast = $parser::ParseFile($item.FullName, ([ref]$tokens),
([ref]$errors))
if ($errors) {
$msg = "File '{0}' has {1} parser errors." -f $item.FullName,
$errors.Count
Expand All @@ -209,8 +192,12 @@ function Get-FunctionPosition {
LineNumber = $position
Path = $item.FullName
}
Add-Member -InputObject $functionPosition `
-TypeName FunctionPosition -PassThru
$addMemberSplat = @{
InputObject = $functionPosition
TypeName = 'FunctionPosition'
PassThru = $true
}
Add-Member @addMemberSplat
}
}
}
Expand All @@ -223,6 +210,12 @@ function Get-FunctionPosition {

## See also

- [about_Automatic_Variables](about_Automatic_Variables.md)
- [about_If](about_If.md)
- [ForEach-Object](xref:Microsoft.PowerShell.Core.ForEach-Object)
- [about_Automatic_Variables][01]
- [about_If][03]
- [ForEach-Object][04]

<!-- link references -->
[01]: about_Automatic_Variables.md
[02]: about_Automatic_Variables.md#using-enumerators
[03]: about_If.md
[04]: xref:Microsoft.PowerShell.Core.ForEach-Object
Loading

0 comments on commit 0109413

Please sign in to comment.