none
Robocopy help copying folders while preserving file structure RRS feed

  • Question

  • I want to search a folder and copy all instances of a couple folders.  In the destination directory, I want robocopy to recreate the folder structure of the source directory if it doesn't exist already.  The folders I need copied are not in the root of the source folder.  They are in subfolders.  Does anyone know how to accomplish this?
    Wednesday, April 17, 2019 12:19 PM

Answers

  • I don't see an /id switch (include directory) that mirrors the /xd switch (exclude directory). And I assume that you also want to copy the files in these directories to the target folder. Here's a Powershell wrapper. Test it out and remove the "/l" switch to actually copy files. Set -include to select the folder names that you want. 

    $src = 'c:\temp\copy test source'
    $dst = 'c:\temp\copy test dest'
    Get-ChildItem -Path $src -Directory -recurse -include 'me','logs' | foreach {
        $tgt = $dst + $_.fullname.Substring($src.length)
        robocopy.exe "$($_.fullname)" "$tgt" /l
    }

    • Marked as answer by MIS Admin Monday, April 29, 2019 3:49 PM
    Wednesday, April 17, 2019 2:14 PM
  • You took a PS script designed to copy folders and you used it to try to copy files without changing the robocopy parameters.

    -------------------------------------------------------------------------------
       ROBOCOPY     ::     Robust File Copy for Windows
    -------------------------------------------------------------------------------
    
      Started : Friday, April 19, 2019 5:23:36 PM
                  Usage :: ROBOCOPY source destination [file [file]...] [options]
    
                 source :: Source Directory (drive:\path or \\server\share\path).
            destination :: Destination Dir  (drive:\path or \\server\share\path).
                   file :: File(s) to copy  (names/wildcards: default is "*.*").

     This is where creating a .ps1 file and running through the ISE is better than trying to jam it all on to a single line and try to debug. 

    Note that files says *.*

    cls
    $env:src='C:\temp\Copy Test Source'
    $env:dst='C:\temp\copy test dest'
    Get-ChildItem -Path $Env:src -recurse -include '*.A', '*.B','*.C' | foreach {
      "File name is {0}" -f $_.Name
      "In directory  {0}" -f$_.DirectoryName
      $tgt = $Env:dst + $_.directoryname.Substring($Env:src.length)
      "Target folder is {0}" -f $tgt
      
      robocopy.exe "$($_.directoryname)" "$tgt" "$($_.Name)" /R:3 /W:3 /l
      }

    • Marked as answer by MIS Admin Monday, April 29, 2019 3:50 PM
    Friday, April 19, 2019 9:43 PM

