主题
    about_Foreach

简短说明
    说明可用于遍历项集合中的所有项的一种语言命令。


详细说明
    Foreach 语句(也称为 Foreach 循环)是一种用于逐一遍历(循环访问)项集合中一系列值的语言
    结构。


    可遍历的最简单、最典型的集合类型是数组。在 Foreach 循环中,经常会针对数组中的
    每一项运行一个或多个命令。


  语法        
      下面显示了 Foreach 语法:

        
          foreach ($<item> in $<collection>){<statement list>}


  命令管道之外的 Foreach 语句 Foreach 语句中括在括号中的部分表示一个变量和一个要循环访问的集
  合。Windows PowerShell 在运行 Foreach 循环时自动创建该变量 ($<item>)。在每次迭代通过循
  环之前,该变量将设置为集合中的值。Foreach 语句后面的语句块 {<statement list>} 包含一组要
  针对集合中的各项执行的命令。
 

  示例
      例如,以下示例中的 Foreach 循环显示了 $letterArray 数组中的值。

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

      
      在此示例中,将创建 $letterArray 数组,并使用字符串值"a"、"b"、"c"和"d"对其进行初
      始化。Foreach 语句第一次运行时,将 $letter 变量设置为与 $letterArray 中的第一项
      ("a")相等的值。然后,该语句使用 Write-Host cmdlet 显示字母 a。下一次通过循环时,
      $letter 被设置为"b",依此类推。在 Foreach 循环显示字母 d 之后,Windows PowerShell 
      退出循环。


      要在 Windows PowerShell 命令提示符下将 Foreach 语句作为命令运行,则整个 Foreach 
      语句必须单占一行。如果将命令放入 .ps1 脚本文件中,则整个 Foreach 语句不必单占一行。


      还可以将 Foreach 语句与可返回项集合的 cmdlet 一起使用。在以下示例中,Foreach 语句将逐一
      通过由 Get-ChildItem cmdlet 返回的项列表。


          foreach ($file in Get-ChildItem)
          {
              Write-Host $file
          }


      可以通过使用 If 语句限制返回的结果来优化该示例。在以下示例中,Foreach 语句将执行与前一示
      例相同的循环操作,但是该示例还添加了 If 语句,以将结果限制为大于 100 千字节 (KB) 的文件:


          foreach ($file in Get-ChildItem)
          {
              if ($file.length -gt 100k)
              {
                  Write-Host $file
              }
          }


      在此示例中,Foreach 循环使用 $file 变量的属性来执行比较运算 ($file.length -gt 100k)。
      $file 变量包含由 Get-ChildItem cmdlet 返回的对象中的所有属性。因此,返回的结果不止只
      有文件名。在下一示例中,Windows PowerShell 将在语句列表中返回长度和上次访问时间:


          foreach ($file in Get-ChildItem)
          {
              if ($file.length -gt 100k)
              {
                  Write-Host $file
                  Write-Host $file.length
                  Write-Host $file.lastaccesstime }
          }

    
      在此示例中,并不限于只在语句列表中执行一条命令。

      
      也可以在 Foreach 循环之外使用变量,并在循环内递增该变量。以下示例对超过 100 KB 的文件进
      行计数:
      
  
          $i = 0
          foreach ($file in Get-ChildItem)
          {
              if ($file.length -gt 100k) 
              {
                  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."}
          else 
          {
              Write-Host "No files greater than 100 KB in the current 
          directory."
          }


      在上一示例中,在循环外将 $i 变量设置为 0,并在每找到一个大于 100 KB 的文件时在循环内将该
      变量递增 1。退出循环时,If 语句对 $i 的值进行计算,以显示超过 100 KB 的所有文件的计数。
      或者,该语句将显示一条消息,表明没有找到超过 100 KB 的文件。


      上一示例还演示了设置文件长度结果格式的方式:


          ($file.length / 1024).ToString("F0")


      该值除以 1024 即可以千字节(而不是字节)为单位显示结果,随后使用固定点格式说明符对计算得
      到的值进行格式设置,以删除结果中的所有小数值。"0"将使格式说明符不显示小数位。


  命令管道之内的 Foreach 语句 
      当 Foreach 出现在命令管道中时,Windows PowerShell 将使用 foreach 别名调用 ForEach-Object 命令。
      在命令管道中使用 foreach 别名时,无需像在 Foreach 语句中那样包含 ($<item> in $<collection>) 语法。
      这是因为管道中的前一命令已提供此信息。在命令管道中使用的 foreach 别名的语法如下:
        

          <command> | foreach {<command_block>}
     

      例如,以下命令管道中的 Foreach 循环将显示工作集(内存使用量)超过 20 兆字节 (MB) 的所有
      进程。Windows PowerShell 通过管道将 Get-Process 命令的输出传递给 foreach 别名。在 
      foreach 别名命令块内,$_.WS 变量包含由 Get-Process cmdlet 传递给它的 WS(工作集)
      属性的值。(声明的 $_ 部分是 Windows Script Host [WSH] 自动变量,WS 部分是属性。)
      If 语句使用条件语句来判断工作集是否大于 20 MB(20,000,000 字节)。如果是,则将显示存储
      在 $_.name 变量中的该进程的名称,并以兆字节为单位显示工作集大小。
      如果不存在超过 20 MB 的进程工作集,则不显示任何内容。


          Write-Host "Processes with working-sets greater than 20 MB" Get-
          Process | foreach {
              if ($_.WS -gt 20m)
              {
                  Write-Host $_.name ": "
         ($_.WS/1m).ToString("F0") MB -Separator ""
              }
          }


      foreach 别名还支持起始命令块、中间命令块和结尾命令块。起始命令块和结尾命令块只运行一
      次,而中间命令块在每次 Foreach 循环访问一次集合或数组时都运行一次。
        

      Foreach 别名在具有起始、中间和结尾命令块组的命令管道中使用时的语法为:
        

          <command> | foreach {<beginning command_block>}{<middle 
          command_block>}{<ending command_block>}

 
      以下示例演示了起始、中间和结尾命令块的用法。


          Get-ChildItem | foreach {
          $fileCount = $directoryCount = 0}{
          if ($_.PsIsContainer) {$directoryCount++} else 
          {$fileCount++}}{ "$directoryCount directories and $fileCount files"}


      起始命令块创建两个变量,并将它们初始化为 0:


          {$fileCount = $directoryCount = 0}
 

      中间命令块计算由 Get-ChildItem 返回的每项是目录还是文件:


          {if ($_.PsIsContainer) {$directoryCount++} else {$fileCount++}}


      如果返回的项是目录,则 $directoryCount 变量递增 1。如果该项不是目录,则 $fileCount 
      变量递增 1。结尾命令块在中间命令块完成循环操作之后运行,返回计算结果:

       
          {"$directoryCount directories and $fileCount files"}


      通过使用起始、中间和结尾命令块结构及管道运算符,可以重新编写前面的示例,以查找大于 
      100 KB 的任何文件,如下所示:


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


另请参阅
    about_Automatic_Variables
    about_If
    Foreach-Object
    




目录