copy "this folder" to network drive (Robocopy or PowerShell) - powershell

Have a folder structure on local drive like this
and a similar structure on network drive like
C:\Documents\Projects\
\\myServer\Storage\Projects\
For each new project I create locally folders like
\Projects\abc\Subfolder1
\Projects\abc\Subfolder2
I need PowerShell or Batch file. The batch is stored in folder abc and it shall perform
Robocopy C:\Documents\Projects\abc \\myServer\Storage\Projects\abc
(of course some switches are reasonable)
Next project, for example xyz
\Projects\abc\Subfolder1
\Projects\abc\Subfolder2
I expect
Robocopy C:\Documents\Projects\xyz \\myServer\Storage\Projects\xyz
Each time I create new project I copy my sample folder structure that is supposed to contain the batch so I can quickly do copy for the project to network,
I think this can be solved by using variables for local and server base path or by doing som

I don't know which Robocopy parameters you need, but this could be a start. This assumes that you place this script in each \Projects\abc directory and run it from there.
$DestinationShare = '\\myServer\Storage'
$SourcePath = $PSScriptRoot
$DestinationPath = $PSScriptRoot -replace ".*?(?<path>\\Projects\\.*)","$DestinationShare`${path}"
robocopy $SourcePath $DestinationPath
This could be turned into a function that would have less static coding.
It is going to be simpler to just robocopy the entire Projects directory whenever it is required.

In batch you could do something like this:
#echo off
set "src=%~dp0"
set "dst=\\myServer\Storage"
for /d %%d in (%src%.) do set "name=%%~nd"
robocopy %src% %dst%\%name%\ /mir
%~dp0 is the directory in which the script resides. The for loop then extracts the name of that directory from the full path.

Related

Robocopy deletes existing files in destination folder

I am new to Powershell and Robocopy usage.
I am trying to send some files to destination path. But destination path contains some files that is not contained in source. I want that files remain intact after copy operation.
When i try to run Robocopy from a powershell script like this:
Robocopy sourcePath destinationPath /MIR
it syncs two paths. So that destinationPath lonely files are deleted.
Is there any way to prevent this behavior?
Don't use the /MIR flag. That is exactly to keep the source and destination in sync, including deletion of files missing in source.
Use robocopy /E to copy a folder structure including empty subfolders. By default it only copies new and newer files.

Copying folder structure to location that doesn't exist

I want to copy a folder, complete with subdirectories, files and files within subdirectories, preserving the structure and create them in a new location that did not previously exist. This is my PowerShell code
Copy-Item c:\development\powershell\folderone\* c:\development\powershell\foldertwo -recurse -Container
Copy-Item c:\development\powershell\folderone\* c:\development\powershell\folderthree -recurse -Container
foldertwo exists and is empty, folderthree does not exist.
If I run the script, the structure is created correctly in foldertwo, however folderthree gets created, but contains only all the files from the entire substructure, all at the root folderthree level. It has not recreated the subfolders within folderone, just put all the files at the root level of folderthree.
What have I done wrong?
Here's a very basic, but fully working and tested example, building on your confirmation above that I understood the issue at-hand:
$folderlist = ("foldertwo", "folderthree")
foreach ($folder in $folderlist)
{
if (!(Test-Path "C:\Development\PowerShell\$folder"))
{
mkdir ("C:\Development\PowerShell\$folder") | Out-Null
}
Copy-Item c:\development\powershell\folderone\* c:\development\powershell\$folder -recurse -Container
}
From what I understand, the question is about recreating the folder structure from [source] to [destination]. As using CmdLets is kind of overkill (and performance loss), I suggest simple batch command that may also be ran in powershell.
xcopy [source] [destination] /T /E
xcopy is a function to copy file and directory trees.
Help provides us info on usefult parameters on the case:
/T Creates directory structure, but does not copy files. Does not
include empty directories or subdirectories. /T /E includes
/E Copies directories and subdirectories, including empty ones.
Same as /S /E. May be used to modify /T.

Robocopy - make a copy of single file in same directory

Using robocopy is it possible to make a copy of a file in same directory?
Something like this...
robocopy c:\temp\file.txt c:\temp\file_copy.txt
COPY could be used. Use /Y to confirm an overwrite.
COPY /Y "C:\temp\file.txt" "C:\temp\file_copy.txt"
I was pulling my hair out to try and figure this problem out. I finally found my own solution and maybe it will help you too.
I noticed that the syntax used to select the entire directory could be used to select a single file.
ROBOCOPY "*" "Directory source" "Directory Output unc path or non"
The above code will copy everything from the directory source folder to the directory output path.
Let's say you only wanted to copy 1 file from the directory source named "test.txt"
In order to do that use the following code:
ROBOCOPY "*test.txt" "Directory source" "Directory Output unc path or non"
Thats about it. It works really well and will only copy the file name you want.
Alternatively you can use
ROBOCOPY "*.txt" "Directory source" "Directory Output unc path or non"
to copy out all text documents from the directory source.
Similarly this will also work with any .ext
.zip .exe .txt .pdf etc..
I signed up to answer this question with a better method. Let me know if I succeeded.

Copy-Item vs XCopy

I was asked to benchmark using a powershell script to do some basic file copying as opposed to using XCopy in a batch file. It seems to run in roughly about the same amount of time, but with Powershell the parent folder of the tree structure is not being created in the destination, whereas with XCopy the parent folder does get created. For example, with
xcopy D:\Webs\First\*.* D:\Test\Sandbox\ /E
The "First" folder does get created with all its contents. Whereas with
$SourceFolder = "D:\\Webs\\First\\"
$TargetFolder = "D:\\Test\\Sandbox\\"
Copy-Item $SourceFolder $TargetFolder -recurse
The folder named "First" does not get created and rather the contents are copied to the destination. If I use "Webs" as the source folder, there are other folders at the same level as "First" that get copied as well and that is not desirable.
How do I get the Parent folder "First" to copy to the destination using the Copy-Item or some other powershell command without manually creating this folder within the script so I get the exact same results?
Thanks...
for a quick way you can append the source parent folder before copy, e.g.
$TargetFolder = "D:\\Test\\Sandbox\\"+($SourceFolder | Split-Path -leaf)
you can also use the Measure-Command Cmdlet for timings

What's the proper way to copy files while preserving folder structure in powershell?

I can never seem to get this right.
I have an existing folder c:\MyApps\Websites\MySite that already has an existing website running in it. I've downloaded the latest bits which are located under c:\temp\MySite\artifacts.
when I try to run this
$source "c:\temp\MySite"
$destination "c:\MyApps\Websites\MySite"
copy-item $source $destination -recurse -force
if c:\MyApps\Websites\MySite already exists then it tries to put it in c:\MyApps\Websites\MySite\artifacts, but if it doesn't already exist it copies it properly. Not sure what's going on here. Any suggestions?
Just use the robocopy command. It's designed for this kind of thing.
robocopy $source $destination /E
It's shipped with Windows 7, so it's an internal command, so it's still a 'Powershell' way, imho, but if you're wanting to use the copy command, then you are very close, but your current implementation grabs the source folder and puts it inside target (ie the result would be C:\target\source\files, not C:\target\files). When you want to make the inside of target look like the inside of source, you need to do:
cp C:\source\* C:\target -r -fo
Notice the *, this grabs the contents of the source folder. If you want target to be cleared first, just do rm -r -fo C:\target\* before the copy.
Powershell doesn't handle long paths, so you will need to use robocopy anyway if you have a long filename or deep folders.