All replies

  • Hi,

    If you only want to copy the folders and no files, you can use the following command:

    robocopy "Source" "Destination" /E /XF *

    This will only copy the whole folder hierarchy and it will not copy any files.


    Best regards,
    Leon


    Blog: https://thesystemcenterblog.com LinkedIn:

    Wednesday, April 17, 2019 12:49 PM
  • You should look at robocopy /?

    Here's what I can tell you:

    robocopy source destination /E /B /COPYALL /MIR /DCOPY:DA /R:1 /W:1

    Be careful not to mess up the source and the destination when using the MIR switch. You might end up erasing everything. If you're nervous, remove /MIR and when you confirm it's working as you expected it, add it back.

    Wednesday, April 17, 2019 12:52 PM
  • I don't see an /id switch (include directory) that mirrors the /xd switch (exclude directory). And I assume that you also want to copy the files in these directories to the target folder. Here's a Powershell wrapper. Test it out and remove the "/l" switch to actually copy files. Set -include to select the folder names that you want. 

    $src = 'c:\temp\copy test source'
    $dst = 'c:\temp\copy test dest'
    Get-ChildItem -Path $src -Directory -recurse -include 'me','logs' | foreach {
        $tgt = $dst + $_.fullname.Substring($src.length)
        robocopy.exe "$($_.fullname)" "$tgt" /l
    }

    • Marked as answer by MIS Admin Monday, April 29, 2019 3:49 PM
    Wednesday, April 17, 2019 2:14 PM
  • Thanks Leon and BLTechnical.  There are files in the root and in other folders that are in the root that I do not want copied.  Those methods will copy the files.

    Thanks MotoX80, your solution looks promising, I still need to test.  I will be running a second robocopy command to get other files so I want to use a .bat file.  Can we do something similar that you are doing in a .bat instead of powershell?

    Wednesday, April 17, 2019 2:41 PM
  • Excluding a folder with Robocopy

    ROBOCOPY "Source" "Destination" /XD "C:\Temp\ExcludedFolder"

    Excluding multiple folders with Robocopy

    ROBOCOPY "Source" "Destination" /XD "C:\Temp\ExcludedFolder" "C:\Temp\ExcludedFolder2"

    Excluding a file with Robocopy

    ROBOCOPY "Source" "Destination" /XF "filename.extension"

    Excluding multiple files with Robocopy

    ROBOCOPY "Source" "Destination" /XF "filename.extension" "filename2.extension"


    Blog: https://thesystemcenterblog.com LinkedIn:

    Wednesday, April 17, 2019 2:54 PM
  • Thanks Leon but the folder names that I do not want can change.  The folders are scattered many levels in many folders.  Also the files have many different extensions.  I don't know what they all are.

    Wednesday, April 17, 2019 3:38 PM
  • User get-childitem -recurse to find the names you want and pipe the results to robocopy in a foreach loop.
    Wednesday, April 17, 2019 3:40 PM
  • Can we do something similar that you are doing in a .bat instead of powershell?

    You could probably do it with a FOR command, but you have so much more flexibility with Powershell. I would suggest converting your bat file to a .ps1 file instead.  
    Wednesday, April 17, 2019 5:04 PM
  • I'm really bad with powershell scripts.  In my batch I have

    Set src="C:\Users\name\Desktop\TESTSOURCE"
    Set dst="C:\Users\name\Desktop\TESTDEST"

    Powershell -NoProfile -ExecutionPolicy Bypass -Command 'Get-ChildItem -Path $Env:src -Directory -recurse -include 'COPYME','COPYME2' | foreach {; $tgt = $Env:dst + $_.fullname.Substring($Env:src.length); robocopy.exe "$($_.fullname)" "$tgt" /l; }'

    but this doesn't display anything.  The windows closes immediately.

    Wednesday, April 17, 2019 5:34 PM
  • Stick a PAUSE command at the end of your bat file, or run the bat file from a command window.

    Note the quote changes. 

    Set src=c:\temp\copy test source
    Set dst=c:\temp\copy test dest
    Powershell -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem -Path $Env:src -Directory -recurse -include 'COPYME','COPYME2'  | foreach {; $tgt = $Env:dst + $_.fullname.Substring($Env:src.length); robocopy.exe """$($_.fullname)""" """$tgt""" /l; }"

    Wednesday, April 17, 2019 6:03 PM
  • Hi,

    Thank you for posting in Microsoft TechNet Forum.

    Have you tried the method mentioned by MotoX80 to work?

    I found a post which may help, please refer to the following link:

    https://superuser.com/questions/544182/how-to-use-robocopy-to-copy-a-folder-structure-into-all-subfolders-located-und

    Note: This is a third-party link and we do not have any guarantees on this website. This is just for your convenience. And Microsoft does not make any guarantees about the content.

    Best regards,

    Hurry


    Please remember to mark the reply as an answer if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com


    Thursday, April 18, 2019 8:13 AM
  • Very good, this version with the quote changes works.  I was planning to have two lines in the .bat file.  The first line would copy certain folders and their files.  MotoX80's line will work for this.  The second line would now copy all files matching certain wildcards...preserving the file structure.  I think I have this line working.  Then I would have this launched by a scheduled task once a week.

    Do you think it would be better to use a .ps1 file for the entire process?  Here's the scenerio.  I have one folder that contains many subfolders and files.  I need a script that will...

    1) Copy only subfolders in the source if their name is "A", "B" or "C" into my destination along with ALL the files in these folders.  The source folder structure needs to be preserved in the destination.

    2) Copy only files in the source if their name is *.A or *.B or *.C, etc.  into the destination.  The source folder structure needs to be preserved in the destination.

    What do you think?

    Hi Hurry.  I think the link you pointed to copies one folder to many.  The reverse of what I'm trying to do.  Thanks for finding it.


    • Edited by MIS Admin Thursday, April 18, 2019 12:12 PM
    Thursday, April 18, 2019 12:11 PM
  • Do you think it would be better to use a .ps1 file for the entire process? 


    Yes.
    Thursday, April 18, 2019 6:42 PM
  • Hi,

    Thank you for your feedback.

    Sincerely hope to succeed in helping you solve this problem.

    If you have any problems, please feel free to contact me.

    Best regards,

    Hurry


    Please remember to mark the reply as an answer if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com


    Friday, April 19, 2019 6:14 AM
  • I tried modifying the script to get the files as I mentioned in step 2 above.

    Powershell -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem -Path $Env:src -recurse -include '*.A', '*.B','*.C' | foreach {; $tgt = $Env:dst + $_.fullname.Substring($Env:src.length); robocopy.exe """$($_.fullname)""" """$tgt""" /R:3 /W:3 /l; }"

    It doesn't work.  I get...

    ERROR 123 (0x0000007B) Accessing Source Directory C:\Users\name\Desktop\TEST SOURCE\folder1\test.a\
    The filename, directory name, or volume label syntax is incorrect.

    Looks like it's finding a file but Robocopy is trying to read it as a folder.  What did I do wrong?

    Friday, April 19, 2019 12:23 PM
  • You took a PS script designed to copy folders and you used it to try to copy files without changing the robocopy parameters.

    -------------------------------------------------------------------------------
       ROBOCOPY     ::     Robust File Copy for Windows
    -------------------------------------------------------------------------------
    
      Started : Friday, April 19, 2019 5:23:36 PM
                  Usage :: ROBOCOPY source destination [file [file]...] [options]
    
                 source :: Source Directory (drive:\path or \\server\share\path).
            destination :: Destination Dir  (drive:\path or \\server\share\path).
                   file :: File(s) to copy  (names/wildcards: default is "*.*").

     This is where creating a .ps1 file and running through the ISE is better than trying to jam it all on to a single line and try to debug. 

    Note that files says *.*

    cls
    $env:src='C:\temp\Copy Test Source'
    $env:dst='C:\temp\copy test dest'
    Get-ChildItem -Path $Env:src -recurse -include '*.A', '*.B','*.C' | foreach {
      "File name is {0}" -f $_.Name
      "In directory  {0}" -f$_.DirectoryName
      $tgt = $Env:dst + $_.directoryname.Substring($Env:src.length)
      "Target folder is {0}" -f $tgt
      
      robocopy.exe "$($_.directoryname)" "$tgt" "$($_.Name)" /R:3 /W:3 /l
      }

    • Marked as answer by MIS Admin Monday, April 29, 2019 3:50 PM
    Friday, April 19, 2019 9:43 PM
  • Hi,

    How was going on this issue, please?

    Please mark the reply as an answer if their answer is helpful.

    Best regards,

    Hurry


    Please remember to mark the reply as an answer if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com


    Sunday, April 21, 2019 1:16 PM
  • Thanks MotoX80.  I would like to get this in one .ps1 file but I don't have the knowledge for it.  I'm trying it now but I can't even debug it in the ISE.  It doesn't run because scripts are disabled.  How do you tell the ISE to bypass the Execution Policy so you can test?
    Tuesday, April 23, 2019 12:17 PM
  • set-executionpolicy remotesigned

    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6

    Tuesday, April 23, 2019 1:33 PM
  • Hi,

    Thank you for your feedback.

    Please refer to the following link to bypass the Execution Policy:

    https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/

    Note: This is a third-party link and we do not have any guarantees on this website. This is just for your convenience. And Microsoft does not make any guarantees about the content.

    Best regards,

    Hurry


    Please remember to mark the reply as an answer if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Wednesday, April 24, 2019 7:51 AM
  • Thanks.  Now that I am trying to work with a .ps1 file, the folder copy doesn't work completely.  Here's what I have...

    $src = 'c:\temp\copy source'
    $dst = 'c:\temp\copy dest'

    Get-ChildItem -Path $src -Directory -recurse -include 'Folder1','Folder2','Folder3' | foreach {
        $tgt = $dst + $_.fullname.Substring($src.length)
        robocopy.exe "$($_.fullname)" "$tgt" /R:3 /W:3 /l /LOG+:"E:\Backups\lastbackup.log" /TEE
        }

    Folder1 is being copied correctly.  It only has files in it.  Folder2 has multiple subfolders and subfolders within them.  It's just copying the files that are in the root of Folder2.  It's not copying all the other subfolders and files, which I also need.  How can I correct this?

    Wednesday, April 24, 2019 4:35 PM
  • robocopy /?

    ::
    :: Copy options :
    ::
                     /S :: copy Subdirectories, but not empty ones.
                     /E :: copy subdirectories, including Empty ones.
                 /LEV:n :: only copy the top n LEVels of the source directory tree.

    Wednesday, April 24, 2019 7:18 PM
  • Thank you.  I was not thinking the issue was with the RoboCopy arguments.  I was thinking the Powershell loop was not finding them.

    The script seems to work now.  I only see one issue now.  I am starting this script from Task Scheduler.  When the script is finished and the Powershell window disappears, the Task doesn't end.  Task Scheduler still reports the task as running.  The task is set to start an external program.  I just have Powershell.exe there and for arguments I have -NoProfile "PathToPS1File".  

    Is there something I need to add in the powershell script to signal the task has ended?

    Thursday, April 25, 2019 7:44 PM
  • Hi,

    Thank you for your feedback.

    If you think the PowerShell loop wasn't finding them, please try to re-create a post about PowerShell. There will have more Professional people to help you.

    If you want Remote Technical Support, please try to Global Customer Service for the further analysis.

    Best regards,

    Hurry


    Please remember to mark the reply as an answer if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Friday, April 26, 2019 9:29 AM
  • Thanks everyone for the help.  It's working now.
    Monday, April 29, 2019 3:49 PM