title: PowerShell: Is `$matches` guaranteed to carry down the pipeline in sync with the pipeline variable?
body: <p>First, make some example files:</p>
  
  <pre><code>2010..2015 | % { "" | Set-Content "example $_.txt" }
  
  #example 2010.txt                                                                          
  #example 2011.txt                                                                          
  #example 2012.txt                                                                          
  #example 2013.txt                                                                          
  #example 2014.txt                                                                          
  #example 2015.txt
  </code></pre>
  
  <p>What I want to do is match the year with a regex capture group, then reference the match with <code>$matches[1]</code> and use it. I can write this to do both in one scriptblock, in one cmdlet, and it works fine:</p>
  
  <pre><code>gci *.txt | foreach { 
  
      if ($_ -match '(\d+)')       # regex match the year
      {                            # on the current loop variable
          $matches[1]              # and use the capture group immediately
      } 
  
  }
  #2010
  #2011
  #.. etc
  </code></pre>
  
  <p>I can also write this to do the match in one scriptblock, and then reference <code>$matches</code> in another cmdlet's scriptblock later on:</p>
  
  <pre><code>gci *.txt | where { 
  
      $_ -match '(\d+)'     # regex match here, in the Where scriptblock
  
  } | foreach {             # pipeline!
  
      $matches[1]           # use $matches which was set in the previous 
                            # scriptblock, in a different cmdlet
  }
  </code></pre>
  
  <p>Which has the same output and it appears to work fine. But is it guaranteed to work, or is it undefined and a coincidence?</p>
  
  <p>Could <code>'example 2012.txt'</code> get matched, then buffered. <code>'example 2013.txt'</code> gets matched, then buffered. <code>| foreach</code> gets to work on <code>'example 2012.txt'</code> but <code>$matches</code> has already been updated with <code>2013</code> and they're out of sync?</p>
  
  <p>I can't make them fall out of sync - but I could still be relying on undefined behaviour.</p>
  
  <p>(FWIW, I prefer the first approach for clarity and readability as well).</p>