PowerShell: Copy-Item -recurse -force Does Not Create Directories when Using Get-ChildItem -include

I recently wrote a PowerShell script which copied documents from a filter to my local hard drive. I chose PowerShell for this task because it was one of the few programs actually allowed on my ultra locked-down workstation (and ‘cuz I love it.)

Because I only wanted specific types of files, I gathered the list of documents using get-childitem -recurse -include and then copied the files using copy-item. What I didn’t initially realize was that copy-item’s -recurse and -force switches are ineffective in my script because 1.) I’m passing the copy-item command one item at a time and 2.) the get-childitem include switch is “best considered a file filter,” according to Lee Holmes of Microsoft’s PowerShell team..

I got around this by manually creating the directory structure as needed using if (!(test-path($dir))) { mkdir $dir }. The entire script can be found below:

Chrissy is a PowerShell MVP who has worked in IT for nearly 20 years, and currently serves as a Sr. Database Engineer in Belgium. Always an avid scripter, she attended the Monad session at Microsoft’s Professional Developers Conference in Los Angeles back in 2005 and has worked and played with PowerShell ever since. Chrissy is currently pursuing an MS in Systems Engineering at Regis University and helps maintain RealCajunRecipes.com in her spare time. She holds a number of certifications, including those relating to SQL Server, SuSE Linux, SharePoint and network security. She recently became co-lead of the SQL PASS PowerShell Virtual Chapter. You can follow her on Twitter at @cl.

Posted in PowerShell
4 comments on “PowerShell: Copy-Item -recurse -force Does Not Create Directories when Using Get-ChildItem -include
  1. Frank says:

    I spent too much time trying to figure out how to do this, then spent too much time trying to find how to do this on the web. I'm thankful I found your script. It's much appreciated.

  2. jgraglia says:

    Thank you so much!!!! This save my day!

  3. Perry says:

    Thank you Chrissy.
    I wanted to move the files and keep a reference of the folder they were moved from but leaving the original folder if there were other files. Your script was instrumental and I’ve included my modification so others could use if they have the smae situation.

    $source = “L:\”
    $destination = “C:\docs\”
    $since = (Get-date).AddDays(-365)
    $includes =”*.doc*”,”*.pdf”,”*.xls*”,”*.ppt*”

    $items = get-childitem $source -recurse -include $includes | where-object {$_.LastAccessTime –gt $since}

    foreach ($item in $items)
    $dir = $item.DirectoryName.Replace($source,$destination)
    $target = $item.FullName.Replace($source,$destination)

    if (!(test-path($dir))) { mkdir $dir }

    Move-Item -Force -path $item.FullName -destination $target

  4. Andrew L says:

    Thanks a lot! Saved a production script issue a week before go-live. Many thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *