title: How to pipe directly to Copy-Item instead of within a ForEach-Object
body: <p>Because the -Exclude parameter of Get-ChildItem is not filtering on subfolders when using the -Recurse flag, see among other <a href="https://stackoverflow.com/questions/19842754">unable-to-exclude-directory-using-get-childitem-exclude-parameter-in-
  powershell</a></p>
  <p>But the -Exclude parameter can be used to filter out folders on the root level</p>
  <p>I wrote my own recursive function:</p>
  <pre><code>function Get-ChildItem-Recurse() {
      [cmdletbinding()]
      Param(
        [parameter(ValueFromPipelineByPropertyName = $true)]
        [alias('FullName')]
        [string[]] $Path,
        [string] $Filter,
        [string[]] $Exclude,
        [string[]] $Include,
        [switch] $Recurse = $true,
        [switch] $File = $false
      )
  
      Process {
        ForEach ( $P in $Path ) {
          Get-ChildItem -Path $P -Filter $Filter -Include $Include -Exclude $Exclude | ForEach-Object {
          if ( -not ( $File -and $_.PSIsContainer ) ) {
            $_
          }
          if ( $Recurse -and $_.PSIsContainer ) {
            $_ | Get-ChildItem-Recurse -Filter $Filter -Exclude $Exclude -Include $Include -Recurse:$Recurse
          }
        }
      }
    }
  }
  </code></pre>
  <p>When I pipe the result to a ForEach-Object to Copy the result to a different destination, all works fine, and the items except those that match the exclude parameter are copied</p>
  <pre><code>$source = 'D:\Temp\'
  $destination = 'D:\Temp_Copy\'
  
  Get-ChildItem-Recurse -Path $source -Exclude @( '*NotThis*', '*NotThat*' ) | ForEach-Object {
    $_ | Copy-Item -Destination ( &quot;$($destination)$($_.FullName.Substring($source.Length))&quot; ) -Force 
  }
  </code></pre>
  <p>When I pipe it directly to the Copy-Item commandlet, I get a null-valued error, because .Substring() is called on $_.FullName that is apparently null</p>
  <pre><code>Get-ChildItem-Recurse -Path $source -Exclude @( '*NotThis*', '*NotThat*' ) |
    Copy-Item -Destination ( &quot;$($destination)$($_.FullName.Substring($source.Length))&quot; ) -Force
  </code></pre>
  <p>Because the native commandlet Get-ChildItem does allow me to pipe its result to Copy-Item, I like my own custom function also to be able to do that. But I can't figure out why it's not working.</p>