Search code examples
powershellcopy-item

How to copy local files AND PATHS to network share using PowerShell?


Using PowerShell, I'm trying to pipe a file list from my local drive so Copy-Items can copy them to a network folder. The following statement does find the files I need, and copies them. However, all path information is lost and they all end up in the same folder. I want each file to be saved in relative path fashion at the destination with its file path from the local disk.

So for example "c:\users\user_name\Documents\file_1.txt" should be copied to "\\server\share\my_folder\users\user_name\Documents\file_1.txt"

My searches have proved fruitless. Can this statement be modified to achieve that?

Get-ChildItem -Path c:\users\user_name -r | ? {!($_.psiscontainer) -AND $_.lastwritetime -gt (get-date).date} | %{Copy-Item -Path $_.fullname -destination "\\server\share\my_folder" -Recurse -Force -Container}

EDIT:

It seems like Copy-Item should be able to do this. The following command works:

Copy-Item -Path c:\users\user_name\Documents -Destination "\\server\share\my_folder" -recurse -Force

This command copies all files, sub-folders and files in the sub-folders found in and under c:\users\user_name\Documents. It then recreates the relative directory structure on the network share. It seems like the $_.fullname parameter from the first command is not being treated in a similar fashion. I'm most certainly not piping file list in the expected manner to Copy-Item. Any other advice?


Solution

  • Okay, this was quite the challenge, but I finally found a mechanism. Thanks to @iRob for pointing me to a potential solution. I could not get his code to create the relative paths at the destination, but was able to extend his concept. I ended up adding in a New-Item command (found via Powershell 2 copy-item which creates a folder if doesn't exist) and a Split-Path (found here Copy a list of files to a directory). The Split-Path sliced off the file name from the joined path, then that path was created via the New-Item command. Finally the Copy-Item had a place to copy the file. So in that sense @Doug Maurer was also right that Copy-Item would not do this itself. Some extra preparation was need before the Copy-Item command could successfully run.

    Set-Location c:\users\user_name; Get-ChildItem -Recurse | ? { !($_.psiscontainer) -AND $_.lastwritetime -gt (get-date).date } | % {Copy-Item $_.fullname -destination (New-Item -type directory -force ((Join-Path '\\server\share\my_folder' ($_ | Resolve-Path -Relative)) | Split-Path -Parent)) -Force}
    

    IMHO something that was trivial in MS-DOS 6.0 (xcopy /D:08-20-2020 /S c:\users\user_name*.* \server\share\my_folder) should not be so difficult in PowerShell. Seems like there should be an easier way. Now that I think of it, probably should have stuck to xcopy instead of diving down this rabbit hole. PowerShell just seems so shiny.