title: Redirection to $null strange behavior in Powershell
body: <p>There are four ways to suppress an output:</p>
  
  <ol>
  <li>Redirection to <code>$null</code> variable
  
  <pre class="lang-bsh prettyprint-override"><code>PS C:\&gt; 1; $(2; return) &gt; $null; 3
  1
  3
  </code></pre></li>
  <li>Piping to <code>Out-Null</code> cmdlet
  
  <pre class="lang-bsh prettyprint-override"><code>PS C:\&gt; 1; $(2; return) | Out-Null; 3
  1
  2
  </code></pre></li>
  <li>Casting to <code>[void]</code> type
  
  <pre class="lang-bsh prettyprint-override"><code>PS C:\&gt; 1; [void]$(2; return); 3
  1
  2
  </code></pre></li>
  <li>Assignment to <code>$null</code> variable
  
  <pre class="lang-bsh prettyprint-override"><code>PS C:\&gt; 1; $null = $(2; return); 3
  1
  2
  </code></pre></li>
  </ol>
  
  <p>All four cases are expected to be equivalent.</p>
  
  <p>Why redirection to <code>$null</code> behaves different? Have I faced a bug?</p>
  
  <h3>An additional example</h3>
  
  <p>This example shows unexpected behavior of <code>&gt; $null</code> command in PS 2.0:</p>
  
  <pre class="lang-bsh prettyprint-override"><code>PS C:\&gt; 1; $(Write-Output 2; Write-Host 3; return; Write-Host 4) &gt; $null; 5
  1
  3
  5
  </code></pre>
  
  <p><code>return</code> command acts as if it exits from some nested context (though there is no command which creates it), stops <code>$()</code> expression execution and then continues the execution (when it shouldn't) in the current context to the <code>Write-Output 5</code> command.</p>
  
  <h2>BEHAVIOR EXPLANATIONS</h2>
  
  <p>(from <a href="https://stackoverflow.com/a/42407253/7204581"><em>wOxxOm</em>'s</a> answer)</p>
  
  <ul>
  <li>in PS 1.0 and 2.0 <code>&gt; $null</code> operation is executed <em>before</em> <code>$()</code> expression and suppresses its output; <code>return</code> command does not exit from the current context (considered a <strong>BUG</strong>), but stops <code>$()</code> expression execution</li>
  <li>in PS 3.0 and newer <code>&gt; $null</code> operation is executed <em>before</em> <code>$()</code> expression and suppresses its output in all cases; <code>return</code> command exits from the current context completely</li>
  <li><code>| Out-Null</code>, <code>[void]</code>, <code>$null =</code> operations are executed <em>after</em> <code>$()</code> expression and suppress its output if there is no <code>return</code> command in it; <code>return</code> command exits from the current context completely</li>
  </ul>
  
  <h2>SUMMARY</h2>
  
  <p>Different methods for suppressing command output:</p>
  
  <ol>
  <li><code>... &gt; $null</code> redirection to <code>$null</code> variable<br>
  <em>Bug in PS 1.0 and 2.0. In PS 3.0+ output may differ from other methods</em></li>
  <li><code>... | Out-Null</code> piping to <code>Out-Null</code> cmdlet<br>
  <em>Performance issues <sup><a href="https://stackoverflow.com/a/5263780/3959875">*</a></sup></em></li>
  <li><code>[void]...</code> casting to <code>[void]</code> type<br>
  <em>Advisable</em></li>
  <li><code>$null = ...</code> assignment to <code>$null</code> variable<br>
  <em>Advisable</em></li>
  </ol>