How to Copy Files between Hyper-V Host and Guests with PowerShell

Copying files to Hyper-V virtual machines wouldn’t seem like a big deal. In most situations, the virtual machine is no different than a physical machine on your network. You could copy files to a virtual machine using traditional methods like you would any other machine, but sometimes that isn’t possible. Fortunately, there is an alternative. If you are running the latest version of Hyper-V on either Windows Server 2012 R2 or Windows 8.1, which implies that you’re running PowerShell 4.0, then you have access to a new cmdlet in the Hyper-V module called Copy-VMFile.

I’m going to demonstrate how to use this cmdlet, but be sure to take time to read the help.

help Copy-VMFile -ShowWindow
Copy-VMFile help in Windows PowerShell. (Image Credit: Jeff Hicks)
Copy-VMFile help in Windows PowerShell. (Image Credit: Jeff Hicks)


 
I’m first going to demonstrate from my Windows 8.1 client that’s running Hyper-V. The Guest Services feature of VM Integration Services must be enabled on any guest virtual machines in order to use this cmdlet. Here’s how you can verify if that feature is enabled:

Get-VMIntegrationService -name Guest* -VMName chi-dc01,chi-dc02,win10preview
Verifying that the Guest Services feature is enabled in Windows PowerShell. (Image Credit: Jeff Hicks)
Verifying that the Guest Services feature is enabled in Windows PowerShell. (Image Credit: Jeff Hicks)


 
The service on CHI-DC01 is all set. It is enabled on CHI-DC02, but notice that the status indicates no contact. That particular virtual machine needs to be updated so that I can install the latest VM Integration Services. Until I get a connection for Guest Services, I won’t be able to use Copy-VMFile. The last virtual machine is running a Windows 10 preview, and as you can see, Guest Services are not enabled. Let’s fix that.

Enable-VMIntegrationService -name Guest* -VMName win10preview -Passthru
Enabling Guest Services in Windows PowerShell. (Image Credit: Jeff Hicks)
Enabling Guest Services in Windows PowerShell. (Image Credit: Jeff Hicks)


 
That looks pretty good. Time to use Copy-VMFile to copy a file.

Copying a File Using Copy-VMFile

When you copy a file using Copy-VMFile, you must specify the source and destination. The source location is relative to the Hyper-V host, which in my situation is my local host running Windows 8.1. The destination is the path on the virtual machine. I especially like that the cmdlet has a parameter, CreateFullPath, that will create all folders that are part of the destination path if they don’t already exist. If you think the file might already exist be sure to use –Force, otherwise you will get an error. Naturally, you must specify the virtual machine names.

A bit later I’ll show you how to pipe a virtual machine object to this cmdlet. Finally, you have to include the –FileSource parameter. Right now this can only take a value of Host. I’m assuming at some point in the future we might be able to copy files from a UNC or the local host. But for now, use Host. Here’s a hashtable of Copy-VMFile parameters:

$paramHash = @{
 Name = 'chi-dc01','win10preview'
 SourcePath = 'C:workfile.txt'
 DestinationPath = 'C:workfile.txt'
 CreateFullPath = $True
 FileSource = 'Host'
 Force = $True
 Verbose = $True
}

My intention is to copy C:workfile.txt to the same path on CHI-DC01 and Win10Preview virtual machines.

Copy-VMFile @paramHash
Copying files using Copy-VMFile in Windows PowerShell. (Image Credit: Jeff Hicks)
Copying files using Copy-VMFile in Windows PowerShell. (Image Credit: Jeff Hicks)


 
It appears to be successful. I can double-check with PowerShell remoting.

invoke-command { get-item c:workfile.txt} -computer chi-dc01,chi-win10
Verifying that the copy file operation completed successfully. (Image Credit: Jeff Hicks)
Verifying that the copy file operation completed successfully. (Image Credit: Jeff Hicks)


 
As you can see, my Windows 10 virtual machine isn’t set up to play nicely on the network, so traditional file copy methods would probably have failed. But I can see from the VM console that the file was indeed copied.

The file was successfully copied to the correct location. (Image Credit: Jeff Hicks)
The file was successfully copied to the correct location. (Image Credit: Jeff Hicks)

 

Copying Multiple Files with PowerShell


What about copying multiple files or a folder using Copy-VMFile? Sadly, the source and destination parameter don’t accept arrays or wildcards. If you want to copy multiple files, then you need to process each one. I’m going to go ahead and re-use my existing hashtable of parameter values.

