主題
    about_Foreach

簡短描述
    描述可用來周遊於項目集合中所有項目的語言命令。


完整描述
    Foreach 陳述式 (也稱為 Foreach 迴圈) 是一種語言建構,用以逐項 (反覆) 處理項目集合中
    的一連串數值。


    最簡單且最常周遊的集合類型是陣列。
    Foreach 迴圈內部常會對陣列中的每個項目執行一或多個命令。


  語法        
      Foreach 的語法如下:

        
          foreach ($<項目> in $<集合>){<陳述式清單>}


  命令管線外的 Foreach 陳述式 Foreach 陳述式置於括號中的部分代表變數以及所要反覆處理
  的集合。Windows PowerShell 會在 Foreach 迴圈執行時自動建立變數 ($<項目>)。每次反覆
  處理迴圈之前,會先將此變數設定為集合中的某個值。Foreach 陳述式後面的區塊 {<陳述式
  清單>} 包含了要對集合中的每個項目執行的一組命令。
 

  範例
      例如,下列 Foreach 迴圈範例將顯示 $letterArray 陣列中的值。

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

      
      此範例使用字串值 "a"、"b"、"c" 和 "d" 建立並初始化 $letterArray 陣列。
      Foreach 陳述式第一次執行時,會將 $letter 變數設定為等於 $letterArray ("a") 
      中的第一個項目, 然後再使用 Write-Host Cmdlet 來顯示字母 a。下一次通過迴圈
      時,$letter 會設定為 "b",以此類推。直到 Foreach 迴圈顯示字母 d 之後,Windows 
      PowerShell 隨即結束迴圈。


      在 Windows PowerShell 命令提示字元輸入時,整個 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.length / 
                  1024).ToString("F0") KB
                  $i = $i + 1
              }
          }

          if ($i -ne 0)
          {
              Write-Host
              Write-Host $i " 個檔案在目前目錄中超過 100 KB。"}
          else 
          {
              Write-Host "目前目錄中沒有大於 100 KB 的檔案。"
          }


      在前述範例中,在迴圈外將 $i 變數設為 0,且迴圈內每找到一個大於 100 KB 的檔案時
      便遞增變數值。結束迴圈後,If 陳述式會評估 $i 的值以顯示所有超過 100 KB 的檔案
      數目, 或顯示訊息表示找不到大於 100 KB 的檔案。


      上述範例也示範如何將檔案長度結果格式化:


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


      值先除以 1,024 而從位元組改為顯示以 KB 為單位的結果,然後使用固定小數點格式指
      定元移除結果中的小數點。當中的 0 係指示格式指定元不應顯示任何小數位數。


  命令管線內的 Foreach 陳述式 每當 Foreach 出現在命令管線內,Windows PowerShell 便會
  使用 foreach 別名藉以呼叫 ForEach-Object 命令。若在命令管線內使用 foreach 別名,
  就不必加上 Foreach 陳述式應有的 ($<項目> in $<集合>) 語法。這是因為管線內的上一個命
  令會提供此資訊。用於命令管線內的 foreach 別名使用下列語法:
        

          <命令> | foreach {<命令區塊>}
     

      例如,下列命令管線內的 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 變數) 
      以及工作組的大小 (以 MB 為單位)。
      若所有的處理序工作組都不超過 20 MB,就不會顯示任何資訊。


          Write-Host "工作組大於 20 MB 的處理序" Get-Process | foreach { 
              if ($_.WS -gt 20m)
              {
                  Write-Host $_.name ": " 
          ($_.WS/1m).ToString("F0") MB -Separator ""
              }
          }

      foreach 別名也支援起始命令區塊、中間命令區塊以及結尾命令區塊。起始與結尾命令區
      塊僅執行一次,中間命令區塊則是在 Foreach 迴圈每次逐項處理集合或陣列時都會執行。
        

      在命令管線內使用,且包含起始、中間與結尾命令區塊之 foreach 別名的語法如下:
        

          <命令> | foreach {<起始命令區塊>}{<中間命令區塊>}{<結尾命令區塊>}

 
      下列範例示範起始、中間與結尾命令區塊的用法。


          Get-ChildItem | foreach {
          $fileCount = $directoryCount = 0}{
          if ($_.PsIsContainer) {$directoryCount++} else 
          {$fileCount++}}{ "$directoryCount 個目錄和 $fileCount 個檔案"}


      起始區塊會建立兩個變數並將其初始化為 0:


          {$fileCount = $directoryCount = 0}
 

      中間區塊會評估 Get-ChildItem 所傳回的每個項目是目錄或檔案:


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


      如果傳回的項目是目錄,$directoryCount 變數會以 1 遞增。如果該項目不是目錄,
      $fileCount 變數會以 1 遞增。結束區塊會在中間區塊完成其迴圈作業之後執行,然
      後再傳回作業的結果。

       
          {"$directoryCount 個目錄和 $fileCount 個檔案"}


      您可以使用起始、中間與結尾命令區塊結構以及管線運算子來改寫稍早的範例,找出大小
      超過 100 KB 的檔案,如下所示:


          Get-ChildItem | foreach{
              $i = 0}{
              if ($_.length -gt 100k)
              {
                  Write-Host $_.name "檔案大小:" ($_.length / 
                  1024).ToString("F0") KB
                  $i++
              }
              }{
              if ($i -ne 0)
              {
                  Write-Host
                  Write-Host "$i 個檔案在目前目錄中超過 100 KB。"
              }
              else 
              {
              Write-Host "目前目錄中沒有大於 100 KB 的檔案。"}
              }


請參閱
    about_Automatic_Variables
    about_If
    Foreach-Object
    




目錄