Link to home
Start Free TrialLog in
Avatar of donpick
donpick

asked on

Copying files using Powershell > problems with destination directory

All computers are running Windows 7 Pro.
I am trying to copy a select number of directories from computer1 to computer100.  I am  a Powershell novice.

The Powershell script is very simple:

$sourcefolder = "g:\test"
$destinationfolder = "\\Computer100\MovieX"
$maxitems = 2
Get-Childitem -Path $sourcefolder | Select-Object -First $maxitems | Copy-Item -Destination $destinationFolder

The g drive is on computer1
Before executing the commands above I ran the following  command:

Set-Executionpolicy Unrestricted

The error produced when I run the script above is in the attached png file.


For the destination folder argument I created a mapped drive and still received the same error.
I know the destination path is accessible.  I can open the destination path from computer1 using Microsoft explorer.

What is wrong with my Powershell script?  What spelling error have I made?Powershell error.png
Avatar of donpick
donpick

ASKER

One thing I forgot to mention:  all the files in g:\test are directories  . What difference, if any , does this make?
Avatar of J0rtIT
It works the 1st time and then it's not allowing you to copy because the folders are already there.


$sourcefolder = "D:\test"
$destinationfolder = "\\CHIAPASV5\nf"
$maxitems = 2
Get-Childitem -Path $sourcefolder -Recurse | Select-Object -First $maxitems  | Copy-Item -Destination $destinationFolder
So what's the point to copy all from Source to Destination?

IF so I'd recommend you to use my robocopy like script
https://gallery.technet.microsoft.com/scriptcenter/Copy-Files-from-folderA-to-29710ef9

Copy-Item does only copy files, no folders. It expects the target folders to exist already.

Since it has been mentioned: why not use RoboCopy?
robocopy g:\test \\Computer100\MovieX /s /r:1 /w:1

Open in new window

which will copy only if changed or not yet copied over, and hence can be stopped and restarted at any time.
Avatar of donpick

ASKER

Hello Jose Gabriel Ortega Castro:  
So the script below will copy folders?
Get-Childitem -Path $sourcefolder -Recurse | Select-Object -First $maxitems  | Copy-Item -Destination $destinationFolder

I am a  novice at using Powershell.  The Powershell book I have says Copy-item will only copy the contents of one folder to another folder
So, to copy a folder from one drive to another I have to use Move-item?

Hello Qlemo:  I have many files to copy.  If I try to copy them all it would take many hours.  For various reasons I need to copy a limited number of directories and files copied at  any one time.  What argument can I use to tell Robocopy to copy X number of files and then stop?

Thank you for providing a robocopy script.  If robocopy is copying files and folders and I need to stop it, what is the best way to  stop it?  If I stop robocopy while it is copying a file, how to make sure robocopy does not leave a partially copied file at the destination folder?

Do I just  terminate the robocopy process or is there a better way to stop robocopy?





What is the target of copying only a few files selected arbitrarily? RoboCopy can'T do that.

You need to kill robocopy (e.g. with Ctrl-C) to stop it. It will not leave fragments of files, unless the connection to the destination is interrupted somehow.

In regard of Copy-Item versus Move-Item: They both act on files (as said), not folders. The difference is that Move-Item removes the source.
Avatar of donpick

ASKER

Hello Qlemo:  
Please tell me what Powershell command will copy folders.

If the C drive contains a folder called c:\stuff   and c:\stuff contains files and folders, what Powershell command will copy all the files and folders in c:\stuff to c:\newfilelocation?

Thank you.


There is no PS cmdlet copying folders. That is one reason why Jose created a robocopy-like script.
Sorry, but I have to intervene here:

PowerShell can of course copy directories, since at least version 2.0

See below for a sample run.

Anyway, I can reproduce that exact error when either the remote computer or the share does not exist. In other words: your destination is incorrect.
Check the target computer name and the share you want to use, and correct it.
This includes the necessary changes to copy directories including their contents:
$sourcefolder = "g:\test"
$destinationfolder = "\\Computer100\MovieX"
$maxitems = 2
Get-Childitem -Path $sourcefolder -Directory |
	Select-Object -First $maxitems |
	Copy-Item -Destination $destinationFolder -Recurse -Verbose

Open in new window




