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.
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.
$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
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...
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.
$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
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.
I also opened a suggestion : Copy-VMGuestFile does not copy all files | VMware PowerCLI
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
Yes I can see the whole list in the source folder and only a part of it in the destination folder.
Everything with PowerShell 🙂
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
Yes this works fine.
All files are present.
Thanks for sharing your code!
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.
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
Excellent!
This solve the timeout issue 🙂
Thanks!