Exploring the Hyper-V 2012 R2 and Copy-VMFile Powershell cmdlet
Today I have been exploring a bit in the Windows 2012 R2 Preview and when looking in the technet article “What´s new in Hyper-V 2012 R2” I found the interesting part with the new Integration Service “Guest Services” that allows moving files from the host to the virtual machine without any network connectivity.
This requires two things, first that the “Guest Services” integration component is activated in the VM settings and also that the virtual machine has the latest integrational components installed and the “Hyper-V Guest Interface” service running.
When creating a new virtual machine this is not enabled but I have noticed that when you install Windows 2012 R2 inside the Virtual Machine it gets enabled somehow during the installation, both good and bad… Maybe you want to have some control on what VM´s get this enabled, this can however be a Preview “bug” and will change when the R2 is RTM.
Inside the VM the following Service is running and makes it possible to move files to the VM from the Host. Note that even that you can run the powershell cmdlet from a remote server that have the Hyper-V RSAT tools installed you will have to put the file/files you want to transfer to the VM on the host!
And with this command I move a file into the VM, the parameter -FileSource that only accepts Host today implies that it might be possible to also move files from the VM to the host in a later version. (this can be done with the mounting of the parent disk of a vhd/vhdx after a snapshot that I have done a blog post about before)
Move-Item c:\temp\vNiklasMove.txt -Destination \\hvr2\c$\temp\vNiklasMove.txt Copy-VMFile -VMName Yellow -ComputerName hvr2 -SourcePath C:\temp\vNiklasMove.txt -DestinationPath c:\temp\vNiklasMove.txt -FileSource Host -CreateFullPath
With the parameter -CreateFullPath the folders will be created that I have in the -DestinationPath inside the VM.
If you want to check what VM´s have this Integration guest service enabled you can check it with PowerShell and also disable it and only enable on a per VM basis when transferring files.
Get-VM -ComputerName hvr2 | Get-VMIntegrationService -Name "Guest Service Interface" | where Enabled -eq $true | Disable-VMIntegrationService -Passthru
And on the following screendump you can see that after disabling this I cannot transfer files to the VM.
Comments
Hyper-V WMI – Cloning Virtual Machines Using Import/Export
How do Crate a vm from Windows Server 2012 R2 Hyper-V import/export ?
Thank You Very Much!
Example For Windows Server 2008 R2/Windows Server 2012 Hyper-V:
#Hyper-V WMI – Cloning Virtual Machines Using Import/Export
param
(
[string]$MasterVM = “000-1-Win2012R2″,
[string]$Path =”D:\Cloud\1-VM”,
[string]$NewName = “001-DC01.i-x-Cloud.com”,
[string]$HyperVHost = “localhost”
)
function ProcessWMIJob
{
param
(
[System.Management.ManagementBaseObject]$Result
)
if ($Result.ReturnValue -eq 4096)
{
$Job = [WMI]$Result.Job
while ($Job.JobState -eq 4)
{
Write-Progress -Id 2 -ParentId 1 $Job.Caption -Status “Executing” -PercentComplete $Job.PercentComplete
Start-Sleep 1
$Job.PSBase.Get()
}
if ($Job.JobState -ne 7)
{
Write-Error $Job.ErrorDescription
Throw $Job.ErrorDescription
}
}
elseif ($Result.ReturnValue -ne 0)
{
Throw $Result.ReturnValue
}
#Write-Progress $Job.Caption -Status “Completed” -PercentComplete 100 -Id 2 -ParentId 1
}
#Main Script Body
$VMManagementService = Get-WmiObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService -ComputerName $HyperVHost
$SourceVm = Get-WmiObject -Namespace root\virtualization -Query “Select * From Msvm_ComputerSystem Where ElementName=’$MasterVM’” -ComputerName $HyperVHost
#$a = 0
#while ($a -lt 10) {
#write-progress -Id 1 “Cloning Vm’s” -Status “Executing” -percentcomplete (($a / 10)*100)
write-progress -Id 1 “Cloning Vm’s-001-DC01.i-x-Cloud.com” -Status “Executing”
#$tempVMName = “$NewName – $a”
$tempVMName = “$NewName”
$VMSettingData = Get-WmiObject -Namespace root\virtualization -Query “Associators of {$SourceVm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState” -ComputerName $HyperVHost
$VMSettingData.ElementName = $tempVMName
$Result = $VMManagementService.ModifyVirtualSystem($SourceVm, $VMSettingData.PSBase.GetText(1))
ProcessWMIJob $Result
$Result = $VMManagementService.ExportVirtualSystem($SourceVm, $TRUE, “$Path”)
ProcessWMIJob $Result
$Result = $VMManagementService.ImportVirtualSystem(“$Path\$tempVMName”, $TRUE)
ProcessWMIJob $Result
#$a ++
#}
write-progress -Id 1 -Completed $TRUE -Activity “Cloning Vm’s”
$VMSettingData = Get-WmiObject -Namespace root\virtualization -Query “Associators of {$SourceVm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState” -ComputerName $HyperVHost
$VMSettingData.ElementName = $MasterVM
$Result = $VMManagementService.ModifyVirtualSystem($SourceVm, $VMSettingData.PSBase.GetText(1))
ProcessWMIJob $Result
To clone a VM on a HyperV host without VMM you would use:
#Variables to change
$vHost=”Hostname.FQDN”
$originalVMName=”OriginalName”
$newVMName=”NewName”
$pathCloud=’C:\ClusterStorage\Volume1\CloudPath\’
$pathExport=$pathCloud+’Export\’
$pathExportVM=$pathExport+$originalVMName+’\Virtual Machines\’
Export-VM -Name $originalVMName -Path $pathExport
$originalVMConfigFile=Get-ChildItem $pathExportVM -name
$pathOriginalVM=$pathExportVM+$originalVMConfigFile
$pathImport=$pathCloud+’Import\’
md $pathImport\$newVMName
$pathNewRootVM=$pathImport+$newVMName+’\’
$pathNewSnap=$pathNewRootVM+’SnapShots\’
$pathNewVHD=$pathNewRootVM+’Virtual Hard Disks\’
$pathNewVMConfig=$pathNewRootVM+’Virtual Machines\’
Import-VM -ComputerName $vHost -Path $pathOriginalVM -copy -generatenewid -VirtualMachinePath $pathNewRootVM -SnapshotFilePath $pathNewSnap -VhdDestinationPath $pathNewVHD | Rename-VM -newname $newVMName
remove-item -path $pathExport$originalVMName -Recurse
#remove-item -path $pathImport$newVMName -Recurse