dir c:files | foreach {
 $destination = Join-path -Path "C:files" -ChildPath $_.name
 write-host "copying $($_.fullname) to $destination" -foreground Yellow
 $paramHash.SourcePath = $_.fullname
 $paramHash.DestinationPath = $destination
 Copy-VMFile @paramHash
}

My goal is to copy all the files under C:Files to CHI-DC01 and my Windows 10 virtual machines using the Copy-VMFile cmdlet. I’m taking each file and updating parameters in the hashtable.

Prepping my hashtable for multiple files. (Image Credit: Jeff Hicks)
Prepping my hashtable for multiple files. (Image Credit: Jeff Hicks)


 
Success!

Copying Files from a Remote Client to Running VMs

Now that you understand the mechanics, let’s switch to a more typical scenario where you want to do this for a Hyper-V host and virtual machines, but from your client desktop. The tricky part is that whatever files you want to copy using Copy-VMFile must reside on the Hyper-V host. You can use whatever method you want to get the files there. I have a file under C:work on my Hyper-V host, CHI-HVr2.
012015 2057 CopyFilesbe8
I want to copy this version of the file to all running virtual machines. That means I need to make sure Guest Services is enabled.

get-vm -ComputerName chi-hvr2| where {$_.state -eq 'running' -AND -Not ((Get-VMIntegrationService -Name Guest* -vm $_).Enabled)}

These virtual machines fail that test.

Verifying that Guest Services is enabled. (Image Credit: Jeff Hicks)
Verifying that Guest Services is enabled. (Image Credit: Jeff Hicks)


 
To enable these virtual machines, I can add on the Enable-VMIntegrationService cmdlet to my previous expression.

get-vm -ComputerName chi-hvr2|
where {$_.state -eq 'running' -AND -Not ((Get-VMIntegrationService -Name Guest* -vm $_).Enabled)} |
Enable-VMIntegrationService -Name Guest* -Passthru

It looks like there is a problem.
012015 2057 CopyFilesbe10
But usually this is temporary. I can always re-verify.

Get-VM -ComputerName chi-hvr2 | where {$_.state -eq 'running'} | Get-VMIntegrationService -Name Guest*

012015 2057 CopyFilesbe11

$paramHash = @{
 SourcePath = 'c:workfile.txt'
 DestinationPath = 'c:workfile.txt'
 Force = $True
 CreateFullPath = $True
 FileSource = 'Host'
 Verbose = $True
}
Get-VM -ComputerName chi-hvr2 |
where {$_.state -eq 'running'} |
Copy-VMFile @paramHash

Here’s the command in action:

Copying a file to a guest. (Image Credit: Jeff Hicks)
Copying a file to a guest. (Image Credit: Jeff Hicks)


 
If you are copying a lot of files or copying to many virtual machines, you also have an option to run Copy-VMFile as a job. Again, be sure to read cmdlet help.
And that’s all there is to it. You can copy files between the Hyper-V host and its virtual machine guests regardless of the state of the guest Windows operating system.

FAQs

What are the minimum system requirements to use copy-vmfile cmdlet in Hyper-V?

To use copy-vmfile, you need Windows Server 2016/2019/2022 or Windows 10/11 with Hyper-V role installed, PowerShell 5.0 or later, and sufficient administrative privileges. The virtual machines must have the latest integration services installed.

Can copy-vmfile transfer files from one VM to another directly?

No, copy-vmfile can only transfer files between the Hyper-V host and guest VMs. To move files between VMs, you need to first copy-vmfile to the host, then use copy-vmfile again to transfer to the destination VM.

Does copy-vmfile work with Linux virtual machines?

While copy-vmfile is primarily designed for Windows VMs, it can work with Linux VMs if they have the latest Linux Integration Services (LIS) installed and the Guest Services feature is enabled.

What are the size limitations when using copy-vmfile?

The copy-vmfile cmdlet doesn’t have specific size limitations, but transfers are subject to available system resources and storage capacity. For large files, it’s recommended to monitor performance and consider breaking transfers into smaller chunks.

Can copy-vmfile transfer files if the VM is in a saved state?

No, copy-vmfile requires the virtual machine to be running and have an active connection with Integration Services. The Guest Services feature must be enabled and functioning for copy-vmfile to work properly.