Now to PowerShell and its ability to copy directories: Yes, PowerShell can copy directories. Would be pretty embarrassing if it couldn't.
The -Recurse argument must be used, otherwise PS will do exactly what it's been told: copy the folder only, without content.
PS C:\> "$($PSVersionTable.PSVersion)"
2.0
PS C:\> gci C:\Temp\Source -Recurse | select -expa FullName
C:\Temp\Source\Sub
C:\Temp\Source\Sub\File.txt
PS C:\> gci C:\Temp\Target -Recurse | select -expa FullName
gci : Cannot find path 'C:\Temp\Target' because it does not exist.
At line:1 char:4
+ gci <<<<  C:\Temp\Target -Recurse | select -expa FullName
    + CategoryInfo          : ObjectNotFound: (C:\Temp\Target:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\> Copy-Item C:\Temp\Source -Destination C:\Temp\Target -Recurse -Verbose
VERBOSE: Performing operation "Copy Directory" on Target "Item: C:\Temp\Source Destination: C:\Temp\Target".
VERBOSE: Performing operation "Create Directory" on Target "Destination: C:\Temp\Target".
VERBOSE: Performing operation "Copy Directory" on Target "Item: C:\Temp\Source\Sub Destination: C:\Temp\Target\Sub".
VERBOSE: Performing operation "Create Directory" on Target "Destination: C:\Temp\Target\Sub".
VERBOSE: Performing operation "Copy File" on Target "Item: C:\Temp\Source\Sub\File.txt Destination: C:\Temp\Target\Sub\File.txt".
PS C:\> gci C:\Temp\Target -Recurse | select -expa FullName
C:\Temp\Target\Sub
C:\Temp\Target\Sub\File.txt
PS C:\>

Open in new window

I stand corrected. Sometimes you are convinced by "alternative facts", but should know better ... To patch things up:

So it is possible to copy folders and complete trees. Back to your request, we can trick PS to do what you want:
$sourcefolder = "g:\test"
$destinationfolder = "\\Computer100\MovieX"
$maxitems = 2
Copy-Item -Recurse -PassThru $sourcefolder -Destination $destinationfolder -Verbose | Select-Object -First $maxitems | Out-Null

Open in new window

That will create/copy folders/files until the given limit is reached. For folders that is it creates exactly two non-existent folders of the tree, if there are no files to copy up to then.

Assuming you are more after always copying two files, we need to be smarter:
$files = 0
Copy-Item -Recurse -PassThru $sourcefolder -Destination $destinationfolder -Verbose |
  ? { !$_.PsIsContainer } |
  % { if (++$files -ge $maxitems) { break } } |
  Out-Null

Open in new window

Both work because each object (file or folder) is passed thru the pipeline one by one, so a command stopping further processing of the pipeline stops the whole copy process. 
Avatar of donpick

ASKER

Hello OBda:  Thank you for the information.  I will work on this as soon as possible.
Avatar of donpick

ASKER

Thank you both oBdA and Qlemo for your help.  The script is working!!   More questions:
 I changed my script to the following:
$sourcefolder = "g:\test\*"
$destinationfolder = "\\Computer100\MovieX"
$maxitems = 2
Copy-Item -Recurse -PassThru $sourcefolder -Destination $destinationfolder -Verbose | Select-Object -First $maxitems | Out-Null

Using "g:\test\*"    prevents the g:\test folder from copying and only the contents of g:\test now get copied.
======================= Question 1 ===============
The code from oBda
Get-Childitem -Path $sourcefolder -Directory |
   Select-Object -First $maxitems |
   Copy-Item -Destination $destinationFolder -Recurse -Verbose

Open in new window

puts Get-Childitem at the front of the code above.  In the Copy-item the -Recurse is near the rear of the code.

The code from Qlemo :
Copy-Item -Recurse -PassThru $sourcefolder -Destination $destinationfolder -Verbose | Select-Object -First $maxitems | Out-Null

Open in new window

does not use Get-Childitem at all.  It puts -Recurse near the start of the code snippet.
What is the determining factor as to where to put the -Recurse parameter?
==================== Question 2 ====================
The code:
Select-Object -First $maxitems
is not working .  All the folders in g:\test are copied to the destination.  What code must I use to limit copying   $maxitems files / folders?



Avatar of donpick

ASKER

 ===================== Question 3 ======================
The following code displays a directory and the 2 subdirectories:
Get-Childitem -Recurse $sourcefolder | Select-Object -First $maxitems -Verbose

I erased the destination directory and tried this code:

Get-Childitem -Recurse $sourcefolder -Verbose | ForEach-Object {Select-Object -First $maxitems | Copy-Item $destinationfolder}

It does not copy anything.  What must be changed in the code above to copy $maxitems  ?
ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of donpick

ASKER

Thanks to you all for your help.
My Script works on Files and Folders, they create the structure and also preserve the files.

If you read the explanation in here:
https://gallery.technet.microsoft.com/scriptcenter/Copy-Files-from-folderA-to-29710ef9 
There are examples. so please let me know what else would you need to do so?
(late comment)