Highlighted
Enthusiast
Enthusiast

copy-vmguestfile does not copy all files

Jump to solution

I have downloaded the ADK localy on a file server and I want to copy this folder, including subfolders and files to a VM.

Here is my command-line

Get-VM -Name 'MyVM' | Copy-VMGuestFile -Source \\fileserver\sharename\ADK -Destination 'C:\temp' -LocalToGuest -GuestCredential (Get-Credential -Credential 'Administrator') -Force

However, there is a subfolder named Installers with 221 files and the Copy-VMGuestFile cmdlet only copies half of them without any seeable logic behind...

Did I miss something or is this a bug?

I use PowerCli v11.3.0.

1 Solution

Accepted Solutions
Highlighted
User Moderator
User Moderator

There is nothing wrong with your bypass, which is in fact the (nearly) correct method to use Copy-VMGuestFile.
Copy-VMGuestFile is made to copy only 1 file, no recursion for subfolders.

See also this older thread where Vitali, from the PowerCLI Dev Team, confirmed that this is the intended working for the cmdlet.

Note1: since this script uses the -replace operator, the 1st value on the right side (the $src in this case) is interpreted as a RegEx. Hence we have to escape all RegEx special characters (like a \)

Note2: if you want the folder Source created as well, you will have to include it yourself in the Destination

Note3: the Force switch is required, otherwise (sub)folders will not be created

Note4: to handle al files recursively, you need to add the Recurse switch on the Get-ChildItem cmdlet

Note5: since the Force parameter will create folders, we only need to list files in the Source, hence the File switch on the Get-ChildItem cmdlet

I normally use it like this.

$vmName = 'VM'

$src = 'C:\Source'

$dst = 'C:\Destination\Source'


$vm = Get-VM -Name $vmName


Get-ChildItem -Path D:\Demos -Recurse -File |

ForEach-Object -Process {

   $sCopy = @{

   VM = $vm

   Source = $_.FullName

   Destination = $_.FullName -replace ([RegEx]::Escape($src)), $dst

   LocalToGuest = $true

   Force = $true

   GuestUser = 'MyAccount'

   GuestPassword = 'MyPassword'

   Verbose = $true

   }

   Copy-VMGuestFile @SCopy

}

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
11 Replies
Highlighted
Enthusiast
Enthusiast

After relaunching the cmdlet several times, I ended up with a workaround.

$Credential = Get-Credential -Credential 'Administrator'

$VM = Get-VM -Name 'MyVM'

Get-ChildItem -Path \\FileServer\ShareName\ADK\Installers |

    ForEach-Object -Process {Copy-VMGuestFile -VM $VM -Source $PSItem.FullName -Destination 'C:\temp\ADK\Installers' -LocalToGuest -GuestCredential $Credential -Force -Verbose}

But this is only a workaround...

I am still trying to understand what's wrong...

0 Kudos
Highlighted
User Moderator
User Moderator

There is nothing wrong with your bypass, which is in fact the (nearly) correct method to use Copy-VMGuestFile.
Copy-VMGuestFile is made to copy only 1 file, no recursion for subfolders.

See also this older thread where Vitali, from the PowerCLI Dev Team, confirmed that this is the intended working for the cmdlet.

Note1: since this script uses the -replace operator, the 1st value on the right side (the $src in this case) is interpreted as a RegEx. Hence we have to escape all RegEx special characters (like a \)

Note2: if you want the folder Source created as well, you will have to include it yourself in the Destination

Note3: the Force switch is required, otherwise (sub)folders will not be created

Note4: to handle al files recursively, you need to add the Recurse switch on the Get-ChildItem cmdlet

Note5: since the Force parameter will create folders, we only need to list files in the Source, hence the File switch on the Get-ChildItem cmdlet

I normally use it like this.

$vmName = 'VM'

$src = 'C:\Source'

$dst = 'C:\Destination\Source'


$vm = Get-VM -Name $vmName


Get-ChildItem -Path D:\Demos -Recurse -File |

ForEach-Object -Process {

   $sCopy = @{

   VM = $vm

   Source = $_.FullName

   Destination = $_.FullName -replace ([RegEx]::Escape($src)), $dst

   LocalToGuest = $true

   Force = $true

   GuestUser = 'MyAccount'

   GuestPassword = 'MyPassword'

   Verbose = $true

   }

   Copy-VMGuestFile @SCopy

}

---------------------------------------------------------------------------------------------------------

Was it helpful? Let us know by completing this short survey here.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
Highlighted
Enthusiast
Enthusiast

Ok than I understand that it has always been like this.

But this doesn't it make normal...

What is weird, is that it copies only a part of the files belonging to the same folder.

A logical behavior would be to copy either one or all of them and not just what appears to be a random number...

Thanks Luc for your explanation and your code.

0 Kudos
Highlighted
Enthusiast
Enthusiast
0 Kudos
Highlighted
User Moderator
User Moderator

When it copies only part of the files in a folder, do you see all file when doing a Get-ChildItem?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Highlighted
Enthusiast
Enthusiast

Yes I can see the whole list in the source folder and only a part of it in the destination folder.

Everything with PowerShell 🙂

0 Kudos
Highlighted
User Moderator
User Moderator

Strange, can't replicate that.

Just to make sure, the script I provided does copy all files?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Highlighted
Enthusiast
Enthusiast

Yes this works fine.

All files are present.

Thanks for sharing your code!

0 Kudos
Highlighted
Enthusiast
Enthusiast

I have to copy the whole folder again on another computer.

This time I am using the script directly.

It fails only on one file with the following message:

Copy-VMGuestFile : 08/08/2019 12:16:24 Copy-VMGuestFile A task was canceled.

It's a 532 Mb file.

Unfortunately it fails constantly before 400 Mb.

This is a task timeout issue because the transfer stops exacty after 5 minutes.

0 Kudos
Highlighted
User Moderator
User Moderator

You could try to change the WebOperationTimeoutSeconds value with Set-PowerCLIConfiguration.

But I'm not 100% sure this has any impact the copying of a file this way.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Highlighted
Enthusiast
Enthusiast

Excellent!

This solve the timeout issue 🙂

Thanks!

0 Kudos